cli-kit 4.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/cla.yml +22 -0
  3. data/.github/workflows/ruby.yml +34 -2
  4. data/.gitignore +2 -0
  5. data/.rubocop.sorbet.yml +47 -0
  6. data/.rubocop.yml +16 -1
  7. data/Gemfile +10 -1
  8. data/Gemfile.lock +94 -18
  9. data/README.md +46 -3
  10. data/Rakefile +1 -0
  11. data/bin/onchange +30 -0
  12. data/bin/tapioca +29 -0
  13. data/bin/testunit +1 -0
  14. data/cli-kit.gemspec +2 -2
  15. data/dev.yml +35 -3
  16. data/examples/minimal/example.rb +3 -1
  17. data/examples/single-file/example.rb +25 -35
  18. data/gen/lib/gen/commands/help.rb +8 -10
  19. data/gen/lib/gen/commands/new.rb +23 -9
  20. data/gen/lib/gen/commands.rb +21 -9
  21. data/gen/lib/gen/entry_point.rb +12 -3
  22. data/gen/lib/gen/generator.rb +28 -7
  23. data/gen/lib/gen/help.rb +63 -0
  24. data/gen/lib/gen.rb +18 -23
  25. data/gen/template/bin/update-deps +2 -2
  26. data/gen/template/lib/__app__/commands.rb +1 -4
  27. data/gen/template/lib/__app__.rb +8 -17
  28. data/gen/template/test/example_test.rb +1 -1
  29. data/lib/cli/kit/args/definition.rb +344 -0
  30. data/lib/cli/kit/args/evaluation.rb +245 -0
  31. data/lib/cli/kit/args/parser/node.rb +132 -0
  32. data/lib/cli/kit/args/parser.rb +129 -0
  33. data/lib/cli/kit/args/tokenizer.rb +133 -0
  34. data/lib/cli/kit/args.rb +16 -0
  35. data/lib/cli/kit/base_command.rb +17 -32
  36. data/lib/cli/kit/command_help.rb +271 -0
  37. data/lib/cli/kit/command_registry.rb +69 -17
  38. data/lib/cli/kit/config.rb +25 -22
  39. data/lib/cli/kit/core_ext.rb +30 -0
  40. data/lib/cli/kit/error_handler.rb +131 -70
  41. data/lib/cli/kit/executor.rb +19 -3
  42. data/lib/cli/kit/ini.rb +31 -38
  43. data/lib/cli/kit/levenshtein.rb +12 -4
  44. data/lib/cli/kit/logger.rb +16 -2
  45. data/lib/cli/kit/opts.rb +301 -0
  46. data/lib/cli/kit/resolver.rb +8 -0
  47. data/lib/cli/kit/sorbet_runtime_stub.rb +156 -0
  48. data/lib/cli/kit/support/test_helper.rb +23 -14
  49. data/lib/cli/kit/support.rb +2 -0
  50. data/lib/cli/kit/system.rb +188 -54
  51. data/lib/cli/kit/util.rb +48 -103
  52. data/lib/cli/kit/version.rb +3 -1
  53. data/lib/cli/kit.rb +103 -7
  54. metadata +22 -10
  55. data/.github/probots.yml +0 -2
  56. data/lib/cli/kit/autocall.rb +0 -21
  57. data/lib/cli/kit/ruby_backports/enumerable.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 523252459712e507c4579e244e6330eb3e8a5d8c71334d4e41553903ab651cd6
4
- data.tar.gz: 459cb0a684e2890718d0cffdd74cd8540bd91a1995dfe1db593df9a189da20d7
3
+ metadata.gz: e576da52278c6b0596840691bffbb12546b54bf2238145455a45333d6101f773
4
+ data.tar.gz: 24243f1a2d66ad3b12fb2728b73b608038950d958ffc31dc0ab7951c3714533a
5
5
  SHA512:
6
- metadata.gz: 8579924711573ce6338b52dc44c47ad40c12f925bbd6f3ad6cee5be9f44b2b4f315e6d272adc309788b0418ee6806567660f0386d7e91d9d09a524beeb0a4a1f
7
- data.tar.gz: b5507292ba97fd6f13b83b6426e81e4500e0ef1480387164c936164b7593bf7daac98e39cbb835362f198c39e562f2d12adf92384365a9c99a7f0ed42c158a45
6
+ metadata.gz: 8e7f4f5c4cc6620a2d98eca89e85ad57e6a9a0bd94ec704503ac0c9ba84f631984beb7c71c60e8b24ddbd2c4cf88b30cc298d3b05009f565450348a5b82c8d7f
7
+ data.tar.gz: ac1c63ad107ca13fda07413a17054a17bb69ec6ae793f2a0abb97a5c2616c15fe7aaeaf7c3328b7ce035136dd72007df51fe7f5aab15e0c90199ede7ddd8d1e0
@@ -0,0 +1,22 @@
1
+ name: Contributor License Agreement (CLA)
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, synchronize]
6
+ issue_comment:
7
+ types: [created]
8
+
9
+ jobs:
10
+ cla:
11
+ runs-on: ubuntu-latest
12
+ if: |
13
+ (github.event.issue.pull_request
14
+ && !github.event.issue.pull_request.merged_at
15
+ && contains(github.event.comment.body, 'signed')
16
+ )
17
+ || (github.event.pull_request && !github.event.pull_request.merged)
18
+ steps:
19
+ - uses: Shopify/shopify-cla-action@v1
20
+ with:
21
+ github-token: ${{ secrets.GITHUB_TOKEN }}
22
+ cla-token: ${{ secrets.CLA_TOKEN }}
@@ -3,6 +3,7 @@ name: Ruby
3
3
  on: [push, pull_request]
4
4
 
5
5
  jobs:
6
+
6
7
  style:
7
8
  runs-on: ubuntu-latest
8
9
  steps:
@@ -14,11 +15,24 @@ jobs:
14
15
  bundler-cache: true
15
16
  - name: Check style
16
17
  run: bundle exec rake style
18
+
19
+ typecheck:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - name: Set up Ruby
24
+ uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: '2.7'
27
+ bundler-cache: true
28
+ - name: Typecheck
29
+ run: bundle exec srb tc
30
+
17
31
  test:
18
32
  strategy:
19
33
  matrix:
20
- os: [macos-latest, ubuntu-latest, windows-latest]
21
- ruby-version: ['2.6', '2.7']
34
+ os: [macos-latest, ubuntu-latest]
35
+ ruby-version: ['2.7', '3.0']
22
36
 
23
37
  runs-on: ${{ matrix.os }}
24
38
  steps:
@@ -30,3 +44,21 @@ jobs:
30
44
  bundler-cache: true
31
45
  - name: Run tests
32
46
  run: bundle exec rake test
47
+
48
+ test-windows:
49
+ strategy:
50
+ matrix:
51
+ ruby-version: ['2.7', '3.0']
52
+
53
+ runs-on: windows-latest
54
+ env:
55
+ BUNDLE_WITHOUT: typecheck
56
+ steps:
57
+ - uses: actions/checkout@v2
58
+ - name: Set up Ruby
59
+ uses: ruby/setup-ruby@v1
60
+ with:
61
+ ruby-version: ${{ matrix.ruby-version }}
62
+ bundler-cache: true
63
+ - name: Run tests
64
+ run: bundle exec rake test
data/.gitignore CHANGED
@@ -4,6 +4,8 @@ build
4
4
  .DS_Store
5
5
  .bundle
6
6
 
7
+ /coverage
8
+
7
9
  .starscope.db
8
10
  cscope.out
9
11
  tags
@@ -0,0 +1,47 @@
1
+ Sorbet:
2
+ Enabled: true
3
+
4
+ Sorbet/ValidSigil:
5
+ Enabled: true
6
+ Exclude:
7
+ - lib/cli/kit/sorbet_runtime_stub.rb
8
+
9
+ Sorbet/FalseSigil:
10
+ Enabled: false
11
+
12
+ Sorbet/TrueSigil:
13
+ Enabled: true
14
+ Include:
15
+ - "**/*.rb"
16
+ - "**/*.rbi"
17
+ - "**/*.rake"
18
+ - "**/*.ru"
19
+ Exclude:
20
+ - lib/cli/kit/sorbet_runtime_stub.rb
21
+ - "test/**/*"
22
+ - "lib/cli/kit/support/test_helper.rb"
23
+
24
+ Sorbet/EnforceSigilOrder:
25
+ Enabled: true
26
+
27
+ Sorbet/EnforceSignatures:
28
+ Enabled: true
29
+ Exclude:
30
+ - lib/cli/kit/sorbet_runtime_stub.rb
31
+ - "test/**/*"
32
+ - bin/testunit
33
+ - "lib/cli/kit/support/test_helper.rb"
34
+
35
+ Sorbet/SignatureBuildOrder:
36
+ Enabled: true
37
+
38
+ Sorbet/KeywordArgumentOrdering:
39
+ Enabled: true
40
+
41
+ Sorbet/ConstantsFromStrings:
42
+ Enabled: true
43
+ Exclude:
44
+ - "examples/**/*"
45
+
46
+ Sorbet/ForbidIncludeConstLiteral:
47
+ Enabled: false
data/.rubocop.yml CHANGED
@@ -1,11 +1,18 @@
1
1
  inherit_gem:
2
2
  rubocop-shopify: rubocop-cli.yml
3
3
 
4
+ inherit_from:
5
+ - .rubocop.sorbet.yml
6
+
7
+ require:
8
+ - rubocop-sorbet
9
+
4
10
  AllCops:
5
11
  Exclude:
6
12
  - gen/template/**/*
7
13
  - vendor/**/*
8
- TargetRubyVersion: 2.5
14
+ TargetRubyVersion: 2.7
15
+ NewCops: disable
9
16
 
10
17
  Style/ClassAndModuleChildren:
11
18
  Exclude:
@@ -36,3 +43,11 @@ Style/MultilineBlockChain:
36
43
 
37
44
  Style/StringLiterals:
38
45
  EnforcedStyle: single_quotes
46
+
47
+ # We heavily manage output on purpose
48
+ Style/GlobalStdStream:
49
+ Enabled: false
50
+
51
+ # Sometimes (often) explicit is good
52
+ Style/EmptyElse:
53
+ Enabled: false
data/Gemfile CHANGED
@@ -4,14 +4,23 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
+ gem 'cli-ui', git: 'https://github.com/Shopify/cli-ui', ref: '0eefd57248f42ec163639884e77a071d82bfbda8'
7
8
  gem 'rubocop'
9
+ gem 'rubocop-rake'
8
10
  gem 'rubocop-shopify'
11
+ gem 'rubocop-sorbet'
9
12
  gem 'byebug'
10
13
  gem 'method_source'
14
+ gem 'simplecov'
15
+ end
16
+
17
+ group :typecheck do
18
+ gem 'sorbet-static-and-runtime'
19
+ gem 'tapioca', require: false
11
20
  end
12
21
 
13
22
  group :test do
14
- gem 'mocha', '~> 1.13.0', require: false
23
+ gem 'mocha', '~> 2.0.1', require: false
15
24
  gem 'minitest', '>= 5.0.0', require: false
16
25
  gem 'minitest-reporters', require: false
17
26
  end
data/Gemfile.lock CHANGED
@@ -1,3 +1,10 @@
1
+ GIT
2
+ remote: https://github.com/Shopify/cli-ui
3
+ revision: 0eefd57248f42ec163639884e77a071d82bfbda8
4
+ ref: 0eefd57248f42ec163639884e77a071d82bfbda8
5
+ specs:
6
+ cli-ui (1.5.1)
7
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
@@ -11,52 +18,121 @@ GEM
11
18
  ast (2.4.2)
12
19
  builder (3.2.4)
13
20
  byebug (11.1.3)
14
- cli-ui (1.5.1)
21
+ diff-lcs (1.5.0)
22
+ docile (1.4.0)
23
+ json (2.6.2)
15
24
  method_source (1.0.0)
16
- minitest (5.14.4)
17
- minitest-reporters (1.4.3)
25
+ minitest (5.16.3)
26
+ minitest-reporters (1.5.0)
18
27
  ansi
19
28
  builder
20
29
  minitest (>= 5.0)
21
30
  ruby-progressbar
22
- mocha (1.13.0)
23
- parallel (1.21.0)
24
- parser (3.0.2.0)
31
+ mocha (2.0.2)
32
+ ruby2_keywords (>= 0.0.5)
33
+ netrc (0.11.0)
34
+ parallel (1.22.1)
35
+ parser (3.1.2.1)
25
36
  ast (~> 2.4.1)
26
- rainbow (3.0.0)
37
+ rainbow (3.1.1)
27
38
  rake (13.0.6)
28
- regexp_parser (2.1.1)
39
+ rbi (0.0.16)
40
+ ast
41
+ parser (>= 2.6.4.0)
42
+ sorbet-runtime (>= 0.5.9204)
43
+ unparser
44
+ regexp_parser (2.6.0)
29
45
  rexml (3.2.5)
30
- rubocop (1.22.3)
46
+ rubocop (1.39.0)
47
+ json (~> 2.3)
31
48
  parallel (~> 1.10)
32
- parser (>= 3.0.0.0)
49
+ parser (>= 3.1.2.1)
33
50
  rainbow (>= 2.2.2, < 4.0)
34
51
  regexp_parser (>= 1.8, < 3.0)
35
- rexml
36
- rubocop-ast (>= 1.12.0, < 2.0)
52
+ rexml (>= 3.2.5, < 4.0)
53
+ rubocop-ast (>= 1.23.0, < 2.0)
37
54
  ruby-progressbar (~> 1.7)
38
55
  unicode-display_width (>= 1.4.0, < 3.0)
39
- rubocop-ast (1.12.0)
40
- parser (>= 3.0.1.1)
41
- rubocop-shopify (2.3.0)
42
- rubocop (~> 1.22)
56
+ rubocop-ast (1.23.0)
57
+ parser (>= 3.1.1.0)
58
+ rubocop-rake (0.6.0)
59
+ rubocop (~> 1.0)
60
+ rubocop-shopify (2.10.1)
61
+ rubocop (~> 1.35)
62
+ rubocop-sorbet (0.6.11)
63
+ rubocop (>= 0.90.0)
43
64
  ruby-progressbar (1.11.0)
44
- unicode-display_width (2.1.0)
65
+ ruby2_keywords (0.0.5)
66
+ simplecov (0.21.2)
67
+ docile (~> 1.1)
68
+ simplecov-html (~> 0.11)
69
+ simplecov_json_formatter (~> 0.1)
70
+ simplecov-html (0.12.3)
71
+ simplecov_json_formatter (0.1.4)
72
+ sorbet (0.5.10554)
73
+ sorbet-static (= 0.5.10554)
74
+ sorbet-runtime (0.5.10554)
75
+ sorbet-static (0.5.10554-universal-darwin-14)
76
+ sorbet-static (0.5.10554-universal-darwin-15)
77
+ sorbet-static (0.5.10554-universal-darwin-16)
78
+ sorbet-static (0.5.10554-universal-darwin-17)
79
+ sorbet-static (0.5.10554-universal-darwin-18)
80
+ sorbet-static (0.5.10554-universal-darwin-19)
81
+ sorbet-static (0.5.10554-universal-darwin-20)
82
+ sorbet-static (0.5.10554-universal-darwin-21)
83
+ sorbet-static (0.5.10554-universal-darwin-22)
84
+ sorbet-static (0.5.10554-x86_64-linux)
85
+ sorbet-static-and-runtime (0.5.10554)
86
+ sorbet (= 0.5.10554)
87
+ sorbet-runtime (= 0.5.10554)
88
+ spoom (1.1.12)
89
+ sorbet (>= 0.5.9204)
90
+ sorbet-runtime (>= 0.5.9204)
91
+ thor (>= 0.19.2)
92
+ tapioca (0.10.3)
93
+ bundler (>= 1.17.3)
94
+ netrc (>= 0.11.0)
95
+ parallel (>= 1.21.0)
96
+ rbi (~> 0.0.0, >= 0.0.16)
97
+ sorbet-static-and-runtime (>= 0.5.9892)
98
+ spoom (~> 1.1.0, >= 1.1.11)
99
+ thor (>= 1.2.0)
100
+ yard-sorbet
101
+ thor (1.2.1)
102
+ unicode-display_width (2.3.0)
103
+ unparser (0.6.5)
104
+ diff-lcs (~> 1.3)
105
+ parser (>= 3.1.0)
106
+ webrick (1.7.0)
107
+ yard (0.9.28)
108
+ webrick (~> 1.7.0)
109
+ yard-sorbet (0.7.0)
110
+ sorbet-runtime (>= 0.5)
111
+ yard (>= 0.9)
45
112
 
46
113
  PLATFORMS
114
+ arm64-darwin-21
47
115
  ruby
116
+ universal-darwin
117
+ x86_64-linux
48
118
 
49
119
  DEPENDENCIES
50
120
  bundler (~> 2.1)
51
121
  byebug
52
122
  cli-kit!
123
+ cli-ui!
53
124
  method_source
54
125
  minitest (>= 5.0.0)
55
126
  minitest-reporters
56
- mocha (~> 1.13.0)
127
+ mocha (~> 2.0.1)
57
128
  rake (~> 13.0)
58
129
  rubocop
130
+ rubocop-rake
59
131
  rubocop-shopify
132
+ rubocop-sorbet
133
+ simplecov
134
+ sorbet-static-and-runtime
135
+ tapioca
60
136
 
61
137
  BUNDLED WITH
62
138
  2.2.24
data/README.md CHANGED
@@ -26,9 +26,52 @@ select how the project consumes `cli-kit` and `cli-ui`. The available options a
26
26
 
27
27
  You're now ready to write your very first `cli-kit` application!
28
28
 
29
+ ## Upgrading to version 5
30
+
31
+ Version 5 includes breaking changes and significant new features. Notably:
32
+
33
+ * `autocall` is completely removed;
34
+ * A help system and command-line option parsing system is added.
35
+
36
+ Migrating away from `autocall` is as simple as replacing `autocall(:X) { y }` with `X = y`.
37
+
38
+ Using the new help system is not yet well-documented, but some hints can be found in the
39
+ `gen/ilb/gen/commands` directory of this repo. Existing commands in existing apps should continue to
40
+ work.
41
+
42
+ To use the new help system, commands should all define `invoke` instead of `call`. `invoke` takes
43
+ `name` as before, but the first argument is now an instance of `Opts`, defined in the command class,
44
+ which must be a subclass of `CLI::Kit::Opts`. For example:
45
+
46
+ ```ruby
47
+ class MyCommand < CLI::Kit::BaseCommand
48
+ class Opts < CLI::Kit::Opts
49
+ def force
50
+ flag(short: '-f', long: '--force', description: 'Force the operation')
51
+ end
52
+ end
53
+ def invoke(op, _name)
54
+ if op.force
55
+ puts 'Forcing the operation'
56
+ else
57
+ puts 'Not forcing the operation'
58
+ end
59
+ end
60
+ end
61
+ ```
62
+
63
+ This particular structure was chosen to allow the code to by fully typed using sorbet, as `invoke`
64
+ can be tagged with `sig { params(op: Opts, _name: String).void }`, and the `#force` method visibly
65
+ exists.
66
+
67
+ `-h/--help` is installed as a default flag, and running this command with `--help` is handled before
68
+ reaching `#invoke`, to print a help message (for which several other class methods on `BaseCommand`
69
+ provide text: `command_name`, `desc`, `long_desc`, `usage`, `example`, and `help_sections`). See
70
+ `gen/lib/gen/commands/new.rb` for an example.
71
+
29
72
  ## How do `cli-kit` Applications Work?
30
73
 
31
- The executable for your `cli-kit` app is stored in the "exe" directory. To execute the app, simply
74
+ The executable for your `cli-kit` app is stored in the "exe" directory. To execute the app, simply
32
75
  run:
33
76
  ```bash
34
77
  ./exe/myproject
@@ -38,7 +81,7 @@ run:
38
81
  * `/exe/` - Location of the executables for your application.
39
82
  * `/lib/` - Location of the resources for your app (modules, classes, helpers, etc).
40
83
  * `myproject.rb` - This file is the starting point for where to look for all other files. It
41
- configures autoload and autocall for the app.
84
+ configures autoload for the app.
42
85
  * `myproject/` - Stores the various commands/entry points.
43
86
  * `entry_point.rb` - This is the file that is first called from the executable. It handles
44
87
  loading and commands.
@@ -113,4 +156,4 @@ powerful command-line user interface elements. For more details on how to use `c
113
156
 
114
157
  ## Examples
115
158
 
116
- - [A Simple To-Do App](https://github.com/Shopify/cli-kit-example)
159
+ - [A Simple To-Do App](https://github.com/Shopify/cli-kit-example)
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
2
  require 'rake/testtask'
3
3
  require 'rubocop/rake_task'
4
4
  require 'bundler/gem_tasks'
5
+ require 'sorbet-runtime' unless ENV['BUNDLE_WITHOUT'] == 'typecheck'
5
6
 
6
7
  TEST_ROOT = File.expand_path('../test', __FILE__)
7
8
 
data/bin/onchange ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ # typed: ignore
3
+ # frozen_string_literal: true
4
+
5
+ require('open3')
6
+
7
+ extra_fswatch_args, cmd_args = if (rest_index = ARGV.index('--'))
8
+ [ARGV[0...rest_index], ARGV[rest_index + 1..-1]]
9
+ else
10
+ [[], ARGV]
11
+ end
12
+
13
+ if cmd_args.size == 1 && cmd_args =~ /[&;|]/
14
+ cmd_args = ['bash', '-c', cmd_args[0]]
15
+ end
16
+
17
+ system(*cmd_args)
18
+
19
+ fswatch_args = [
20
+ '-e', 'coverage',
21
+ '-e', '/\.git',
22
+ '--one-per-batch',
23
+ *extra_fswatch_args,
24
+ '.',
25
+ ]
26
+
27
+ Open3.popen3('fswatch', *fswatch_args) do |stdin, stdout, _stderr, _wait_thr|
28
+ stdin.close
29
+ stdout.each { |_| system(*cmd_args) }
30
+ end
data/bin/tapioca ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'tapioca' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path('../bundle', __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require 'rubygems'
27
+ require 'bundler/setup'
28
+
29
+ load Gem.bin_path('tapioca', 'tapioca')
data/bin/testunit CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler/setup'
5
+ require 'sorbet-runtime' unless ENV['BUNDLE_WITHOUT'] == 'typecheck'
5
6
 
6
7
  root = File.expand_path('../..', __FILE__)
7
8
  CLI_TEST_ROOT = root + '/test'
data/cli-kit.gemspec CHANGED
@@ -16,13 +16,13 @@ Gem::Specification.new do |spec|
16
16
  spec.license = 'MIT'
17
17
 
18
18
  spec.files = %x(git ls-files -z).split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
19
+ f.match(%r{^(sorbet|test|spec|features)/})
20
20
  end
21
21
  spec.bindir = 'exe'
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_runtime_dependency('cli-ui', '>= 1.1.4')
25
+ spec.add_runtime_dependency('cli-ui', '~> 2.0')
26
26
 
27
27
  spec.add_development_dependency('bundler', '~> 2.1')
28
28
  spec.add_development_dependency('minitest', '~> 5.0')
data/dev.yml CHANGED
@@ -1,7 +1,39 @@
1
1
  up:
2
- - ruby: 2.7.0
2
+ - homebrew:
3
+ - fswatch
4
+ - ruby: 3.0.4
3
5
  - bundler
4
6
 
5
7
  commands:
6
- test: bin/testunit
7
- style: "bundle exec rubocop -D"
8
+ console: irb -I./lib -rcli/kit
9
+ check:
10
+ run: 'srb && rake style test'
11
+ aliases: [ck]
12
+ test:
13
+ run: rake test
14
+ aliases: [t]
15
+ style:
16
+ run: rake style
17
+ aliases: [st]
18
+ typecheck:
19
+ run: srb
20
+ aliases: [tc]
21
+ watch:
22
+ aliases: [w]
23
+ subcommands:
24
+ style:
25
+ run: bin/onchange rake style
26
+ aliases: [st]
27
+ test:
28
+ run: bin/onchange rake test
29
+ aliases: [t]
30
+ typecheck:
31
+ run: bin/onchange srb
32
+ aliases: [tc]
33
+ check:
34
+ run: bin/onchange 'srb && rake style test'
35
+ aliases: [ck]
36
+ fastcheck:
37
+ Test: bundle exec rake test
38
+ Style: bundle exec rake style
39
+ Typecheck: bundle exec srb tc
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # typed: true
2
3
 
3
4
  require 'cli/ui'
4
5
  require 'cli/kit'
@@ -7,8 +8,9 @@ CLI::UI::StdoutRouter.enable
7
8
 
8
9
  include(CLI::Kit)
9
10
 
10
- registry = CommandRegistry.new(default: 'hello', contextual_resolver: nil)
11
+ registry = CommandRegistry.new(default: 'hello')
11
12
  registry.add(Class.new(BaseCommand) do
13
+ sig { params(_args: T::Array[String], _name: String).void }
12
14
  def call(_args, _name)
13
15
  puts 'hello, world!'
14
16
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # typed: true
2
3
 
3
4
  require 'cli/ui'
4
5
  require 'cli/kit'
@@ -6,62 +7,51 @@ require 'cli/kit'
6
7
  CLI::UI::StdoutRouter.enable
7
8
 
8
9
  module Example
9
- extend CLI::Kit::Autocall
10
-
11
10
  TOOL_NAME = 'example'
12
11
  ROOT = File.expand_path('../..', __FILE__)
13
12
  LOG_FILE = '/tmp/example.log'
14
13
 
15
14
  module Commands
16
- extend CLI::Kit::Autocall
15
+ Registry = CLI::Kit::CommandRegistry.new(default: 'hello')
17
16
 
18
- Registry = CLI::Kit::CommandRegistry.new(
19
- default: 'hello',
20
- contextual_resolver: nil
21
- )
17
+ class << self
18
+ sig { params(const: Symbol, cmd: String, path: String, lamda_const: T.proc.returns(Example::Command)).void }
19
+ def register(const, cmd, path, lamda_const)
20
+ autoload(const, path)
21
+ Registry.add(lamda_const, cmd)
22
+ end
22
23
 
23
- def self.register(const, cmd, path = nil, &block)
24
- path ? autoload(const, path) : autocall(const, &block)
25
- Registry.add(->() { const_get(const) }, cmd)
24
+ # register(:Hello, 'hello', 'a/b/hello', -> { Commands::Hello })
26
25
  end
27
26
 
28
- # register(:Hello, 'hello', 'a/b/hello')
29
-
30
- register(:Hello, 'hello') do
31
- Class.new(Example::Command) do
32
- def call(_args, _name)
33
- puts 'hello, world!'
34
- end
27
+ class Hello < Example::Command
28
+ sig { override.params(_args: T::Array[String], _name: String).void }
29
+ def call(_args, _name)
30
+ puts 'hello, world!'
35
31
  end
36
32
  end
37
33
  end
38
34
 
39
- autocall(:EntryPoint) do
40
- Module.new do
41
- def self.call(args)
35
+ module EntryPoint
36
+ class << self
37
+ sig { params(args: T::Array[String]).void }
38
+ def call(args)
42
39
  cmd, command_name, args = Example::Resolver.call(args)
43
40
  Example::Executor.call(cmd, command_name, args)
44
41
  end
45
42
  end
46
43
  end
47
44
 
48
- autocall(:Config) { CLI::Kit::Config.new(tool_name: TOOL_NAME) }
49
- autocall(:Command) { CLI::Kit::BaseCommand }
45
+ Config = CLI::Kit::Config.new(tool_name: TOOL_NAME)
46
+ Command = CLI::Kit::BaseCommand
50
47
 
51
- autocall(:Executor) { CLI::Kit::Executor.new(log_file: LOG_FILE) }
52
- autocall(:Resolver) do
53
- CLI::Kit::Resolver.new(
54
- tool_name: TOOL_NAME,
55
- command_registry: Example::Commands::Registry
56
- )
57
- end
48
+ Executor = CLI::Kit::Executor.new(log_file: LOG_FILE)
49
+ Resolver = CLI::Kit::Resolver.new(
50
+ tool_name: TOOL_NAME,
51
+ command_registry: Example::Commands::Registry,
52
+ )
58
53
 
59
- autocall(:ErrorHandler) do
60
- CLI::Kit::ErrorHandler.new(
61
- log_file: LOG_FILE,
62
- exception_reporter: nil
63
- )
64
- end
54
+ ErrorHandler = CLI::Kit::ErrorHandler.new(log_file: LOG_FILE)
65
55
  end
66
56
 
67
57
  if __FILE__ == $PROGRAM_NAME