cl 0.1.23 → 0.1.24

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
  SHA1:
3
- metadata.gz: 1e48bfc8c20e185f62bb0b729a9bbbb27a24f470
4
- data.tar.gz: a8c88e60d22e9ee3d4961301b6322d0b2961a3ab
3
+ metadata.gz: 72952e2db91c199b725e62742a795797062e4ce6
4
+ data.tar.gz: 44492b50481c1622bc45436f611ae1a4211169a6
5
5
  SHA512:
6
- metadata.gz: f147afa28916b0b348a840ad74da1373f418756160128bc2e48401abaa003fc431c803df74f9b1a924b4cb8fbf529073713efe13cac2af37b09ae4a92a9355ef
7
- data.tar.gz: 87d62debde99d4d840dad4811c828868bb3feeea6aaa84f4eda65fd5a26f565beb2d18e3b149e5a739eae8299b4b7657d1582f14767dccdeb7f9dabbf93522f3
6
+ metadata.gz: 7b4a5998249ae7521747203fc2e7b3f21f66bcbef86568d025113b4e808faa84f4f7f7b2aa7401eb9ca1e190f25977bf0c5a5856a5b128181e551584a021e665
7
+ data.tar.gz: 11d40ccbca05ab8dc596dca41d7610992a09745809fb19fdb1ba3c17828a1bf49a0bf1f4e935e5776b6d5a541980b4fe482f82b228d9afd08c760f3bc76be16e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cl (0.1.22)
4
+ cl (0.1.23)
5
5
  regstry (~> 1.0.3)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -18,7 +18,9 @@ Further documentation is available on [rubydoc.info](https://www.rubydoc.info/gi
18
18
  * [Command Registry](#command-registry)
19
19
  * [Runners](#runners)
20
20
  * [Command DSL](#command-dsl)
21
- * [Description, Summary, Examples](#description-summary-examples)
21
+ * [Commands](#commands)
22
+ * [Description, Summary, Examples](#description-summary-examples)
23
+ * [Abstract](#abstract)
22
24
  * [Arguments](#arguments)
23
25
  * [Types](#types)
24
26
  * [Splat](#splat)
@@ -32,6 +34,8 @@ Further documentation is available on [rubydoc.info](https://www.rubydoc.info/gi
32
34
  * [Format](#format)
33
35
  * [Internal](#internal)
34
36
  * [Min and Max](#min-and-max)
37
+ * [Note](#note)
38
+ * [Secret](#secret)
35
39
  * [See Also](#see-also)
36
40
  * [Types](#types)
37
41
  * [Required Options](#required-options)
@@ -135,6 +139,13 @@ module One
135
139
  end
136
140
  ```
137
141
 
142
+ Be aware that if you derive a common base command class from `Cl::Cmd` it
143
+ should be declared as `abstract` in order to unregister itself from the command
144
+ registry.
145
+
146
+ This will prevent the runner to consider it as a runnable command, and omit it
147
+ from help output. See [abstract](#abstract) for details.
148
+
138
149
  ### Runners
139
150
 
140
151
  Runners lookup the command to execute from the registry, by checking the
@@ -217,7 +228,11 @@ See the example [rakeish](blob/master/examples/rakeish) for more details.
217
228
 
218
229
  The DSL is defined on the class body.
219
230
 
220
- ## Description, Summary, Examples
231
+ ### Commands
232
+
233
+ Commands are classes that are derived from the base class `Cl::Cmd`.
234
+
235
+ #### Description, Summary, Examples
221
236
 
222
237
  The description, summary, and examples are used in the help output.
223
238
 
@@ -234,16 +249,48 @@ module Owners
234
249
  examples <<~str
235
250
  Adding a single user to the group admins:
236
251
 
237
- ./bin/owners add user --to admins
252
+ owners add user --to admins
238
253
 
239
254
  Adding a several users at once:
240
255
 
241
- ./bin/owners add one two three --to admins
256
+ owners add one two three --to admins
242
257
  str
243
258
  end
244
259
  end
245
260
  ```
246
261
 
262
+ #### Abstract
263
+
264
+ Command base classes can be declared abstract in order to prevent them from
265
+ being identified as a runnable command and to omit them from help output.
266
+
267
+ This is only relevant if a command base class is registered. See [Command
268
+ Registry](#command-registry) for details.
269
+
270
+ ```ruby
271
+ class Base < Cl::Cmd
272
+ abstract
273
+ end
274
+
275
+ class Add < Base
276
+ end
277
+
278
+ Cl.new('owners').help
279
+
280
+ # Output:
281
+ #
282
+ # Type "owners help COMMAND [SUBCOMMAND]" for more details:
283
+ #
284
+ # owners add [options]
285
+
286
+ Cl.new('owners').run(%w(base))
287
+
288
+ # Error output:
289
+ #
290
+ # Unknown command: base
291
+
292
+ ```
293
+
247
294
  ### Arguments
248
295
 
249
296
  Arguments can be declared like so:
@@ -677,6 +724,54 @@ Cl.new('owners').run(%w(add --retries 10))
677
724
 
678
725
  ```
679
726
 
727
+ #### Note
728
+
729
+ Options can have a note that will be printed in the help output.
730
+
731
+ ```ruby
732
+ class Add < Cl::Cmd
733
+ opt '--to GROUP', note: 'needs to be a group'
734
+ end
735
+
736
+ Cl.new('owners').run(%w(add --help))
737
+
738
+ # Usage: owners add [options]
739
+ #
740
+ # Options:
741
+ #
742
+ # --to GROUP type: string, note: needs to be a group
743
+ # --help Get help on this command
744
+
745
+ ```
746
+
747
+ #### Secret
748
+
749
+ Options can be declared as secret.
750
+
751
+ This makes it possible for client code to inspect if a given option is secret.
752
+ Also, option values given by the user will be tainted, so client code can rely
753
+ on this in order to, for example, obfuscate values from log output.
754
+
755
+ ```ruby
756
+ class Add < Cl::Cmd
757
+ opt '--to GROUP'
758
+ opt '--password PASS', secret: true
759
+
760
+ def run
761
+ puts [:secret?, self.class.opts[:password].secret?].join(' ')
762
+ puts [:tainted?, password.tainted?].join(' ')
763
+ end
764
+ end
765
+
766
+ Cl.new('owners').run(%w(add --password pass))
767
+
768
+ # Output:
769
+ #
770
+ # secret? true
771
+ # tainted? true
772
+
773
+ ```
774
+
680
775
  #### See Also
681
776
 
682
777
  Options can refer to documentation using the `see` option. This will be printed
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Base < Cl::Cmd
7
+ abstract
8
+ end
9
+
10
+ class Add < Base
11
+ end
12
+
13
+ Cl.new('owners').help
14
+
15
+ # Output:
16
+ #
17
+ # Type "owners help COMMAND [SUBCOMMAND]" for more details:
18
+ #
19
+ # owners add [options]
20
+
21
+ Cl.new('owners').run(%w(base))
22
+
23
+ # Error output:
24
+ #
25
+ # Unknown command: base
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Add < Cl::Cmd
7
+ opt '--to GROUP', note: 'needs to be a group'
8
+ end
9
+
10
+ Cl.new('owners').run(%w(add --help))
11
+
12
+ # Usage: owners add [options]
13
+ #
14
+ # Options:
15
+ #
16
+ # --to GROUP type: string, note: needs to be a group
17
+ # --help Get help on this command
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('lib')
3
+
4
+ require 'cl'
5
+
6
+ class Add < Cl::Cmd
7
+ opt '--to GROUP'
8
+ opt '--password PASS', secret: true
9
+
10
+ def run
11
+ puts [:secret?, self.class.opts[:password].secret?].join(' ')
12
+ puts [:tainted?, password.tainted?].join(' ')
13
+ end
14
+ end
15
+
16
+ Cl.new('owners').run(%w(add --password pass))
17
+
18
+ # Output:
19
+ #
20
+ # secret? true
21
+ # tainted? true
data/lib/cl.rb CHANGED
@@ -8,14 +8,14 @@ class Cl
8
8
 
9
9
  # @overload initialize(ctx, name, opts)
10
10
  # @param ctx [Cl::Ctx] the current execution context (optional)
11
- # @param name [String] the program (executable) name (optional, defaults to $0)
11
+ # @param name [String] the program (executable) name (optional, defaults to the last segment of $0)
12
12
  # @param opts [Hash] options (optional)
13
13
  # @option opts [Cl::Runner] :runner registry key for a runner (optional, defaults to :default)
14
14
  # @option opts [Cl::Ui] :ui the ui for handling user interaction
15
15
  def initialize(*args)
16
16
  ctx = args.shift if args.first.is_a?(Ctx)
17
17
  @opts = args.last.is_a?(Hash) ? args.pop : {}
18
- @name = args.shift || $0
18
+ @name = args.shift || $0.split('/').last
19
19
  @ctx = ctx || Ctx.new(name, opts)
20
20
  end
21
21
 
data/lib/cl/ctx.rb CHANGED
@@ -9,11 +9,12 @@ class Cl
9
9
  def_delegators :ui, :puts, :stdout, :announce, :info, :notice, :warn,
10
10
  :error, :success, :cmd
11
11
 
12
- attr_accessor :config, :ui
12
+ attr_accessor :config, :name, :ui
13
13
 
14
14
  def initialize(name, opts = {})
15
15
  @config = Config.new(name).to_h
16
16
  @ui = opts[:ui] || Ui.new(self, opts)
17
+ @name = name
17
18
  end
18
19
 
19
20
  def abort(error, *strs)
data/lib/cl/help.rb CHANGED
@@ -7,7 +7,7 @@ class Cl
7
7
  end
8
8
 
9
9
  def help
10
- args.any? ? Cmd.new(cmd).format : Cmds.new(cmds).format
10
+ args.any? ? Cmd.new(ctx, cmd).format : Cmds.new(ctx, cmds).format
11
11
  end
12
12
 
13
13
  private
data/lib/cl/help/cmd.rb CHANGED
@@ -3,21 +3,15 @@ require 'cl/help/usage'
3
3
 
4
4
  class Cl
5
5
  class Help
6
- class Cmd
6
+ class Cmd < Struct.new(:ctx, :cmd)
7
7
  include Regex
8
8
 
9
- attr_reader :cmd
10
-
11
- def initialize(cmd)
12
- @cmd = cmd
13
- end
14
-
15
9
  def format
16
10
  [usage, summary, description, arguments, options, common, examples].compact.join("\n\n")
17
11
  end
18
12
 
19
13
  def usage
20
- "Usage: #{Usage.new(cmd).format}"
14
+ "Usage: #{Usage.new(ctx, cmd).format}"
21
15
  end
22
16
 
23
17
  def summary
data/lib/cl/help/cmds.rb CHANGED
@@ -3,17 +3,15 @@ require 'cl/help/usage'
3
3
 
4
4
  class Cl
5
5
  class Help
6
- class Cmds
7
- HEAD = %(Type "#{$0.split('/').last} help COMMAND [SUBCOMMAND]" for more details:\n)
6
+ class Cmds < Struct.new(:ctx, :cmds)
7
+ HEAD = %(Type "%s help COMMAND [SUBCOMMAND]" for more details:\n)
8
8
 
9
- attr_reader :cmds
10
-
11
- def initialize(cmds)
12
- @cmds = cmds
9
+ def format
10
+ [head, Table.new(list).format].join("\n")
13
11
  end
14
12
 
15
- def format
16
- [HEAD, Table.new(list).format].join("\n")
13
+ def head
14
+ HEAD % ctx.name
17
15
  end
18
16
 
19
17
  def list
@@ -21,7 +19,7 @@ class Cl
21
19
  end
22
20
 
23
21
  def format_cmd(cmd)
24
- ["#{Usage.new(cmd).format}", cmd.summary]
22
+ ["#{Usage.new(ctx, cmd).format}", cmd.summary]
25
23
  end
26
24
  end
27
25
  end
data/lib/cl/help/usage.rb CHANGED
@@ -1,19 +1,17 @@
1
1
  class Cl
2
2
  class Help
3
- class Usage
4
- attr_reader :cmd
5
-
6
- def initialize(cmd)
7
- @cmd = cmd
8
- end
9
-
3
+ class Usage < Struct.new(:ctx, :cmd)
10
4
  def format
11
- usage = [$0.split('/').last, name]
5
+ usage = [executable, name]
12
6
  usage += cmd.args.map(&:to_s) # { |arg| "[#{arg}]" }
13
7
  usage << '[options]' if opts?
14
8
  usage.join(' ')
15
9
  end
16
10
 
11
+ def executable
12
+ ctx.name
13
+ end
14
+
17
15
  def name
18
16
  cmd.registry_key.to_s.gsub(':', ' ')
19
17
  end
data/lib/cl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Cl
2
- VERSION = '0.1.23'
2
+ VERSION = '0.1.24'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.23
4
+ version: 0.1.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: regstry
@@ -43,6 +43,7 @@ files:
43
43
  - examples/gem
44
44
  - examples/heroku
45
45
  - examples/rakeish
46
+ - examples/readme/abstract
46
47
  - examples/readme/alias
47
48
  - examples/readme/arg
48
49
  - examples/readme/arg_array
@@ -57,12 +58,14 @@ files:
57
58
  - examples/readme/example
58
59
  - examples/readme/format
59
60
  - examples/readme/internal
61
+ - examples/readme/note
60
62
  - examples/readme/opts
61
63
  - examples/readme/opts_block
62
64
  - examples/readme/range
63
65
  - examples/readme/required
64
66
  - examples/readme/requireds
65
67
  - examples/readme/requires
68
+ - examples/readme/secret
66
69
  - examples/readme/see
67
70
  - examples/readme/type
68
71
  - lib/cl.rb