dry-cli 0.6.0 → 1.0.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: 448f01b536f8cc664a86d2b4e558e8db6062c6ac31256c32d507828f1d3b7519
4
- data.tar.gz: 254448f2e0b031cfc0077021ca3d0876b81b5eb9c7b1a7e51afce0d9524c95cc
3
+ metadata.gz: 1d37c32bb092f046364d8537259aec4a8f3e233fe57167b8d19c667f8c3421a7
4
+ data.tar.gz: dcab3ac00499da55cad199c0ca98854e16109f23d0d257ffa9a0c826c765e476
5
5
  SHA512:
6
- metadata.gz: b114fa6217a59fdca38df56819e016a47337843ad357a52cd0f006bac2048dc2ee9253439a0353721412edac8e3a4d1f3c9601e7b3ccb729c86f5899d53fc2d6
7
- data.tar.gz: 1edf50dce27e4d1cc9e9cc868c14d18e9399e62b0edcebf5a3166559bc8ef66a7fa79a04d0ac0c2ef5c6ffa1384aecb80ca967c16136f9dceb3721123e9c53a4
6
+ metadata.gz: 1e29fb0c9aa6672108b1c4afc8629ab9274655675c95a04cf85503824c1565dcef22fe2da20f6ca8a6a65d8b4b07e626f3c793fbede40a10f7a645cfaf1f7421
7
+ data.tar.gz: 8d65f61919776a08c9d6519cf2e6d47c85ec5c4e723234dcee2159b5a3fa6c99d2ecb754299dcd74f9f767e3c0d9e710f099ed16b347571256af082967d8e5cb
data/CHANGELOG.md CHANGED
@@ -1,17 +1,55 @@
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
+
3
+ ## 1.0.0 2022-11-05
4
+
5
+
6
+ ### Changed
7
+
8
+ - Version bumped to 1.0.0 (@solnic)
9
+
10
+ [Compare v0.7.0...v1.0.0](https://github.com/dry-rb/dry-cli/compare/v0.7.0...v1.0.0)
11
+
12
+ ## 0.7.0 2020-05-08
13
+
14
+
15
+ ### Added
16
+
17
+ - Inheritable attributes for subclasses of commands (@IvanShamatov)
18
+ - Ability to register instances, not only classes as Commands (@IvanShamatov)
19
+ - Add support for subcommands with a parent command (@unrooty)
20
+
21
+ ### Fixed
22
+
23
+ - Safely rescue pipe exception, when you CLI app is producing output for piped CLI app (IvanShamatov)
24
+ - Safely rescue keyboard interrupts (@IvanShamatov)
25
+ - [Internal] Don't run specs twice (@jodosha)
26
+ - Update inline call with keyward arguments (@flash-gordon)
27
+
28
+ ### Changed
29
+
30
+ - Extracted Dry::CLI::Utils::Files into dry-files (@jodosha)
31
+ - Drop 2.3 ruby support (@IvanShamatov)
32
+ - [Internal] Changelog, issue templates (@solnic)
33
+ - Documentation updates (@davydovanton)
34
+ - Remove concurrent-ruby as runtime dependency (@jodosha)
35
+ - [Internal] Banner and Parses refactoring (@IvanShamatov)
36
+
37
+ [Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-cli/compare/v0.6.0...v0.7.0)
38
+
1
39
  ## 0.6.0 2020-03-06
2
40
 
3
41
 
4
42
  ### Added
5
43
 
6
- - [Ivan Shamatov] Ability to pass command along with registry (for a singular command case)
7
- - [Nikita Shilnikov] [Internal] Backported ability to run gem's CI against ruby 2.3
8
- - [Ivan Shamatov] Inline syntax for commands
9
- - [Ivan Shamatov] Introduced stderr to any diagnostic output
44
+ - Ability to pass command along with registry (for a singular command case) (@IvanShamatov)
45
+ - [Internal] Backported ability to run gem's CI against ruby 2.3 (@flash-gordon)
46
+ - Inline syntax for commands (@IvanShamatov)
47
+ - Introduced stderr to any diagnostic output (@IvanShamatov)
10
48
 
11
49
  ### Fixed
12
50
 
13
- - [John Ledbetter & Luca Guidi] Fix ruby 2.7 warnings
14
- - [Ivan Shamatov] Fix banner, when option is a type of Array
51
+ - [John Ledbetter & Luca Guidi] Fix ruby 2.7 warnings (@jodosha)
52
+ - Fix banner, when option is a type of Array (@IvanShamatov)
15
53
 
16
54
 
17
55
  [Compare v0.5.1...v0.6.0](https://github.com/dry-rb/dry-cli/compare/v0.5.1...v0.6.0)
@@ -21,15 +59,15 @@
21
59
 
22
60
  ### Added
23
61
 
24
- - [Ivan Shamatov] Anonymous Registry sintax
25
- - [Ivan Shamatov] [Internal] Specs refactored, more unit specs added
26
- - [Luca Guidi] [Internal] removed `dry-inflector` as runtime dependency
27
- - [Ivan Shamatov] [Internal] Refactored Command class (command_name property removed)
28
- - [Piotr Solnica, Luca Guidi, Nikita Shilnikov & Christian Georgii] [Internal] Adapt gem to dry-rb style
62
+ - Anonymous Registry sintax (@IvanShamatov)
63
+ - [Internal] Specs refactored, more unit specs added (@IvanShamatov)
64
+ - [Internal] removed `dry-inflector` as runtime dependency (@jodosha)
65
+ - [Internal] Refactored Command class (command_name property removed) (@IvanShamatov)
66
+ - [Internal] Adapt gem to dry-rb style (@jodosha, @flash-gordon, @solnic, @cgeorgii)
29
67
 
30
68
  ### Fixed
31
69
 
32
- - [Piotr Solnica] Added missing 'set' require
70
+ - Added missing 'set' require (@solnic)
33
71
 
34
72
 
35
73
  [Compare v0.5.0...v0.5.1](https://github.com/dry-rb/dry-cli/compare/v0.5.0...v0.5.1)
@@ -39,7 +77,7 @@
39
77
 
40
78
  ### Added
41
79
 
42
- - [Ivan Shamatov, Piotr Solnica, Luca Guidi] [Internal] removed runtime and development dependency against `hanami-utils`
80
+ - [Internal] removed runtime and development dependency against `hanami-utils` (@jodosha, @IvanShamatov, @solnic)
43
81
 
44
82
 
45
83
  [Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-cli/compare/v0.4.0...v0.5.0)
@@ -49,7 +87,7 @@
49
87
 
50
88
  ### Added
51
89
 
52
- - [Ivan Shamatov, Piotr Solnica, Luca Guidi] `hanami-cli` => `dry-cli`
90
+ - `hanami-cli` => `dry-cli` (@jodosha, @IvanShamatov, @solnic)
53
91
 
54
92
 
55
93
  [Compare v0.3.1...v0.4.0](https://github.com/dry-rb/dry-cli/compare/v0.3.1...v0.4.0)
@@ -59,8 +97,8 @@
59
97
 
60
98
  ### Added
61
99
 
62
- - [Luca Guidi] Official support for Ruby: MRI 2.6
63
- - [Luca Guidi] Support `bundler` 2.0+
100
+ - Official support for Ruby: MRI 2.6 (@jodosha)
101
+ - Support `bundler` 2.0+ (@jodosha)
64
102
 
65
103
 
66
104
  [Compare v0.3.0...v0.3.1](https://github.com/dry-rb/dry-cli/compare/v0.3.0...v0.3.1)
@@ -76,14 +114,14 @@
76
114
 
77
115
  ### Added
78
116
 
79
- - [Anton Davydov & Alfonso Uceda] Introduce array type for arguments (`foo exec test spec/bookshelf/entities spec/bookshelf/repositories`)
80
- - [Anton Davydov & Alfonso Uceda] Introduce array type for options (`foo generate config --apps=web,api`)
81
- - [Alfonso Uceda] Introduce variadic arguments (`foo run ruby:latest -- ruby -v`)
82
- - [Luca Guidi] Official support for JRuby 9.2.0.0
117
+ - Introduce array type for arguments (`foo exec test spec/bookshelf/entities spec/bookshelf/repositories`) (@davydovanton, @AlfonsoUceda)
118
+ - Introduce array type for options (`foo generate config --apps=web,api`) (@davydovanton, @AlfonsoUceda)
119
+ - Introduce variadic arguments (`foo run ruby:latest -- ruby -v`)
120
+ - Official support for JRuby 9.2.0.0 (@jodosha, @AlfonsoUceda)
83
121
 
84
122
  ### Fixed
85
123
 
86
- - [Anton Davydov] Print informative message when unknown or wrong option is passed (`"test" was called with arguments "--framework=unknown"`)
124
+ - Print informative message when unknown or wrong option is passed (`"test" was called with arguments "--framework=unknown"`) (@davydovanton)
87
125
 
88
126
 
89
127
  [Compare v0.2.0...v0.3.0.beta1](https://github.com/dry-rb/dry-cli/compare/v0.2.0...v0.3.0.beta1)
@@ -111,11 +149,11 @@
111
149
 
112
150
  ### Added
113
151
 
114
- - [Anton Davydov & Luca Guidi] Support objects as callbacks
152
+ - Support objects as callbacks (@jodosha, @davydovanton)
115
153
 
116
154
  ### Fixed
117
155
 
118
- - [Anton Davydov & Luca Guidi] Ensure callbacks' context of execution (aka `self`) to be the command that is being executed
156
+ - Ensure callbacks' context of execution (aka `self`) to be the command that is being executed (@jodosha, @davydovanton)
119
157
 
120
158
 
121
159
  [Compare v0.2.0.beta1...v0.2.0.beta2](https://github.com/dry-rb/dry-cli/compare/v0.2.0.beta1...v0.2.0.beta2)
@@ -125,7 +163,7 @@
125
163
 
126
164
  ### Added
127
165
 
128
- - [Anton Davydov] Register `before`/`after` callbacks for commands
166
+ - Register `before`/`after` callbacks for commands (@davydovanton)
129
167
 
130
168
 
131
169
  [Compare v0.1.1...v0.2.0.beta1](https://github.com/dry-rb/dry-cli/compare/v0.1.1...v0.2.0.beta1)
@@ -135,12 +173,12 @@
135
173
 
136
174
  ### Added
137
175
 
138
- - [Luca Guidi] Official support for Ruby: MRI 2.5
176
+ - Official support for Ruby: MRI 2.5 (@jodosha)
139
177
 
140
178
  ### Fixed
141
179
 
142
- - [Alfonso Uceda] Ensure default values for arguments to be sent to commands
143
- - [Alfonso Uceda] Ensure to fail when a missing required argument isn't provider, but an option is provided instead
180
+ - Ensure default values for arguments to be sent to commands (@AlfonsoUceda)
181
+ - Ensure to fail when a missing required argument isn't provider, but an option is provided instead (@AlfonsoUceda)
144
182
 
145
183
 
146
184
  [Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-cli/compare/v0.1.0...v0.1.1)
@@ -168,7 +206,7 @@
168
206
 
169
207
  ### Added
170
208
 
171
- -  [Alfonso Uceda] Allow default value for arguments
209
+ - Allow default value for arguments (@AlfonsoUceda)
172
210
 
173
211
 
174
212
  [Compare v0.1.0.beta1...v0.1.0.beta2](https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta1...v0.1.0.beta2)
@@ -178,12 +216,12 @@
178
216
 
179
217
  ### Added
180
218
 
181
- -  [Alfonso Uceda, Luca Guidi] Commands banner and usage
182
- -  [Alfonso Uceda] Added support for subcommands
183
- - [Alfonso Uceda] Validations for arguments and options
184
- - [Alfonso Uceda] Commands arguments and options
185
- - [Alfonso Uceda] Commands description
186
- - [Alfonso Uceda, Oana Sipos] Commands aliases
187
- - [Luca Guidi] Exit on unknown command
188
- - [Luca Guidi, Alfonso Uceda, Oana Sipos] Command lookup
189
- - [Luca Guidi, Tim Riley] Trie based registry to register commands and allow third-parties to override/add commands
219
+ - Commands banner and usage (@jodosha, @AlfonsoUceda)
220
+ - Added support for subcommands (@AlfonsoUceda)
221
+ - Validations for arguments and options (@AlfonsoUceda)
222
+ - Commands arguments and options (@AlfonsoUceda)
223
+ - Commands description (@AlfonsoUceda)
224
+ - Commands aliases (@AlfonsoUceda, @oana-sipos)
225
+ - Exit on unknown command (@jodosha)
226
+ - Command lookup (@AlfonsoUceda, @oana-sipos)
227
+ - Trie based registry to register commands and allow third-parties to override/add commands (@jodosha, @timriley)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2020 dry-rb team
3
+ Copyright (c) 2015-2021 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ <!--- this file is synced from dry-rb/template-gem project -->
1
2
  [gem]: https://rubygems.org/gems/dry-cli
2
3
  [actions]: https://github.com/dry-rb/dry-cli/actions
3
4
  [codacy]: https://www.codacy.com/gh/dry-rb/dry-cli
@@ -10,19 +11,19 @@
10
11
  [![CI Status](https://github.com/dry-rb/dry-cli/workflows/ci/badge.svg)][actions]
11
12
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/61dd5d070fc74f0cacf575b19d4930e1)][codacy]
12
13
  [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/61dd5d070fc74f0cacf575b19d4930e1)][codacy]
13
- [![Inline docs](http://inch-ci.org/github/dry-rb/dry-cli.svg?branch=master)][inchpages]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-cli.svg?branch=main)][inchpages]
14
15
 
15
16
  ## Links
16
17
 
17
- * [User documentation](http://dry-rb.org/gems/dry-cli)
18
+ * [User documentation](https://dry-rb.org/gems/dry-cli)
18
19
  * [API documentation](http://rubydoc.info/gems/dry-cli)
19
20
 
20
21
  ## Supported Ruby versions
21
22
 
22
23
  This library officially supports the following Ruby versions:
23
24
 
24
- * MRI >= `2.4`
25
- * jruby >= `9.2`
25
+ * MRI `>= 2.4.0`
26
+ * jruby `>= 9.3` (postponed until 2.7 is supported)
26
27
 
27
28
  ## License
28
29
 
data/dry-cli.gemspec CHANGED
@@ -1,37 +1,38 @@
1
1
  # frozen_string_literal: true
2
- # this file is managed by dry-rb/devtools project
3
2
 
4
- lib = File.expand_path('lib', __dir__)
3
+ # this file is synced from dry-rb/template-gem project
4
+
5
+ lib = File.expand_path("lib", __dir__)
5
6
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'dry/cli/version'
7
+ require "dry/cli/version"
7
8
 
8
9
  Gem::Specification.new do |spec|
9
- spec.name = 'dry-cli'
10
+ spec.name = "dry-cli"
10
11
  spec.authors = ["Luca Guidi"]
11
12
  spec.email = ["me@lucaguidi.com"]
12
- spec.license = 'MIT'
13
+ spec.license = "MIT"
13
14
  spec.version = Dry::CLI::VERSION.dup
14
15
 
15
16
  spec.summary = "Common framework to build command line interfaces with Ruby"
16
17
  spec.description = spec.summary
17
- spec.homepage = 'https://dry-rb.org/gems/dry-cli'
18
+ spec.homepage = "https://dry-rb.org/gems/dry-cli"
18
19
  spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-cli.gemspec", "lib/**/*"]
19
- spec.bindir = 'bin'
20
+ spec.bindir = "bin"
20
21
  spec.executables = []
21
- spec.require_paths = ['lib']
22
+ spec.require_paths = ["lib"]
22
23
 
23
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
24
- spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-cli/blob/master/CHANGELOG.md'
25
- spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-cli'
26
- spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-cli/issues'
24
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
25
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-cli/blob/main/CHANGELOG.md"
26
+ spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-cli"
27
+ spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-cli/issues"
27
28
 
28
- spec.required_ruby_version = ">= 2.3.0"
29
+ spec.required_ruby_version = ">= 2.7.0"
29
30
 
30
31
  # to update dependencies edit project.yml
31
- spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
32
32
 
33
33
  spec.add_development_dependency "bundler", ">= 1.6", "< 3"
34
34
  spec.add_development_dependency "rake", "~> 13.0"
35
35
  spec.add_development_dependency "rspec", "~> 3.7"
36
+ spec.add_development_dependency "rubocop", "~> 0.82"
36
37
  spec.add_development_dependency "simplecov", "~> 0.17.1"
37
38
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/cli/program_name'
3
+ require "dry/cli/program_name"
4
4
 
5
5
  module Dry
6
6
  class CLI
@@ -16,15 +16,15 @@ module Dry
16
16
  #
17
17
  # @since 0.1.0
18
18
  # @api private
19
- def self.call(command, names)
20
- full_command_name = full_command_name(names)
19
+ def self.call(command, name)
21
20
  [
22
- command_name(full_command_name),
23
- command_name_and_arguments(command, full_command_name),
21
+ command_name(name),
22
+ command_name_and_arguments(command, name),
24
23
  command_description(command),
24
+ command_subcommands(command),
25
25
  command_arguments(command),
26
26
  command_options(command),
27
- command_examples(command, full_command_name)
27
+ command_examples(command, name)
28
28
  ].compact.join("\n")
29
29
  end
30
30
 
@@ -37,7 +37,11 @@ module Dry
37
37
  # @since 0.1.0
38
38
  # @api private
39
39
  def self.command_name_and_arguments(command, name)
40
- "\nUsage:\n #{name}#{arguments(command)}"
40
+ usage = "\nUsage:\n #{name}#{arguments(command)}"
41
+
42
+ return usage + " | #{name} SUBCOMMAND" if command.subcommands.any?
43
+
44
+ usage
41
45
  end
42
46
 
43
47
  # @since 0.1.0
@@ -45,7 +49,7 @@ module Dry
45
49
  def self.command_examples(command, name)
46
50
  return if command.examples.empty?
47
51
 
48
- "\nExamples:\n#{command.examples.map { |example| " #{name} #{example}" }.join("\n")}" # rubocop:disable Metrics/LineLength
52
+ "\nExamples:\n#{command.examples.map { |example| " #{name} #{example}" }.join("\n")}"
49
53
  end
50
54
 
51
55
  # @since 0.1.0
@@ -56,6 +60,12 @@ module Dry
56
60
  "\nDescription:\n #{command.description}"
57
61
  end
58
62
 
63
+ def self.command_subcommands(command)
64
+ return if command.subcommands.empty?
65
+
66
+ "\nSubcommands:\n#{build_subcommands_list(command.subcommands)}"
67
+ end
68
+
59
69
  # @since 0.1.0
60
70
  # @api private
61
71
  def self.command_arguments(command)
@@ -70,30 +80,24 @@ module Dry
70
80
  "\nOptions:\n#{extended_command_options(command)}"
71
81
  end
72
82
 
73
- # @since 0.1.0
74
- # @api private
75
- def self.full_command_name(names)
76
- ProgramName.call(names)
77
- end
78
-
79
83
  # @since 0.1.0
80
84
  # @api private
81
85
  def self.arguments(command)
82
86
  required_arguments = command.required_arguments
83
87
  optional_arguments = command.optional_arguments
84
88
 
85
- required = required_arguments.map { |arg| arg.name.upcase }.join(' ') if required_arguments.any? # rubocop:disable Metrics/LineLength
86
- optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(' ') if optional_arguments.any? # rubocop:disable Metrics/LineLength
89
+ required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any? # rubocop:disable Metrics/LineLength
90
+ optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any? # rubocop:disable Metrics/LineLength
87
91
  result = [required, optional].compact
88
92
 
89
- " #{result.join(' ')}" unless result.empty?
93
+ " #{result.join(" ")}" unless result.empty?
90
94
  end
91
95
 
92
96
  # @since 0.1.0
93
97
  # @api private
94
98
  def self.extended_command_arguments(command)
95
99
  command.arguments.map do |argument|
96
- " #{argument.name.to_s.upcase.ljust(20)}\t# #{'REQUIRED ' if argument.required?}#{argument.desc}" # rubocop:disable Metrics/LineLength
100
+ " #{argument.name.to_s.upcase.ljust(32)} # #{"REQUIRED " if argument.required?}#{argument.desc}" # rubocop:disable Metrics/LineLength
97
101
  end.join("\n")
98
102
  end
99
103
 
@@ -110,16 +114,22 @@ module Dry
110
114
  else
111
115
  "#{name}=VALUE"
112
116
  end
113
- name = "#{name}, #{option.alias_names.join(', ')}" if option.aliases.any?
117
+ name = "#{name}, #{option.alias_names.join(", ")}" if option.aliases.any?
114
118
  name = " --#{name.ljust(30)}"
115
- name = "#{name}\t# #{option.desc}"
119
+ name = "#{name} # #{option.desc}"
116
120
  name = "#{name}, default: #{option.default.inspect}" unless option.default.nil?
117
121
  name
118
122
  end
119
123
 
120
- result << " --#{'help, -h'.ljust(30)}\t# Print this help"
124
+ result << " --#{"help, -h".ljust(30)} # Print this help"
121
125
  result.join("\n")
122
126
  end
127
+
128
+ def self.build_subcommands_list(subcommands)
129
+ subcommands.map do |subcommand_name, subcommand|
130
+ " #{subcommand_name.ljust(32)} # #{subcommand.command.description}"
131
+ end.join("\n")
132
+ end
123
133
  end
124
134
  end
125
135
  end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
4
- require 'concurrent/array'
5
- require 'dry/cli/option'
3
+ require "forwardable"
4
+ require "dry/cli/option"
6
5
 
7
6
  module Dry
8
7
  class CLI
@@ -14,25 +13,20 @@ module Dry
14
13
  # @api private
15
14
  def self.inherited(base)
16
15
  super
16
+ base.class_eval do
17
+ @_mutex = Mutex.new
18
+ @description = nil
19
+ @examples = []
20
+ @subcommands = []
21
+ @arguments = base.superclass_arguments || []
22
+ @options = base.superclass_options || []
23
+ end
17
24
  base.extend ClassMethods
18
25
  end
19
26
 
20
27
  # @since 0.1.0
21
28
  # @api private
22
29
  module ClassMethods
23
- # @since 0.1.0
24
- # @api private
25
- def self.extended(base)
26
- super
27
-
28
- base.class_eval do
29
- @description = nil
30
- @examples = Concurrent::Array.new
31
- @arguments = Concurrent::Array.new
32
- @options = Concurrent::Array.new
33
- end
34
- end
35
-
36
30
  # @since 0.1.0
37
31
  # @api private
38
32
  attr_reader :description
@@ -48,6 +42,14 @@ module Dry
48
42
  # @since 0.1.0
49
43
  # @api private
50
44
  attr_reader :options
45
+
46
+ # @since 0.7.0
47
+ # @api private
48
+ attr_reader :subcommands
49
+
50
+ # @since 0.7.0
51
+ # @api private
52
+ attr_writer :subcommands
51
53
  end
52
54
 
53
55
  # Set the description of the command
@@ -103,7 +105,7 @@ module Dry
103
105
  # # foo server --port=2306 # Bind to a port
104
106
  # # foo server --no-code-reloading # Disable code reloading
105
107
  def self.example(*examples)
106
- @examples += examples.flatten
108
+ @examples += examples.flatten(1)
107
109
  end
108
110
 
109
111
  # Specify an argument
@@ -211,7 +213,7 @@ module Dry
211
213
  # require "dry/cli"
212
214
  #
213
215
  # class Console < Dry::CLI::Command
214
- # param :engine
216
+ # option :engine
215
217
  #
216
218
  # def call(engine: nil, **)
217
219
  # puts "starting console (engine: #{engine || :irb})"
@@ -228,7 +230,7 @@ module Dry
228
230
  # require "dry/cli"
229
231
  #
230
232
  # class Console < Dry::CLI::Command
231
- # param :engine, values: %w(irb pry ripl)
233
+ # option :engine, values: %w(irb pry ripl)
232
234
  #
233
235
  # def call(engine: nil, **)
234
236
  # puts "starting console (engine: #{engine || :irb})"
@@ -242,13 +244,13 @@ module Dry
242
244
  # # starting console (engine: pry)
243
245
  #
244
246
  # # $ foo console --engine=foo
245
- # # Error: Invalid param provided
247
+ # # ERROR: Invalid param provided
246
248
  #
247
249
  # @example Description
248
250
  # require "dry/cli"
249
251
  #
250
252
  # class Console < Dry::CLI::Command
251
- # param :engine, desc: "Force a console engine"
253
+ # option :engine, desc: "Force a console engine"
252
254
  #
253
255
  # def call(engine: nil, **)
254
256
  # # ...
@@ -266,7 +268,7 @@ module Dry
266
268
  # require "dry/cli"
267
269
  #
268
270
  # class Server < Dry::CLI::Command
269
- # param :code_reloading, type: :boolean, default: true
271
+ # option :code_reloading, type: :boolean, default: true
270
272
  #
271
273
  # def call(code_reloading:, **)
272
274
  # puts "staring server (code reloading: #{code_reloading})"
@@ -289,7 +291,7 @@ module Dry
289
291
  # require "dry/cli"
290
292
  #
291
293
  # class Server < Dry::CLI::Command
292
- # param :port, aliases: ["-p"]
294
+ # option :port, aliases: ["-p"]
293
295
  #
294
296
  # def call(options)
295
297
  # puts "staring server (port: #{options.fetch(:port, 2300)})"
@@ -317,7 +319,9 @@ module Dry
317
319
  # @since 0.1.0
318
320
  # @api private
319
321
  def self.params
320
- (@arguments + @options).uniq
322
+ @_mutex.synchronize do
323
+ (@arguments + @options).uniq
324
+ end
321
325
  end
322
326
 
323
327
  # @since 0.1.0
@@ -340,6 +344,32 @@ module Dry
340
344
  arguments.reject(&:required?)
341
345
  end
342
346
 
347
+ # @since 0.7.0
348
+ # @api private
349
+ def self.subcommands
350
+ subcommands
351
+ end
352
+
353
+ # @since 0.7.0
354
+ # @api private
355
+ def self.superclass_variable_dup(var)
356
+ if superclass.instance_variable_defined?(var)
357
+ superclass.instance_variable_get(var).dup
358
+ end
359
+ end
360
+
361
+ # @since 0.7.0
362
+ # @api private
363
+ def self.superclass_arguments
364
+ superclass_variable_dup(:@arguments)
365
+ end
366
+
367
+ # @since 0.7.0
368
+ # @api private
369
+ def self.superclass_options
370
+ superclass_variable_dup(:@options)
371
+ end
372
+
343
373
  extend Forwardable
344
374
 
345
375
  delegate %i[
@@ -351,7 +381,8 @@ module Dry
351
381
  default_params
352
382
  required_arguments
353
383
  optional_arguments
354
- ] => 'self.class'
384
+ subcommands
385
+ ] => "self.class"
355
386
  end
356
387
  end
357
388
  end