rfix 1.4.1 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/exe/rfix +78 -34
  3. data/lib/rfix.rb +17 -28
  4. data/lib/rfix/branch.rb +3 -25
  5. data/lib/rfix/branch/base.rb +27 -0
  6. data/lib/rfix/branch/head.rb +15 -0
  7. data/lib/rfix/branch/main.rb +33 -0
  8. data/lib/rfix/branch/name.rb +21 -0
  9. data/lib/rfix/branch/reference.rb +15 -0
  10. data/lib/rfix/branch/upstream.rb +17 -0
  11. data/lib/rfix/cli/command.rb +19 -0
  12. data/lib/rfix/cli/command/base.rb +65 -0
  13. data/lib/rfix/cli/command/branch.rb +13 -0
  14. data/lib/rfix/cli/command/config.rb +22 -0
  15. data/lib/rfix/cli/command/extension.rb +25 -0
  16. data/lib/rfix/cli/command/help.rb +11 -0
  17. data/lib/rfix/cli/command/info.rb +11 -0
  18. data/lib/rfix/cli/command/lint.rb +17 -0
  19. data/lib/rfix/cli/command/local.rb +11 -0
  20. data/lib/rfix/cli/command/origin.rb +11 -0
  21. data/lib/rfix/cli/command/setup.rb +11 -0
  22. data/lib/rfix/error.rb +5 -1
  23. data/lib/rfix/extension/offense.rb +79 -0
  24. data/lib/rfix/extension/pastel.rb +11 -0
  25. data/lib/rfix/extension/string.rb +12 -0
  26. data/lib/rfix/extension/strings.rb +9 -0
  27. data/lib/rfix/file.rb +6 -41
  28. data/lib/rfix/file/base.rb +73 -0
  29. data/lib/rfix/file/deleted.rb +17 -0
  30. data/lib/rfix/file/ignored.rb +17 -0
  31. data/lib/rfix/file/tracked.rb +42 -0
  32. data/lib/rfix/file/untracked.rb +20 -0
  33. data/lib/rfix/formatter.rb +125 -86
  34. data/lib/rfix/highlighter.rb +118 -0
  35. data/lib/rfix/indicator.rb +19 -0
  36. data/lib/rfix/log.rb +12 -121
  37. data/lib/rfix/rake/gemfile.rb +111 -0
  38. data/lib/rfix/rake/paths.rb +25 -23
  39. data/lib/rfix/rake/support.rb +72 -57
  40. data/lib/rfix/repository.rb +114 -164
  41. data/lib/rfix/types.rb +52 -0
  42. data/lib/rfix/version.rb +1 -1
  43. data/rfix.gemspec +28 -38
  44. data/vendor/dry-cli/CHANGELOG.md +191 -0
  45. data/vendor/dry-cli/CODEOWNERS +1 -0
  46. data/vendor/dry-cli/CODE_OF_CONDUCT.md +13 -0
  47. data/vendor/dry-cli/CONTRIBUTING.md +29 -0
  48. data/vendor/dry-cli/Gemfile +14 -0
  49. data/vendor/dry-cli/Gemfile.devtools +18 -0
  50. data/vendor/dry-cli/LICENSE +20 -0
  51. data/vendor/dry-cli/README.md +29 -0
  52. data/vendor/dry-cli/Rakefile +13 -0
  53. data/vendor/dry-cli/bin/console +15 -0
  54. data/vendor/dry-cli/bin/setup +8 -0
  55. data/vendor/dry-cli/changelog.yml +97 -0
  56. data/vendor/dry-cli/docsite/source/arguments.html.md +57 -0
  57. data/vendor/dry-cli/docsite/source/callbacks.html.md +51 -0
  58. data/vendor/dry-cli/docsite/source/commands-with-subcommands-and-params.md +86 -0
  59. data/vendor/dry-cli/docsite/source/commands.html.md +41 -0
  60. data/vendor/dry-cli/docsite/source/index.html.md +302 -0
  61. data/vendor/dry-cli/docsite/source/options.html.md +51 -0
  62. data/vendor/dry-cli/docsite/source/subcommands.html.md +38 -0
  63. data/vendor/dry-cli/docsite/source/variadic-arguments.html.md +45 -0
  64. data/vendor/dry-cli/dry-cli.gemspec +36 -0
  65. data/vendor/dry-cli/lib/dry/cli.rb +224 -0
  66. data/vendor/dry-cli/lib/dry/cli/banner.rb +135 -0
  67. data/vendor/dry-cli/lib/dry/cli/command.rb +387 -0
  68. data/vendor/dry-cli/lib/dry/cli/command_registry.rb +253 -0
  69. data/vendor/dry-cli/lib/dry/cli/errors.rb +37 -0
  70. data/vendor/dry-cli/lib/dry/cli/inflector.rb +17 -0
  71. data/vendor/dry-cli/lib/dry/cli/inline.rb +75 -0
  72. data/vendor/dry-cli/lib/dry/cli/option.rb +131 -0
  73. data/vendor/dry-cli/lib/dry/cli/parser.rb +138 -0
  74. data/vendor/dry-cli/lib/dry/cli/program_name.rb +21 -0
  75. data/vendor/dry-cli/lib/dry/cli/registry.rb +338 -0
  76. data/vendor/dry-cli/lib/dry/cli/usage.rb +94 -0
  77. data/vendor/dry-cli/lib/dry/cli/version.rb +8 -0
  78. data/vendor/dry-cli/project.yml +13 -0
  79. data/vendor/dry-cli/spec/integration/commands_spec.rb +14 -0
  80. data/vendor/dry-cli/spec/integration/inherited_commands_spec.rb +24 -0
  81. data/vendor/dry-cli/spec/integration/inline_spec.rb +43 -0
  82. data/vendor/dry-cli/spec/integration/processes_errors_spec.rb +29 -0
  83. data/vendor/dry-cli/spec/integration/rendering_spec.rb +31 -0
  84. data/vendor/dry-cli/spec/integration/single_command_spec.rb +81 -0
  85. data/vendor/dry-cli/spec/integration/subcommands_spec.rb +60 -0
  86. data/vendor/dry-cli/spec/integration/third_party_gems_spec.rb +18 -0
  87. data/vendor/dry-cli/spec/spec_helper.rb +15 -0
  88. data/vendor/dry-cli/spec/support/coverage.rb +15 -0
  89. data/vendor/dry-cli/spec/support/files.rb +13 -0
  90. data/vendor/dry-cli/spec/support/fixtures/based +65 -0
  91. data/vendor/dry-cli/spec/support/fixtures/baz +9 -0
  92. data/vendor/dry-cli/spec/support/fixtures/baz_command.rb +19 -0
  93. data/vendor/dry-cli/spec/support/fixtures/foo +588 -0
  94. data/vendor/dry-cli/spec/support/fixtures/infinites +31 -0
  95. data/vendor/dry-cli/spec/support/fixtures/inline +20 -0
  96. data/vendor/dry-cli/spec/support/fixtures/registry.rb +15 -0
  97. data/vendor/dry-cli/spec/support/fixtures/shared_commands.rb +596 -0
  98. data/vendor/dry-cli/spec/support/fixtures/with_block.rb +86 -0
  99. data/vendor/dry-cli/spec/support/fixtures/with_registry.rb +90 -0
  100. data/vendor/dry-cli/spec/support/fixtures/with_zero_arity_block.rb +87 -0
  101. data/vendor/dry-cli/spec/support/helpers.rb +37 -0
  102. data/vendor/dry-cli/spec/support/path.rb +24 -0
  103. data/vendor/dry-cli/spec/support/rspec.rb +26 -0
  104. data/vendor/dry-cli/spec/support/rspec_options.rb +16 -0
  105. data/vendor/dry-cli/spec/support/shared_examples/commands.rb +300 -0
  106. data/vendor/dry-cli/spec/support/shared_examples/inherited_commands.rb +197 -0
  107. data/vendor/dry-cli/spec/support/shared_examples/rendering.rb +181 -0
  108. data/vendor/dry-cli/spec/support/shared_examples/subcommands.rb +226 -0
  109. data/vendor/dry-cli/spec/support/shared_examples/third_party_gems.rb +49 -0
  110. data/vendor/dry-cli/spec/support/warnings.rb +10 -0
  111. data/vendor/dry-cli/spec/unit/dry/cli/cli_spec.rb +123 -0
  112. data/vendor/dry-cli/spec/unit/dry/cli/inflector_spec.rb +26 -0
  113. data/vendor/dry-cli/spec/unit/dry/cli/registry_spec.rb +78 -0
  114. data/vendor/dry-cli/spec/unit/dry/cli/version_spec.rb +7 -0
  115. data/vendor/strings-ansi/CHANGELOG.md +24 -0
  116. data/vendor/strings-ansi/CODE_OF_CONDUCT.md +74 -0
  117. data/vendor/strings-ansi/Gemfile +11 -0
  118. data/{LICENSE.txt → vendor/strings-ansi/LICENSE.txt} +1 -1
  119. data/vendor/strings-ansi/README.md +155 -0
  120. data/vendor/strings-ansi/Rakefile +8 -0
  121. data/vendor/strings-ansi/appveyor.yml +32 -0
  122. data/vendor/strings-ansi/bin/console +14 -0
  123. data/vendor/strings-ansi/bin/setup +8 -0
  124. data/vendor/strings-ansi/lib/strings-ansi.rb +1 -0
  125. data/vendor/strings-ansi/lib/strings/ansi.rb +84 -0
  126. data/vendor/strings-ansi/lib/strings/ansi/extensions.rb +23 -0
  127. data/vendor/strings-ansi/lib/strings/ansi/version.rb +7 -0
  128. data/vendor/strings-ansi/spec/fixtures/ansi_codes.yaml +194 -0
  129. data/vendor/strings-ansi/spec/spec_helper.rb +51 -0
  130. data/vendor/strings-ansi/spec/unit/ansi_spec.rb +15 -0
  131. data/vendor/strings-ansi/spec/unit/extensions_spec.rb +19 -0
  132. data/vendor/strings-ansi/spec/unit/only_ansi_spec.rb +36 -0
  133. data/vendor/strings-ansi/spec/unit/sanitize_spec.rb +53 -0
  134. data/vendor/strings-ansi/strings-ansi.gemspec +34 -0
  135. data/vendor/strings-ansi/tasks/console.rake +11 -0
  136. data/vendor/strings-ansi/tasks/coverage.rake +11 -0
  137. data/vendor/strings-ansi/tasks/spec.rake +29 -0
  138. metadata +274 -188
  139. data/.github/workflows/main.yml +0 -26
  140. data/.gitignore +0 -43
  141. data/.rspec +0 -2
  142. data/.rubocop.yml +0 -87
  143. data/.travis.yml +0 -35
  144. data/Gemfile +0 -2
  145. data/Gemfile.base +0 -14
  146. data/Gemfile.base.lock +0 -172
  147. data/Gemfile.lock +0 -188
  148. data/Guardfile +0 -16
  149. data/Makefile +0 -12
  150. data/README.md +0 -85
  151. data/Rakefile +0 -31
  152. data/bin/bundle +0 -114
  153. data/bin/console +0 -29
  154. data/bin/guard +0 -29
  155. data/bin/rake +0 -29
  156. data/bin/rfix +0 -29
  157. data/bin/rspec +0 -29
  158. data/bin/setup +0 -29
  159. data/ci/Gemfile.rubocop-0.80 +0 -2
  160. data/ci/Gemfile.rubocop-0.80.lock +0 -170
  161. data/ci/Gemfile.rubocop-0.81 +0 -2
  162. data/ci/Gemfile.rubocop-0.81.lock +0 -170
  163. data/ci/Gemfile.rubocop-0.82 +0 -2
  164. data/ci/Gemfile.rubocop-0.82.lock +0 -170
  165. data/ci/Gemfile.rubocop-0.83 +0 -2
  166. data/ci/Gemfile.rubocop-0.83.lock +0 -168
  167. data/ci/Gemfile.rubocop-0.84 +0 -2
  168. data/ci/Gemfile.rubocop-0.84.lock +0 -171
  169. data/ci/Gemfile.rubocop-0.85 +0 -2
  170. data/ci/Gemfile.rubocop-0.85.1 +0 -2
  171. data/ci/Gemfile.rubocop-0.85.1.lock +0 -173
  172. data/ci/Gemfile.rubocop-0.85.lock +0 -173
  173. data/lib/rfix/box.rb +0 -112
  174. data/lib/rfix/branches/base.rb +0 -15
  175. data/lib/rfix/branches/head.rb +0 -13
  176. data/lib/rfix/branches/main.rb +0 -28
  177. data/lib/rfix/branches/name.rb +0 -23
  178. data/lib/rfix/branches/reference.rb +0 -21
  179. data/lib/rfix/branches/upstream.rb +0 -13
  180. data/lib/rfix/cmd.rb +0 -39
  181. data/lib/rfix/commands/branch.rb +0 -15
  182. data/lib/rfix/commands/extensions/options.rb +0 -8
  183. data/lib/rfix/commands/help.rb +0 -7
  184. data/lib/rfix/commands/helper/args.rb +0 -141
  185. data/lib/rfix/commands/helper/help.rb +0 -6
  186. data/lib/rfix/commands/helper/loader.rb +0 -6
  187. data/lib/rfix/commands/helper/option.rb +0 -0
  188. data/lib/rfix/commands/helper/params.rb +0 -0
  189. data/lib/rfix/commands/helper/rubocop.rb +0 -17
  190. data/lib/rfix/commands/info.rb +0 -30
  191. data/lib/rfix/commands/lint.rb +0 -22
  192. data/lib/rfix/commands/local.rb +0 -12
  193. data/lib/rfix/commands/origin.rb +0 -19
  194. data/lib/rfix/commands/setup.rb +0 -29
  195. data/lib/rfix/commands/welcome.rb +0 -24
  196. data/lib/rfix/deleted.rb +0 -13
  197. data/lib/rfix/extensions/extensions.rb +0 -18
  198. data/lib/rfix/extensions/offense.rb +0 -78
  199. data/lib/rfix/extensions/string.rb +0 -8
  200. data/lib/rfix/file_cache.rb +0 -59
  201. data/lib/rfix/git_helper.rb +0 -59
  202. data/lib/rfix/indentation.rb +0 -39
  203. data/lib/rfix/loader/bundler.rb +0 -37
  204. data/lib/rfix/loader/env.rb +0 -33
  205. data/lib/rfix/loader/spec.rb +0 -41
  206. data/lib/rfix/no_file.rb +0 -13
  207. data/lib/rfix/rfix.rb +0 -34
  208. data/lib/rfix/tracked.rb +0 -72
  209. data/lib/rfix/tracked_file.rb +0 -16
  210. data/lib/rfix/untracked.rb +0 -13
  211. data/resources/ps.png +0 -0
  212. data/tasks/bump.rake +0 -11
  213. data/tasks/bundle.rake +0 -17
  214. data/tasks/complex.rake +0 -54
  215. data/tasks/execute.rake +0 -38
  216. data/tasks/libgit2.rake +0 -33
  217. data/tasks/simple.rake +0 -62
  218. data/tasks/travis.rake +0 -74
  219. data/tasks/vendor.rake +0 -34
@@ -0,0 +1,29 @@
1
+ [gem]: https://rubygems.org/gems/dry-cli
2
+ [actions]: https://github.com/dry-rb/dry-cli/actions
3
+ [codacy]: https://www.codacy.com/gh/dry-rb/dry-cli
4
+ [chat]: https://dry-rb.zulipchat.com
5
+ [inchpages]: http://inch-ci.org/github/dry-rb/dry-cli
6
+
7
+ # dry-cli [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
+
9
+ [![Gem Version](https://badge.fury.io/rb/dry-cli.svg)][gem]
10
+ [![CI Status](https://github.com/dry-rb/dry-cli/workflows/ci/badge.svg)][actions]
11
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/61dd5d070fc74f0cacf575b19d4930e1)][codacy]
12
+ [![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
+
15
+ ## Links
16
+
17
+ * [User documentation](http://dry-rb.org/gems/dry-cli)
18
+ * [API documentation](http://rubydoc.info/gems/dry-cli)
19
+
20
+ ## Supported Ruby versions
21
+
22
+ This library officially supports the following Ruby versions:
23
+
24
+ * MRI >= `2.5`
25
+ * jruby >= `9.2`
26
+
27
+ ## License
28
+
29
+ See `LICENSE` file.
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/gem_tasks"
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
6
+
7
+ require "rspec/core"
8
+ require "rspec/core/rake_task"
9
+
10
+ task default: :spec
11
+
12
+ desc "Run all specs in spec directory"
13
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "dry/cli"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,97 @@
1
+ ---
2
+ - version: 0.6.0
3
+ date: '2020-03-06'
4
+ added:
5
+ - "[Ivan Shamatov] Ability to pass command along with registry (for a singular command case)"
6
+ - "[Nikita Shilnikov] [Internal] Backported ability to run gem's CI against ruby 2.3"
7
+ - "[Ivan Shamatov] Inline syntax for commands"
8
+ - "[Ivan Shamatov] Introduced stderr to any diagnostic output"
9
+ fixed:
10
+ - "[John Ledbetter & Luca Guidi] Fix ruby 2.7 warnings"
11
+ - "[Ivan Shamatov] Fix banner, when option is a type of Array"
12
+ - version: 0.5.1
13
+ date: '2020-01-23'
14
+ added:
15
+ - "[Ivan Shamatov] Anonymous Registry sintax"
16
+ - "[Ivan Shamatov] [Internal] Specs refactored, more unit specs added"
17
+ - "[Luca Guidi] [Internal] removed `dry-inflector` as runtime dependency"
18
+ - "[Ivan Shamatov] [Internal] Refactored Command class (command_name property removed)"
19
+ - "[Piotr Solnica, Luca Guidi, Nikita Shilnikov & Christian Georgii] [Internal] Adapt gem to dry-rb style"
20
+ fixed:
21
+ - "[Piotr Solnica] Added missing 'set' require"
22
+ - version: 0.5.0
23
+ date: '2019-12-21'
24
+ added:
25
+ - "[Ivan Shamatov, Piotr Solnica, Luca Guidi] [Internal] removed runtime and development
26
+ dependency against `hanami-utils`"
27
+ - version: 0.4.0
28
+ date: '2019-12-10'
29
+ added:
30
+ - "[Ivan Shamatov, Piotr Solnica, Luca Guidi] `hanami-cli` => `dry-cli`"
31
+ - version: 0.3.1
32
+ date: '2019-01-18'
33
+ added:
34
+ - "[Luca Guidi] Official support for Ruby: MRI 2.6"
35
+ - "[Luca Guidi] Support `bundler` 2.0+"
36
+ - version: 0.3.0
37
+ date: '2018-10-24'
38
+ - version: 0.3.0.beta1
39
+ date: '2018-08-08'
40
+ added:
41
+ - "[Anton Davydov & Alfonso Uceda] Introduce array type for arguments (`foo exec
42
+ test spec/bookshelf/entities spec/bookshelf/repositories`)"
43
+ - "[Anton Davydov & Alfonso Uceda] Introduce array type for options (`foo generate
44
+ config --apps=web,api`)"
45
+ - "[Alfonso Uceda] Introduce variadic arguments (`foo run ruby:latest -- ruby -v`)"
46
+ - "[Luca Guidi] Official support for JRuby 9.2.0.0"
47
+ fixed:
48
+ - '[Anton Davydov] Print informative message when unknown or wrong option is passed
49
+ (`"test" was called with arguments "--framework=unknown"`)'
50
+ - version: 0.2.0
51
+ date: '2018-04-11'
52
+ - version: 0.2.0.rc2
53
+ date: '2018-04-06'
54
+ - version: 0.2.0.rc1
55
+ date: '2018-03-30'
56
+ - version: 0.2.0.beta2
57
+ date: '2018-03-23'
58
+ added:
59
+ - "[Anton Davydov & Luca Guidi] Support objects as callbacks"
60
+ fixed:
61
+ - "[Anton Davydov & Luca Guidi] Ensure callbacks' context of execution (aka `self`)
62
+ to be the command that is being executed"
63
+ - version: 0.2.0.beta1
64
+ date: '2018-02-28'
65
+ added:
66
+ - "[Anton Davydov] Register `before`/`after` callbacks for commands"
67
+ - version: 0.1.1
68
+ date: '2018-02-27'
69
+ added:
70
+ - "[Luca Guidi] Official support for Ruby: MRI 2.5"
71
+ fixed:
72
+ - "[Alfonso Uceda] Ensure default values for arguments to be sent to commands"
73
+ - "[Alfonso Uceda] Ensure to fail when a missing required argument isn't provider,
74
+ but an option is provided instead"
75
+ - version: 0.1.0
76
+ date: '2017-10-25'
77
+ - version: 0.1.0.rc1
78
+ date: '2017-10-16'
79
+ - version: 0.1.0.beta3
80
+ date: '2017-10-04'
81
+ - version: 0.1.0.beta2
82
+ date: '2017-10-03'
83
+ added:
84
+ - " [Alfonso Uceda] Allow default value for arguments"
85
+ - version: 0.1.0.beta1
86
+ date: '2017-08-11'
87
+ added:
88
+ - " [Alfonso Uceda, Luca Guidi] Commands banner and usage"
89
+ - " [Alfonso Uceda] Added support for subcommands"
90
+ - "[Alfonso Uceda] Validations for arguments and options"
91
+ - "[Alfonso Uceda] Commands arguments and options"
92
+ - "[Alfonso Uceda] Commands description"
93
+ - "[Alfonso Uceda, Oana Sipos] Commands aliases"
94
+ - "[Luca Guidi] Exit on unknown command"
95
+ - "[Luca Guidi, Alfonso Uceda, Oana Sipos] Command lookup"
96
+ - "[Luca Guidi, Tim Riley] Trie based registry to register commands and allow third-parties
97
+ to override/add commands"
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Arguments
3
+ layout: gem-single
4
+ name: dry-cli
5
+ ---
6
+
7
+ An argument is a token passed after the _command name_.
8
+ For instance, given the `foo greet` command, when an user types `foo greet Luca`, then `Luca` is considered an argument.
9
+ A command can accept none or many arguments.
10
+ An argument can be declared as _required_.
11
+
12
+ ```ruby
13
+ #!/usr/bin/env ruby
14
+ require "bundler/setup"
15
+ require "dry/cli"
16
+
17
+ module Foo
18
+ module CLI
19
+ module Commands
20
+ extend Dry::CLI::Registry
21
+
22
+ class Greet < Dry::CLI::Command
23
+ argument :name, required: true, desc: "The name of the person to greet"
24
+ argument :age, desc: "The age of the person to greet"
25
+
26
+ def call(name:, age: nil, **)
27
+ result = "Hello, #{name}."
28
+ result = "#{result} You are #{age} years old." unless age.nil?
29
+
30
+ puts result
31
+ end
32
+ end
33
+
34
+ register "greet", Greet
35
+ end
36
+ end
37
+ end
38
+
39
+ Dry::CLI.new(Foo::CLI::Commands).call
40
+ ```
41
+
42
+ ```sh
43
+ $ foo greet Luca
44
+ Hello, Luca.
45
+ ```
46
+
47
+ ```sh
48
+ $ foo greet Luca 35
49
+ Hello, Luca. You are 35 years old.
50
+ ```
51
+
52
+ ```sh
53
+ $ foo greet
54
+ ERROR: "foo greet" was called with no arguments
55
+ Usage: "foo greet NAME"
56
+ ```
57
+
@@ -0,0 +1,51 @@
1
+ ---
2
+ title: Callbacks
3
+ layout: gem-single
4
+ name: dry-cli
5
+ ---
6
+
7
+ Third party gems can register _before_ and _after_ callbacks to enhance a command.
8
+
9
+ ### Example
10
+
11
+ From the `foo` gem we have a command `hello`.
12
+
13
+ ```ruby
14
+ #!/usr/bin/env ruby
15
+ require "dry/cli"
16
+
17
+ module Foo
18
+ module CLI
19
+ module Commands
20
+ extend Dry::CLI::Registry
21
+
22
+ class Hello < Dry::CLI::Command
23
+ argument :name, required: true
24
+
25
+ def call(name:, **)
26
+ puts "hello #{name}"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ Foo::CLI::Commands.register "hello", Foo::CLI::Commands::Hello
34
+
35
+ cli = Dry::CLI.new(Foo::CLI::Commands)
36
+ cli.call
37
+ ```
38
+
39
+ The `foo-bar` gem enhances `hello` command with callbacks:
40
+
41
+ ```ruby
42
+ Foo::CLI::Commands.before("hello") { |args| puts "debug: #{args.inspect}" } # syntax 1
43
+ Foo::CLI::Commands.after "hello", &->(args) { puts "bye, #{args.fetch(:name)}" } # syntax 2
44
+ ```
45
+
46
+ ```sh
47
+ $ foo hello Anton
48
+ debug: {:name=>"Anton"}
49
+ hello Anton
50
+ bye, Anton
51
+ ```
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: Commands with subcommands and params
3
+ layout: gem-single
4
+ name: dry-cli
5
+ ---
6
+
7
+ There is a way to register command with arguments, options and subcommands.
8
+
9
+ This helps to implement complex nested logic.
10
+
11
+ Arguments and options can be defined for parent both commands and child commands.
12
+
13
+ ^INFO
14
+ If you call a command with an argument equal to the name of the subcommand, it will call the subcommand instead of the parent command.
15
+ ^
16
+ ```ruby
17
+ #!/usr/bin/env ruby
18
+ require "bundler/setup"
19
+ require "dry/cli"
20
+
21
+ module Foo
22
+ module CLI
23
+ module Commands
24
+ extend Dry::CLI::Registry
25
+
26
+ class Account < Dry::CLI::Command
27
+ desc 'Information about account'
28
+
29
+ argument :format, default: "short", values: %w[long short], desc: "Output format"
30
+
31
+ def call(**options)
32
+ puts "Information about account in #{options.fetch(:format)} format."
33
+ end
34
+
35
+ class Users < Dry::CLI::Command
36
+ desc 'Information about account users'
37
+
38
+ def call(**_options)
39
+ puts "Information about account users."
40
+ end
41
+ end
42
+ end
43
+
44
+ register "account", Account
45
+ register "account users", Account::Users
46
+ end
47
+ end
48
+ end
49
+
50
+ Dry::CLI.new(Foo::CLI::Commands).call
51
+ ```
52
+ ```
53
+ $ foo account -h
54
+ Command:
55
+ foo account
56
+
57
+ Usage:
58
+ foo account [FORMAT] | foo account SUBCOMMAND
59
+
60
+ Description:
61
+ Information about account
62
+
63
+ Subcommands:
64
+ users # Information about account users
65
+
66
+ Arguments:
67
+ FORMAT # Output format: (long/short)
68
+
69
+ Options:
70
+ --help, -h # Print this help
71
+ ```
72
+ ```sh
73
+ $ foo account
74
+ # Information about account in short format.
75
+ ```
76
+
77
+ ```sh
78
+ $ foo account long
79
+ # Information about account in long format.
80
+ ```
81
+
82
+ ```sh
83
+ $ foo account users
84
+ # Information about account users.
85
+ ```
86
+
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Commands
3
+ layout: gem-single
4
+ name: dry-cli
5
+ ---
6
+
7
+ A command is a subclass of `Dry::CLI::Command` and it **must** respond to `#call(*)`.
8
+
9
+ For a given _command name_, you can register a corresponding _command_.
10
+
11
+ **Please note:** there is **no** convention between the _command name_ and the _command object_ class name.
12
+ The manual _registration_ assigns a _command object_ to a _command name_.
13
+
14
+ ```ruby
15
+ #!/usr/bin/env ruby
16
+ require "bundler/setup"
17
+ require "dry/cli"
18
+
19
+ module Foo
20
+ module CLI
21
+ module Commands
22
+ extend Dry::CLI::Registry
23
+
24
+ class Hello < Dry::CLI::Command
25
+ def call(*)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Version < Dry::CLI::Command
33
+ def call(*)
34
+ end
35
+ end
36
+
37
+ Foo::CLI::Commands.register "hi", Foo::CLI::Commands::Hello
38
+ Foo::CLI::Commands.register "v", Version
39
+
40
+ Dry::CLI.new(Foo::CLI::Commands).call
41
+ ```
@@ -0,0 +1,302 @@
1
+ ---
2
+ title: Introduction
3
+ description: General purpose Command Line Interface (CLI) framework
4
+ layout: gem-single
5
+ type: gem
6
+ name: dry-cli
7
+ sections:
8
+ - commands
9
+ - subcommands
10
+ - arguments
11
+ - options
12
+ - variadic-arguments
13
+ - commands-with-subcommands-and-params
14
+ - callbacks
15
+ ---
16
+
17
+ `dry-cli` is a general-purpose framework for developing Command Line Interface (CLI) applications. It represents commands as objects that can be registered and offers support for arguments, options and forwarding variadic arguments to a sub-command.
18
+
19
+ ## Usage
20
+
21
+ The following is an elaborate example showcasing most of the available features.
22
+
23
+ Imagine you want to build a CLI executable `foo` for your Ruby project. The entire program is defined as below:
24
+
25
+ ```ruby
26
+ #!/usr/bin/env ruby
27
+ require "bundler/setup"
28
+ require "dry/cli"
29
+
30
+ module Foo
31
+ module CLI
32
+ module Commands
33
+ extend Dry::CLI::Registry
34
+
35
+ class Version < Dry::CLI::Command
36
+ desc "Print version"
37
+
38
+ def call(*)
39
+ puts "1.0.0"
40
+ end
41
+ end
42
+
43
+ class Echo < Dry::CLI::Command
44
+ desc "Print input"
45
+
46
+ argument :input, desc: "Input to print"
47
+
48
+ example [
49
+ " # Prints 'wuh?'",
50
+ "hello, folks # Prints 'hello, folks'"
51
+ ]
52
+
53
+ def call(input: nil, **)
54
+ if input.nil?
55
+ puts "wuh?"
56
+ else
57
+ puts input
58
+ end
59
+ end
60
+ end
61
+
62
+ class Start < Dry::CLI::Command
63
+ desc "Start Foo machinery"
64
+
65
+ argument :root, required: true, desc: "Root directory"
66
+
67
+ example [
68
+ "path/to/root # Start Foo at root directory"
69
+ ]
70
+
71
+ def call(root:, **)
72
+ puts "started - root: #{root}"
73
+ end
74
+ end
75
+
76
+ class Stop < Dry::CLI::Command
77
+ desc "Stop Foo machinery"
78
+
79
+ option :graceful, type: :boolean, default: true, desc: "Graceful stop"
80
+
81
+ def call(**options)
82
+ puts "stopped - graceful: #{options.fetch(:graceful)}"
83
+ end
84
+ end
85
+
86
+ class Exec < Dry::CLI::Command
87
+ desc "Execute a task"
88
+
89
+ argument :task, type: :string, required: true, desc: "Task to be executed"
90
+ argument :dirs, type: :array, required: false, desc: "Optional directories"
91
+
92
+ def call(task:, dirs: [], **)
93
+ puts "exec - task: #{task}, dirs: #{dirs.inspect}"
94
+ end
95
+ end
96
+
97
+ module Generate
98
+ class Configuration < Dry::CLI::Command
99
+ desc "Generate configuration"
100
+
101
+ option :apps, type: :array, default: [], desc: "Generate configuration for specific apps"
102
+
103
+ def call(apps:, **)
104
+ puts "generated configuration for apps: #{apps.inspect}"
105
+ end
106
+ end
107
+
108
+ class Test < Dry::CLI::Command
109
+ desc "Generate tests"
110
+
111
+ option :framework, default: "minitest", values: %w[minitest rspec]
112
+
113
+ def call(framework:, **)
114
+ puts "generated tests - framework: #{framework}"
115
+ end
116
+ end
117
+ end
118
+
119
+ register "version", Version, aliases: ["v", "-v", "--version"]
120
+ register "echo", Echo
121
+ register "start", Start
122
+ register "stop", Stop
123
+ register "exec", Exec
124
+
125
+ register "generate", aliases: ["g"] do |prefix|
126
+ prefix.register "config", Generate::Configuration
127
+ prefix.register "test", Generate::Test
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ Dry::CLI.new(Foo::CLI::Commands).call
134
+ ```
135
+
136
+ ### Available commands
137
+
138
+ With this code in place, we can now have a look at the command line usage by issuing the command `foo` without any arguments or options:
139
+
140
+ ```sh
141
+ $ foo
142
+ Commands:
143
+ foo echo [INPUT] # Print input
144
+ foo exec TASK [DIRS] # Execute a task
145
+ foo generate [SUBCOMMAND]
146
+ foo start ROOT # Start Foo machinery
147
+ foo stop # Stop Foo machinery
148
+ foo version # Print version
149
+ ```
150
+
151
+ ### Help
152
+
153
+ It is also possible to get help for a particular command using the `--help` flag:
154
+
155
+ ```sh
156
+ $ foo echo --help
157
+ Command:
158
+ foo echo
159
+
160
+ Usage:
161
+ foo echo [INPUT]
162
+
163
+ Description:
164
+ Print input
165
+
166
+ Arguments:
167
+ INPUT # Input to print
168
+
169
+ Options:
170
+ --help, -h # Print this help
171
+
172
+ Examples:
173
+ foo echo # Prints 'wuh?'
174
+ foo echo hello, folks # Prints 'hello, folks'
175
+ ```
176
+
177
+ ### Optional arguments
178
+
179
+ A command can have optional arguments, which enables a default action in case nothing is provided:
180
+
181
+ ```sh
182
+ $ foo echo
183
+ wuh?
184
+
185
+ $ foo echo hello
186
+ hello
187
+ ```
188
+
189
+ ### Required arguments
190
+
191
+ On the other hand, required arguments will throw an error if not provided:
192
+
193
+ ```sh
194
+ $ foo start .
195
+ started - root: .
196
+ ```
197
+
198
+ ```sh
199
+ $ foo start
200
+ ERROR: "foo start" was called with no arguments
201
+ Usage: "foo start ROOT"
202
+ ```
203
+
204
+ ### Array arguments
205
+
206
+ Captures all the remaining arguments in a single array.
207
+ Please note that `array` argument must be used as the last argument, as it works as a _"catch-all"_.
208
+
209
+ ```sh
210
+ $ foo exec test
211
+ exec - task: test, dirs: []
212
+ ```
213
+
214
+ ```sh
215
+ $ foo exec test spec/bookshelf/entities spec/bookshelf/repositories
216
+ exec - task: test, dirs: ["spec/bookshelf/entities", "spec/bookshelf/repositories"]
217
+ ```
218
+
219
+ ### Options
220
+
221
+ An option is a named argument that is passed after the command name and the arguments:
222
+
223
+ ```sh
224
+ $ foo generate test
225
+ generated tests - framework: minitest
226
+ ```
227
+
228
+ ```sh
229
+ $ foo generate test --framework=rspec
230
+ generated tests - framework: rspec
231
+ ```
232
+
233
+ ```sh
234
+ $ foo generate test --framework=unknown
235
+ ERROR: "foo generate test" was called with arguments "--framework=unknown"
236
+ ```
237
+
238
+ ### Boolean options
239
+
240
+ Boolean options are flags that change the behaviour of a command:
241
+
242
+ ```sh
243
+ $ foo stop
244
+ stopped - graceful: true
245
+ ```
246
+
247
+ ```sh
248
+ $ foo stop --no-graceful
249
+ stopped - graceful: false
250
+ ```
251
+
252
+ ### Array options
253
+
254
+ Array options are similar to arguments but must be named:
255
+
256
+ ```sh
257
+ $ foo generate config --apps=web,api
258
+ generated configuration for apps: ["web", "api"]
259
+ ```
260
+
261
+ ### Subcommands
262
+
263
+ Subcommands are simply commands that have been registered under a nested path:
264
+
265
+ ```sh
266
+ $ foo generate
267
+ Commands:
268
+ foo generate config # Generate configuration
269
+ foo generate test # Generate tests
270
+ ```
271
+
272
+ ### Aliases
273
+
274
+ Aliases are supported:
275
+
276
+ ```sh
277
+ $ foo version
278
+ 1.0.0
279
+ ```
280
+
281
+ ```sh
282
+ $ foo v
283
+ 1.0.0
284
+ ```
285
+
286
+ ```sh
287
+ $ foo -v
288
+ 1.0.0
289
+ ```
290
+
291
+ ```sh
292
+ $ foo --version
293
+ 1.0.0
294
+ ```
295
+
296
+ ### Subcommand aliases
297
+
298
+ Work similarly to command aliases
299
+ ```sh
300
+ $ foo g config
301
+ generated configuration for apps: []
302
+ ```