Skip to content

Commit 742e3cd

Browse files
committed
- Add support for nested configuration
1 parent 9230b1a commit 742e3cd

File tree

7 files changed

+125
-14
lines changed

7 files changed

+125
-14
lines changed

completely.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
1616

1717
s.required_ruby_version = '>= 3.0'
1818

19-
s.add_runtime_dependency 'colsole', '>= 0.8.1', '< 2'
20-
s.add_runtime_dependency 'mister_bin', '~> 0.7'
19+
s.add_dependency 'colsole', '>= 0.8.1', '< 2'
20+
s.add_dependency 'mister_bin', '~> 0.7'
2121

2222
s.metadata = {
2323
'bug_tracker_uri' => 'https://github.com/DannyBen/completely/issues',

lib/completely.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'completely/exceptions'
2+
require 'completely/config'
23
require 'completely/pattern'
34
require 'completely/completions'
45
require 'completely/tester'

lib/completely/completions.rb

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,20 @@ class Completions
77

88
class << self
99
def load(config_path, function_name: nil)
10-
begin
11-
data = YAML.load_file config_path, aliases: true
12-
rescue ArgumentError
13-
# :nocov:
14-
data = YAML.load_file config_path
15-
# :nocov:
16-
end
17-
18-
new data, function_name: function_name
10+
config = Config.load config_path
11+
new config, function_name: function_name
1912
end
2013
end
2114

2215
def initialize(config, function_name: nil)
23-
@config = config
16+
@config = config.is_a?(Config) ? config : Config.new(config)
2417
@function_name = function_name
2518
end
2619

20+
def flat_config
21+
@flat_config ||= config.flat_config
22+
end
23+
2724
def patterns
2825
@patterns ||= patterns!
2926
end
@@ -54,7 +51,7 @@ def tester
5451
private
5552

5653
def patterns!
57-
result = config.map do |text, completions|
54+
result = flat_config.map do |text, completions|
5855
Pattern.new text, completions, pattern_function_name
5956
end
6057

@@ -70,7 +67,7 @@ def template
7067
end
7168

7269
def command
73-
@command ||= config.keys.first.split.first
70+
@command ||= flat_config.keys.first.split.first
7471
end
7572

7673
def function_name

lib/completely/config.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
module Completely
2+
class Config
3+
attr_reader :config
4+
5+
class << self
6+
def load(config_path)
7+
begin
8+
config = YAML.load_file config_path, aliases: true
9+
rescue ArgumentError
10+
# :nocov:
11+
config = YAML.load_file config_path
12+
# :nocov:
13+
end
14+
15+
new config
16+
end
17+
end
18+
19+
def initialize(config)
20+
@config = config
21+
end
22+
23+
def flat_config
24+
result = {}
25+
26+
config.each do |root_key, root_list|
27+
result.merge! process_key(root_key, root_list)
28+
end
29+
30+
result
31+
end
32+
33+
private
34+
35+
def process_key(prefix, list)
36+
result = {}
37+
result[prefix] = collect_immediate_children list
38+
result.merge! process_nested_items(prefix, list)
39+
result
40+
end
41+
42+
def collect_immediate_children(list)
43+
list.map do |item|
44+
x = item.is_a?(Hash) ? item.keys.first : item
45+
x.gsub(/^[*+]/, '')
46+
end
47+
end
48+
49+
def process_nested_items(prefix, list)
50+
result = {}
51+
52+
list.each do |item|
53+
next unless item.is_a? Hash
54+
55+
nested_prefix = generate_nested_prefix(prefix, item)
56+
nested_list = item.values.first
57+
result.merge!(process_key(nested_prefix, nested_list))
58+
end
59+
60+
result
61+
end
62+
63+
def generate_nested_prefix(prefix, item)
64+
appended_prefix = item.keys.first.gsub(/^\+/, '*')
65+
appended_prefix = " #{appended_prefix}" unless appended_prefix.start_with? '*'
66+
"#{prefix}#{appended_prefix}"
67+
end
68+
end
69+
end

spec/approvals/config/flat_config

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
git:
3+
- "--help"
4+
- "--version"
5+
- init
6+
- checkout
7+
git init:
8+
- "--help"
9+
- "--bare"
10+
git checkout:
11+
- "--help"
12+
- "--branch"
13+
- "-b"
14+
git checkout*--branch:
15+
- dev
16+
- master
17+
git checkout*-b:
18+
- dev
19+
- master

spec/completely/config_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
describe Config do
2+
subject { described_class.load path }
3+
4+
let(:path) { "spec/fixtures/#{file}.yaml" }
5+
let(:file) { 'nested' }
6+
7+
describe '#flat_config' do
8+
it 'returns a flat pattern => completions hash' do
9+
expect(subject.flat_config.to_yaml).to match_approval('config/flat_config')
10+
end
11+
end
12+
end

spec/fixtures/nested.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
git:
2+
- --help
3+
- --version
4+
- init:
5+
- --help
6+
- --bare
7+
- checkout:
8+
- --help
9+
# + prefix is a wildcard (can also use "*--branches" instead, but in quotes)
10+
- +--branch: &branches
11+
- dev
12+
- master
13+
- +-b: *branches

0 commit comments

Comments
 (0)