command_kit-completion 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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