command_kit-completion 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c0c0378bac84ce2d4471fa0f3765f67b0c5fbf2324e4014fbbc6dc7b2d65eba
4
- data.tar.gz: 5bc39444369f6b447b8a7ac7e184180de85867be5c11a69d9a0d5fcbb11124f8
3
+ metadata.gz: 721a31416806fcf1375dfa9060827013fbde3ffc06f0d9916f31c5602d4386f7
4
+ data.tar.gz: e6bb27f5dd650bfb26b9fda270bb66a97c7c260cbaa45b3a520a93aa53594567
5
5
  SHA512:
6
- metadata.gz: cb50d3dfa8d1ea82cbc4e81587e2d96f197417d0e05c1e553ea246dba428387c93baf78c4ec8985a92d6c38177eddc3468e2285460680578e703941c2c8dc007
7
- data.tar.gz: 0ed3ebd76e5463e2d05b74b424a3e83c87c69ca99babd98486d47ca0c813546a737ff258fa17c5badc744d21c9ec55b916b3bdf86f0f30c3d2f2aef232b6de81
6
+ metadata.gz: 6e9820c5f5ae32b4f9672d9b05bec71b86e0a66a9a8ae873e74346d65fe2d5b8d37c205921689d7c842d30e1d8411328fc5181da61b57abe71fbd31518485229
7
+ data.tar.gz: 855fd91e1a677a359f62f1ebcc38350e6308e5451cfa7d69dea172ec3d88c015a2323e1b7d6559f64cd6667bd1c5ac2489d62644523e39bf80f8a2628bd64621
@@ -9,9 +9,10 @@ jobs:
9
9
  fail-fast: false
10
10
  matrix:
11
11
  ruby:
12
- - 3.0
13
- - 3.1
14
- - 3.2
12
+ - '3.0'
13
+ - '3.1'
14
+ - '3.2'
15
+ - '3.3'
15
16
  - jruby
16
17
  - truffleruby
17
18
  name: OS ${{ matrix.os }} / Ruby ${{ matrix.ruby }}
data/ChangeLog.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.3.0 / 2024-12-16
2
+
3
+ * Generate `<file>` and `<directory>` completion rules for arguments named
4
+ `PATH` or ending in `_PATH`, so they can tab complete both files and
5
+ directories.
6
+
1
7
  ### 0.2.1 / 2024-04-29
2
8
 
3
9
  * Support loading YAML input files that contain YAML aliases.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2023 Hal Brodigan
1
+ Copyright (c) 2023-2024 Hal Brodigan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -45,7 +45,7 @@ rake command_kit:completion
45
45
 
46
46
  ## License
47
47
 
48
- Copyright (c) 2023 Hal Brodigan
48
+ Copyright (c) 2023-2024 Hal Brodigan
49
49
 
50
50
  See {file:LICENSE.txt} for details.
51
51
 
@@ -10,37 +10,61 @@ require 'fileutils'
10
10
 
11
11
  module CommandKit
12
12
  module Completion
13
+ #
14
+ # `command_kit-completion` rake task.
15
+ #
16
+ # ## Example
17
+ #
18
+ # require 'command_kit/completion/task'
19
+ # CommandKit::Completion::Task.new(
20
+ # class_file: './examples/cli',
21
+ # class_name: 'Foo::CLI',
22
+ # output_file: 'completion.sh'
23
+ # )
24
+ #
13
25
  class Task < Rake::TaskLib
14
26
 
15
27
  # The file that the command_kit CLI is defined in.
16
28
  #
17
29
  # @return [String]
30
+ #
31
+ # @api private
18
32
  attr_reader :class_file
19
33
 
20
34
  # The class name of the command_kit CLI.
21
35
  #
22
36
  # @return [String]
37
+ #
38
+ # @api private
23
39
  attr_reader :class_name
24
40
 
25
41
  # The output file to write the shell completions to.
26
42
  #
27
43
  # @return [String]
44
+ #
45
+ # @api private
28
46
  attr_reader :output_file
29
47
 
30
48
  # Optional input YAML file to read additional shell completions from.
31
49
  #
32
50
  # @return [String, nil]
51
+ #
52
+ # @api private
33
53
  attr_reader :input_file
34
54
 
35
55
  # Specifies whether the shell completion logic should be wrapped in a
36
56
  # function.
37
57
  #
38
58
  # @return [Boolean]
59
+ #
60
+ # @api private
39
61
  attr_reader :wrap_function
40
62
 
41
63
  # Optional function name to wrap the shell completions within.
42
64
  #
43
65
  # @return [String, nil]
66
+ #
67
+ # @api private
44
68
  attr_reader :function_name
45
69
 
46
70
  #
@@ -61,6 +85,8 @@ module CommandKit
61
85
  #
62
86
  # [completely examples]: https://github.com/DannyBen/completely?tab=readme-ov-file#using-the-completely-command-line
63
87
  #
88
+ # @api public
89
+ #
64
90
  def initialize(class_file: ,
65
91
  class_name: ,
66
92
  output_file: ,
@@ -81,6 +107,8 @@ module CommandKit
81
107
  #
82
108
  # Defines the `command_kit:completion` task.
83
109
  #
110
+ # @api private
111
+ #
84
112
  def define
85
113
  task(@output_file) do
86
114
  completions = Completely::Completions.new(completion_rules)
@@ -105,6 +133,8 @@ module CommandKit
105
133
  #
106
134
  # @return [Class]
107
135
  #
136
+ # @api private
137
+ #
108
138
  def load_class
109
139
  require(@class_file)
110
140
  Object.const_get(@class_name)
@@ -116,6 +146,8 @@ module CommandKit
116
146
  # @return [Hash]
117
147
  # The completion rules from the {#input_file}.
118
148
  #
149
+ # @api private
150
+ #
119
151
  def load_input_file
120
152
  YAML.load_file(@input_file, aliases: true)
121
153
  end
@@ -126,17 +158,20 @@ module CommandKit
126
158
  # @param [String] arg
127
159
  # The argument name.
128
160
  #
129
- # @return [String, nil]
161
+ # @return [Array<String>, nil]
130
162
  # The suggestion keyword for the argument name.
131
163
  #
132
- # @since 0.2.0
164
+ # @since 0.3.0
133
165
  #
134
- def suggestion_for_argument(arg)
166
+ # @api private
167
+ #
168
+ def suggestions_for_argument(arg)
135
169
  case arg
136
- when /\AFILE\z|_FILE\z/ then '<file>'
137
- when /\ADIR\z|_DIR\z/ then '<directory>'
138
- when /\AHOST\z|_HOST\z/ then '<hostname>'
139
- when /\AUSER\z|_USER\z/ then '<user>'
170
+ when /\AFILE\z|_FILE\z/ then %w[<file>]
171
+ when /\ADIR\z|_DIR\z/ then %w[<directory>]
172
+ when /\APATH\z|_PATH\z/ then %w[<file> <directory>]
173
+ when /\AHOST\z|_HOST\z/ then %w[<hostname>]
174
+ when /\AUSER\z|_USER\z/ then %w[<user>]
140
175
  end
141
176
  end
142
177
 
@@ -152,6 +187,8 @@ module CommandKit
152
187
  # @return [Hash{String => Array<String>}]
153
188
  # The completion rules for the command class and any sub-commands.
154
189
  #
190
+ # @api private
191
+ #
155
192
  def completion_rules_for(command_class)
156
193
  command_name = command_class.command_name
157
194
  completions = {command_name => []}
@@ -164,16 +201,16 @@ module CommandKit
164
201
  completions[command_name] << option.short if option.short
165
202
 
166
203
  if option.value
167
- if (suggestion = suggestion_for_argument(option.value.usage))
204
+ if (suggestions = suggestions_for_argument(option.value.usage))
168
205
  command_pattern = "#{command_name}*#{option.long}"
169
206
 
170
207
  # add a special rule if the option's value USAGE maps to a
171
208
  # 'completely' completion keyword (ex: `FILE` -> `<file>`).
172
- completions[command_pattern] = [suggestion]
209
+ completions[command_pattern] = suggestions
173
210
 
174
211
  if option.short
175
212
  # also add another rule with the option's short flag
176
- completions["#{command_name}*#{option.short}"] = [suggestion]
213
+ completions["#{command_name}*#{option.short}"] = suggestions
177
214
  end
178
215
  end
179
216
  end
@@ -195,9 +232,9 @@ module CommandKit
195
232
  completions[command_name].concat(command_class.command_aliases.keys)
196
233
  elsif command_class.include?(CommandKit::Arguments)
197
234
  if (argument = command_class.arguments.values.first)
198
- if (suggestion = suggestion_for_argument(argument.usage))
235
+ if (suggestions = suggestions_for_argument(argument.usage))
199
236
  # add a suggestion for the first argument
200
- completions[command_name] << suggestion
237
+ completions[command_name].concat(suggestions)
201
238
  end
202
239
  end
203
240
  end
@@ -216,6 +253,8 @@ module CommandKit
216
253
  #
217
254
  # @return [Hash{String => Array<String>}]
218
255
  #
256
+ # @api private
257
+ #
219
258
  def completion_rules
220
259
  completion_rules = completion_rules_for(load_class)
221
260
 
@@ -3,6 +3,6 @@
3
3
  module CommandKit
4
4
  module Completion
5
5
  # command_kit-completion version
6
- VERSION = '0.2.1'
6
+ VERSION = '0.3.0'
7
7
  end
8
8
  end
data/spec/task_spec.rb CHANGED
@@ -605,52 +605,90 @@ describe CommandKit::Completion::Task do
605
605
  end
606
606
  end
607
607
 
608
- describe "#suggestion_for_argument" do
608
+ describe "#suggestions_for_argument" do
609
609
  context "when given 'FILE'" do
610
- it "must return '<file>'" do
611
- expect(subject.suggestion_for_argument('FILE')).to eq('<file>')
610
+ it "must return ['<file>']" do
611
+ expect(subject.suggestions_for_argument('FILE')).to eq(
612
+ %w[<file>]
613
+ )
612
614
  end
613
615
  end
614
616
 
615
617
  context "when the string ends with '_FILE'" do
616
- it "must return '<file>'" do
617
- expect(subject.suggestion_for_argument('FOO_FILE')).to eq('<file>')
618
+ it "must return ['<file>']" do
619
+ expect(subject.suggestions_for_argument('FOO_FILE')).to eq(
620
+ %w[<file>]
621
+ )
618
622
  end
619
623
  end
620
624
 
621
625
  context "when given 'DIR'" do
622
- it "must return '<directory>'" do
623
- expect(subject.suggestion_for_argument('DIR')).to eq('<directory>')
626
+ it "must return ['<directory>']" do
627
+ expect(subject.suggestions_for_argument('DIR')).to eq(
628
+ %w[<directory>]
629
+ )
624
630
  end
625
631
  end
626
632
 
627
633
  context "when the string ends with '_DIR'" do
628
- it "must return '<directory>'" do
629
- expect(subject.suggestion_for_argument('FOO_DIR')).to eq('<directory>')
634
+ it "must return ['<directory>']" do
635
+ expect(subject.suggestions_for_argument('FOO_DIR')).to eq(
636
+ %w[<directory>]
637
+ )
638
+ end
639
+ end
640
+
641
+ context "when given 'PATH'" do
642
+ it "must return ['<file>', '<directory>']" do
643
+ expect(subject.suggestions_for_argument('PATH')).to eq(
644
+ %w[
645
+ <file>
646
+ <directory>
647
+ ]
648
+ )
649
+ end
650
+ end
651
+
652
+ context "when the string ends with '_PATH'" do
653
+ it "must return ['<file>', '<directory>']" do
654
+ expect(subject.suggestions_for_argument('FOO_PATH')).to eq(
655
+ %w[
656
+ <file>
657
+ <directory>
658
+ ]
659
+ )
630
660
  end
631
661
  end
632
662
 
633
663
  context "when given 'HOST'" do
634
- it "must return '<hostname>'" do
635
- expect(subject.suggestion_for_argument('HOST')).to eq('<hostname>')
664
+ it "must return ['<hostname>']" do
665
+ expect(subject.suggestions_for_argument('HOST')).to eq(
666
+ %w[<hostname>]
667
+ )
636
668
  end
637
669
  end
638
670
 
639
671
  context "when the string ends with '_HOST'" do
640
- it "must return '<hostname>'" do
641
- expect(subject.suggestion_for_argument('FOO_HOST')).to eq('<hostname>')
672
+ it "must return ['<hostname>']" do
673
+ expect(subject.suggestions_for_argument('FOO_HOST')).to eq(
674
+ %w[<hostname>]
675
+ )
642
676
  end
643
677
  end
644
678
 
645
679
  context "when given 'USER'" do
646
- it "must return '<user>'" do
647
- expect(subject.suggestion_for_argument('USER')).to eq('<user>')
680
+ it "must return ['<user>']" do
681
+ expect(subject.suggestions_for_argument('USER')).to eq(
682
+ %w[<user>]
683
+ )
648
684
  end
649
685
  end
650
686
 
651
687
  context "when the string ends with '_USER'" do
652
- it "must return '<user>'" do
653
- expect(subject.suggestion_for_argument('FOO_USER')).to eq('<user>')
688
+ it "must return ['<user>']" do
689
+ expect(subject.suggestions_for_argument('FOO_USER')).to eq(
690
+ %w[<user>]
691
+ )
654
692
  end
655
693
  end
656
694
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_kit-completion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-29 00:00:00.000000000 Z
11
+ date: 2024-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: command_kit
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  requirements: []
114
- rubygems_version: 3.4.19
114
+ rubygems_version: 3.5.22
115
115
  signing_key:
116
116
  specification_version: 4
117
117
  summary: Generate shell completions for command_kit commands