cli-kit 5.0.0 → 5.0.1
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 +4 -4
- data/.github/dependabot.yml +3 -0
- data/.github/workflows/ruby.yml +2 -20
- data/.rubocop.yml +17 -1
- data/.ruby-version +1 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +79 -82
- data/bin/tapioca +1 -2
- data/cli-kit.gemspec +7 -2
- data/dev.yml +4 -1
- data/examples/minimal/example.rb +9 -6
- data/gen/lib/gen/generator.rb +4 -4
- data/gen/lib/gen/help.rb +1 -1
- data/gen/template/dev-gems.yml +1 -1
- data/gen/template/dev-vendor.yml +1 -1
- data/lib/cli/kit/args/evaluation.rb +9 -20
- data/lib/cli/kit/command_help.rb +2 -2
- data/lib/cli/kit/command_registry.rb +4 -4
- data/lib/cli/kit/core_ext.rb +1 -1
- data/lib/cli/kit/executor.rb +3 -2
- data/lib/cli/kit/opts.rb +1 -1
- data/lib/cli/kit/parse_args.rb +55 -0
- data/lib/cli/kit/sorbet_runtime_stub.rb +0 -2
- data/lib/cli/kit/support/test_helper.rb +4 -2
- data/lib/cli/kit/system.rb +9 -6
- data/lib/cli/kit/util.rb +2 -2
- data/lib/cli/kit/version.rb +1 -1
- data/lib/cli/kit.rb +1 -0
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af93e4820420cf1704d8cca5d63107f7bd83961100daa6db8e7f8548680cd10e
|
4
|
+
data.tar.gz: 4894fe464e5be800e850a9543978bb80f3353837ed8e52b63a8cd60f1167f951
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d47834888929cf73123f2ecb5ca47676f530fbc51355f54b1dd4ef098f6f1afa5f0603d4e6c468326d114324ff467487085dced9cd24bf67ac87890ec4eadb8
|
7
|
+
data.tar.gz: f49180d83cf371a0e5f8870c95a5dcfdb44add7ab4938ba6cb24adb1de034a2526c9505b5eba1cd731d28e8b2089fbce748dec6c5191dcdc140a44713f6f6c79
|
data/.github/dependabot.yml
CHANGED
data/.github/workflows/ruby.yml
CHANGED
@@ -11,7 +11,6 @@ jobs:
|
|
11
11
|
- name: Set up Ruby
|
12
12
|
uses: ruby/setup-ruby@v1
|
13
13
|
with:
|
14
|
-
ruby-version: '2.7'
|
15
14
|
bundler-cache: true
|
16
15
|
- name: Check style
|
17
16
|
run: bundle exec rake style
|
@@ -23,7 +22,6 @@ jobs:
|
|
23
22
|
- name: Set up Ruby
|
24
23
|
uses: ruby/setup-ruby@v1
|
25
24
|
with:
|
26
|
-
ruby-version: '2.7'
|
27
25
|
bundler-cache: true
|
28
26
|
- name: Typecheck
|
29
27
|
run: bundle exec srb tc
|
@@ -31,26 +29,10 @@ jobs:
|
|
31
29
|
test:
|
32
30
|
strategy:
|
33
31
|
matrix:
|
34
|
-
os: [macos-latest, ubuntu-latest]
|
35
|
-
ruby-version: ['
|
32
|
+
os: [macos-latest, ubuntu-latest, windows-latest]
|
33
|
+
ruby-version: ['3.1', '3.2', '3.3']
|
36
34
|
|
37
35
|
runs-on: ${{ matrix.os }}
|
38
|
-
steps:
|
39
|
-
- uses: actions/checkout@v2
|
40
|
-
- name: Set up Ruby
|
41
|
-
uses: ruby/setup-ruby@v1
|
42
|
-
with:
|
43
|
-
ruby-version: ${{ matrix.ruby-version }}
|
44
|
-
bundler-cache: true
|
45
|
-
- name: Run tests
|
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
36
|
env:
|
55
37
|
BUNDLE_WITHOUT: typecheck
|
56
38
|
steps:
|
data/.rubocop.yml
CHANGED
@@ -11,7 +11,7 @@ AllCops:
|
|
11
11
|
Exclude:
|
12
12
|
- gen/template/**/*
|
13
13
|
- vendor/**/*
|
14
|
-
|
14
|
+
- lib/cli/kit/levenshtein.rb # Vendored
|
15
15
|
NewCops: disable
|
16
16
|
|
17
17
|
Style/ClassAndModuleChildren:
|
@@ -51,3 +51,19 @@ Style/GlobalStdStream:
|
|
51
51
|
# Sometimes (often) explicit is good
|
52
52
|
Style/EmptyElse:
|
53
53
|
Enabled: false
|
54
|
+
|
55
|
+
# We make frequent use Open3 methods to run other programs. When passing long command lines, it's useful and informative
|
56
|
+
# to place the argument to an option on the same line as its option, eg:
|
57
|
+
# Open3.capture3(
|
58
|
+
# 'curl',
|
59
|
+
# '-H', 'X-Header: value',
|
60
|
+
# '-o', 'file.txt',
|
61
|
+
# '-L',
|
62
|
+
# 'https://example.com/',
|
63
|
+
# )
|
64
|
+
Layout/MultilineMethodArgumentLineBreaks:
|
65
|
+
Enabled: false
|
66
|
+
Layout/MultilineArrayLineBreaks:
|
67
|
+
Enabled: false
|
68
|
+
Layout/MultilineHashKeyLineBreaks:
|
69
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.3.0
|
data/Gemfile
CHANGED
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
group :development, :test do
|
7
|
-
gem 'cli-ui'
|
7
|
+
gem 'cli-ui'
|
8
8
|
gem 'rubocop'
|
9
9
|
gem 'rubocop-rake'
|
10
10
|
gem 'rubocop-shopify'
|
@@ -20,7 +20,7 @@ group :typecheck do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
group :test do
|
23
|
-
gem 'mocha', '~> 2.0
|
23
|
+
gem 'mocha', '~> 2.4.0', require: false
|
24
24
|
gem 'minitest', '>= 5.0.0', require: false
|
25
25
|
gem 'minitest-reporters', require: false
|
26
26
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,130 +1,127 @@
|
|
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
|
-
|
8
1
|
PATH
|
9
2
|
remote: .
|
10
3
|
specs:
|
11
|
-
cli-kit (
|
12
|
-
cli-ui (
|
4
|
+
cli-kit (5.0.1)
|
5
|
+
cli-ui (~> 2.0)
|
13
6
|
|
14
7
|
GEM
|
15
8
|
remote: https://rubygems.org/
|
16
9
|
specs:
|
17
10
|
ansi (1.5.0)
|
18
11
|
ast (2.4.2)
|
19
|
-
|
12
|
+
benchmark (0.4.0)
|
13
|
+
builder (3.3.0)
|
20
14
|
byebug (11.1.3)
|
21
|
-
|
22
|
-
docile (1.4.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
cli-ui (2.3.0)
|
16
|
+
docile (1.4.1)
|
17
|
+
erubi (1.13.1)
|
18
|
+
json (2.10.1)
|
19
|
+
language_server-protocol (3.17.0.4)
|
20
|
+
lint_roller (1.1.0)
|
21
|
+
logger (1.6.6)
|
22
|
+
method_source (1.1.0)
|
23
|
+
minitest (5.25.4)
|
24
|
+
minitest-reporters (1.7.1)
|
27
25
|
ansi
|
28
26
|
builder
|
29
27
|
minitest (>= 5.0)
|
30
28
|
ruby-progressbar
|
31
|
-
mocha (2.
|
29
|
+
mocha (2.4.5)
|
32
30
|
ruby2_keywords (>= 0.0.5)
|
33
31
|
netrc (0.11.0)
|
34
|
-
parallel (1.
|
35
|
-
parser (3.
|
32
|
+
parallel (1.26.3)
|
33
|
+
parser (3.3.7.1)
|
36
34
|
ast (~> 2.4.1)
|
35
|
+
racc
|
36
|
+
prism (1.3.0)
|
37
|
+
racc (1.8.1)
|
37
38
|
rainbow (3.1.1)
|
38
|
-
rake (13.
|
39
|
-
rbi (0.0
|
40
|
-
|
41
|
-
|
39
|
+
rake (13.2.1)
|
40
|
+
rbi (0.3.0)
|
41
|
+
prism (~> 1.0)
|
42
|
+
rbs (>= 3.4.4)
|
42
43
|
sorbet-runtime (>= 0.5.9204)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
rubocop (1.
|
44
|
+
rbs (3.8.1)
|
45
|
+
logger
|
46
|
+
regexp_parser (2.10.0)
|
47
|
+
rubocop (1.73.2)
|
47
48
|
json (~> 2.3)
|
49
|
+
language_server-protocol (~> 3.17.0.2)
|
50
|
+
lint_roller (~> 1.1.0)
|
48
51
|
parallel (~> 1.10)
|
49
|
-
parser (>= 3.
|
52
|
+
parser (>= 3.3.0.2)
|
50
53
|
rainbow (>= 2.2.2, < 4.0)
|
51
|
-
regexp_parser (>=
|
52
|
-
|
53
|
-
rubocop-ast (>= 1.23.0, < 2.0)
|
54
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
55
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
54
56
|
ruby-progressbar (~> 1.7)
|
55
|
-
unicode-display_width (>=
|
56
|
-
rubocop-ast (1.
|
57
|
-
parser (>= 3.
|
58
|
-
rubocop-rake (0.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
58
|
+
rubocop-ast (1.38.1)
|
59
|
+
parser (>= 3.3.1.0)
|
60
|
+
rubocop-rake (0.7.1)
|
61
|
+
lint_roller (~> 1.1)
|
62
|
+
rubocop (>= 1.72.1)
|
63
|
+
rubocop-shopify (2.16.0)
|
64
|
+
rubocop (~> 1.62)
|
65
|
+
rubocop-sorbet (0.9.0)
|
66
|
+
lint_roller (~> 1.1)
|
67
|
+
rubocop (>= 1)
|
68
|
+
ruby-progressbar (1.13.0)
|
65
69
|
ruby2_keywords (0.0.5)
|
66
|
-
simplecov (0.
|
70
|
+
simplecov (0.22.0)
|
67
71
|
docile (~> 1.1)
|
68
72
|
simplecov-html (~> 0.11)
|
69
73
|
simplecov_json_formatter (~> 0.1)
|
70
|
-
simplecov-html (0.
|
74
|
+
simplecov-html (0.13.1)
|
71
75
|
simplecov_json_formatter (0.1.4)
|
72
|
-
sorbet (0.5.
|
73
|
-
sorbet-static (= 0.5.
|
74
|
-
sorbet-runtime (0.5.
|
75
|
-
sorbet-static (0.5.
|
76
|
-
sorbet-static (0.5.
|
77
|
-
sorbet-static (0.5.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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)
|
76
|
+
sorbet (0.5.11915)
|
77
|
+
sorbet-static (= 0.5.11915)
|
78
|
+
sorbet-runtime (0.5.11915)
|
79
|
+
sorbet-static (0.5.11915-universal-darwin)
|
80
|
+
sorbet-static (0.5.11915-x86_64-linux)
|
81
|
+
sorbet-static-and-runtime (0.5.11915)
|
82
|
+
sorbet (= 0.5.11915)
|
83
|
+
sorbet-runtime (= 0.5.11915)
|
84
|
+
spoom (1.5.4)
|
85
|
+
erubi (>= 1.10.0)
|
86
|
+
prism (>= 0.28.0)
|
87
|
+
rbi (>= 0.2.3)
|
88
|
+
sorbet-static-and-runtime (>= 0.5.10187)
|
91
89
|
thor (>= 0.19.2)
|
92
|
-
tapioca (0.
|
93
|
-
|
90
|
+
tapioca (0.16.11)
|
91
|
+
benchmark
|
92
|
+
bundler (>= 2.2.25)
|
94
93
|
netrc (>= 0.11.0)
|
95
94
|
parallel (>= 1.21.0)
|
96
|
-
rbi (~> 0.
|
97
|
-
sorbet-static-and-runtime (>= 0.5.
|
98
|
-
spoom (
|
95
|
+
rbi (~> 0.2)
|
96
|
+
sorbet-static-and-runtime (>= 0.5.11087)
|
97
|
+
spoom (>= 1.2.0)
|
99
98
|
thor (>= 1.2.0)
|
100
99
|
yard-sorbet
|
101
|
-
thor (1.2
|
102
|
-
unicode-display_width (
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
yard-sorbet (0.7.0)
|
110
|
-
sorbet-runtime (>= 0.5)
|
111
|
-
yard (>= 0.9)
|
100
|
+
thor (1.3.2)
|
101
|
+
unicode-display_width (3.1.4)
|
102
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
103
|
+
unicode-emoji (4.0.4)
|
104
|
+
yard (0.9.37)
|
105
|
+
yard-sorbet (0.9.0)
|
106
|
+
sorbet-runtime
|
107
|
+
yard
|
112
108
|
|
113
109
|
PLATFORMS
|
114
110
|
arm64-darwin-21
|
115
|
-
ruby
|
116
111
|
universal-darwin
|
112
|
+
x64-mingw-ucrt
|
113
|
+
x64-mingw32
|
117
114
|
x86_64-linux
|
118
115
|
|
119
116
|
DEPENDENCIES
|
120
117
|
bundler (~> 2.1)
|
121
118
|
byebug
|
122
119
|
cli-kit!
|
123
|
-
cli-ui
|
120
|
+
cli-ui
|
124
121
|
method_source
|
125
122
|
minitest (>= 5.0.0)
|
126
123
|
minitest-reporters
|
127
|
-
mocha (~> 2.0
|
124
|
+
mocha (~> 2.4.0)
|
128
125
|
rake (~> 13.0)
|
129
126
|
rubocop
|
130
127
|
rubocop-rake
|
@@ -135,4 +132,4 @@ DEPENDENCIES
|
|
135
132
|
tapioca
|
136
133
|
|
137
134
|
BUNDLED WITH
|
138
|
-
2.
|
135
|
+
2.4.9
|
data/bin/tapioca
CHANGED
@@ -9,8 +9,7 @@
|
|
9
9
|
#
|
10
10
|
|
11
11
|
require 'pathname'
|
12
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
13
|
-
Pathname.new(__FILE__).realpath)
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
14
13
|
|
15
14
|
bundle_binstub = File.expand_path('../bundle', __FILE__)
|
16
15
|
|
data/cli-kit.gemspec
CHANGED
@@ -7,8 +7,11 @@ require 'cli/kit/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'cli-kit'
|
9
9
|
spec.version = CLI::Kit::VERSION
|
10
|
-
spec.authors = ['Burke Libbey', 'Aaron Olson', 'Lisa Ugray']
|
11
|
-
spec.email = [
|
10
|
+
spec.authors = ['Burke Libbey', 'Aaron Olson', 'Lisa Ugray', 'Don Kelly']
|
11
|
+
spec.email = [
|
12
|
+
'burke.libbey@shopify.com', 'aaron.olson@shopify.com', 'lisa.ugray@shopify.com',
|
13
|
+
'don.kelly@shopify.com',
|
14
|
+
]
|
12
15
|
|
13
16
|
spec.summary = 'Terminal UI framework extensions'
|
14
17
|
spec.description = 'Terminal UI framework extensions'
|
@@ -24,6 +27,8 @@ Gem::Specification.new do |spec|
|
|
24
27
|
|
25
28
|
spec.add_runtime_dependency('cli-ui', '~> 2.0')
|
26
29
|
|
30
|
+
spec.required_ruby_version = '>= 3.0'
|
31
|
+
|
27
32
|
spec.add_development_dependency('bundler', '~> 2.1')
|
28
33
|
spec.add_development_dependency('minitest', '~> 5.0')
|
29
34
|
spec.add_development_dependency('rake', '~> 13.0')
|
data/dev.yml
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
up:
|
2
2
|
- homebrew:
|
3
3
|
- fswatch
|
4
|
-
- ruby
|
4
|
+
- ruby
|
5
5
|
- bundler
|
6
6
|
|
7
7
|
commands:
|
8
|
+
add-back-ruby:
|
9
|
+
run: bundle lock --add-platform ruby && git commit -a -m 'Add back ruby platform' && git push
|
10
|
+
aliases: [abr]
|
8
11
|
console: irb -I./lib -rcli/kit
|
9
12
|
check:
|
10
13
|
run: 'srb && rake style test'
|
data/examples/minimal/example.rb
CHANGED
@@ -9,12 +9,15 @@ CLI::UI::StdoutRouter.enable
|
|
9
9
|
include(CLI::Kit)
|
10
10
|
|
11
11
|
registry = CommandRegistry.new(default: 'hello')
|
12
|
-
registry.add(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
12
|
+
registry.add(
|
13
|
+
Class.new(BaseCommand) do
|
14
|
+
sig { params(_args: T::Array[String], _name: String).void }
|
15
|
+
def call(_args, _name)
|
16
|
+
puts 'hello, world!'
|
17
|
+
end
|
18
|
+
end,
|
19
|
+
'hello',
|
20
|
+
)
|
18
21
|
|
19
22
|
executor = Executor.new(log_file: '/tmp/example.log')
|
20
23
|
error_handler = ErrorHandler.new(log_file: '/tmp/example.log', exception_reporter: nil)
|
data/gen/lib/gen/generator.rb
CHANGED
@@ -149,10 +149,10 @@ module Gen
|
|
149
149
|
sig { params(s: String).returns(String) }
|
150
150
|
def apply_template_variables(s)
|
151
151
|
s
|
152
|
-
.gsub(
|
153
|
-
.gsub(
|
154
|
-
.gsub(
|
155
|
-
.gsub(
|
152
|
+
.gsub('__app__', @project_name)
|
153
|
+
.gsub('__App__', @title_case_project_name)
|
154
|
+
.gsub('__cli-kit-version__', cli_kit_version)
|
155
|
+
.gsub('__cli-ui-version__', cli_ui_version)
|
156
156
|
end
|
157
157
|
|
158
158
|
sig { returns(String) }
|
data/gen/lib/gen/help.rb
CHANGED
@@ -40,7 +40,7 @@ module Gen
|
|
40
40
|
max_len = cmds.map(&:first).map(&:length).max
|
41
41
|
|
42
42
|
cmds.each do |name, desc|
|
43
|
-
to.write(CLI::UI.fmt(" {{command:#{name.ljust(max_len)}}} #{desc}\n"))
|
43
|
+
to.write(CLI::UI.fmt(" {{command:#{name.ljust(T.must(max_len))}}} #{desc}\n"))
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
data/gen/template/dev-gems.yml
CHANGED
data/gen/template/dev-vendor.yml
CHANGED
@@ -151,7 +151,7 @@ module CLI
|
|
151
151
|
next unless opt.required?
|
152
152
|
|
153
153
|
node = @parse.detect do |node|
|
154
|
-
node.is_a?(Parser::Node::Option) && node.name == opt.name
|
154
|
+
node.is_a?(Parser::Node::Option) && node.name.to_sym == opt.name
|
155
155
|
end
|
156
156
|
if !node || T.cast(node, Parser::Node::Option).value.nil?
|
157
157
|
raise(MissingRequiredOption, opt.as_written_by_user)
|
@@ -199,26 +199,15 @@ module CLI
|
|
199
199
|
|
200
200
|
sig { params(opt: Definition::Option).returns(T.any(NilClass, String, T::Array[String])) }
|
201
201
|
def lookup_option(opt)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
return(opt.multi? ? matches.map(&:value) : last.value)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
if opt.long
|
213
|
-
opts = T.cast(
|
214
|
-
parse.select { |node| node.is_a?(Parser::Node::LongOption) },
|
215
|
-
T::Array[Parser::Node::LongOption],
|
216
|
-
)
|
217
|
-
matches = opts.select { |node| node.name == opt.long }
|
218
|
-
if (last = matches.last)
|
219
|
-
return(opt.multi? ? matches.map(&:value) : last.value)
|
220
|
-
end
|
202
|
+
opts = T.cast(
|
203
|
+
parse.select { |node| node.is_a?(Parser::Node::ShortOption) || node.is_a?(Parser::Node::LongOption) },
|
204
|
+
T::Array[T.any(Parser::Node::ShortOption, Parser::Node::LongOption)],
|
205
|
+
)
|
206
|
+
matches = opts.select { |node| (opt.short && node.name == opt.short) || (opt.long && node.name == opt.long) }
|
207
|
+
if (last = matches.last)
|
208
|
+
return(opt.multi? ? matches.map(&:value) : last.value)
|
221
209
|
end
|
210
|
+
|
222
211
|
opt.default
|
223
212
|
end
|
224
213
|
|
data/lib/cli/kit/command_help.rb
CHANGED
@@ -149,7 +149,7 @@ module CLI
|
|
149
149
|
o = opts.new
|
150
150
|
o.define!(@defn)
|
151
151
|
|
152
|
-
return
|
152
|
+
return if @defn.options.empty? && @defn.flags.empty?
|
153
153
|
|
154
154
|
merged = T.let(@defn.options, T::Array[T.any(Args::Definition::Option, Args::Definition::Flag)])
|
155
155
|
merged += @defn.flags
|
@@ -238,7 +238,7 @@ module CLI
|
|
238
238
|
|
239
239
|
sig { returns(T.nilable(String)) }
|
240
240
|
def build_examples
|
241
|
-
return
|
241
|
+
return unless @examples
|
242
242
|
|
243
243
|
cmd_prefix = " {{command:#{CommandHelp._tool_name} #{_command_name}}}"
|
244
244
|
"{{bold:Examples:}}\n" + @examples.map do |command, explanation|
|
@@ -107,15 +107,15 @@ module CLI
|
|
107
107
|
sig { params(name: String).returns([T.nilable(T.class_of(CLI::Kit::BaseCommand)), String]) }
|
108
108
|
def resolve_command(name)
|
109
109
|
name = resolve_alias(name)
|
110
|
-
resolve_global_command(name) ||
|
111
|
-
resolve_contextual_command(name) ||
|
110
|
+
resolve_global_command(name) ||
|
111
|
+
resolve_contextual_command(name) ||
|
112
112
|
[nil, name]
|
113
113
|
end
|
114
114
|
|
115
115
|
sig { params(name: String).returns(T.nilable([T.class_of(CLI::Kit::BaseCommand), String])) }
|
116
116
|
def resolve_global_command(name)
|
117
117
|
klass = resolve_class(commands.fetch(name, nil))
|
118
|
-
return
|
118
|
+
return unless klass
|
119
119
|
|
120
120
|
[klass, name]
|
121
121
|
rescue NameError
|
@@ -125,7 +125,7 @@ module CLI
|
|
125
125
|
sig { params(name: String).returns(T.nilable([T.class_of(CLI::Kit::BaseCommand), String])) }
|
126
126
|
def resolve_contextual_command(name)
|
127
127
|
found = @contextual_resolver.command_names.include?(name)
|
128
|
-
return
|
128
|
+
return unless found
|
129
129
|
|
130
130
|
[@contextual_resolver.command_class(name), name]
|
131
131
|
end
|
data/lib/cli/kit/core_ext.rb
CHANGED
data/lib/cli/kit/executor.rb
CHANGED
@@ -56,8 +56,9 @@ module CLI
|
|
56
56
|
end
|
57
57
|
|
58
58
|
sig do
|
59
|
-
type_parameters(:T)
|
60
|
-
block: T.proc.returns(T.type_parameter(:T)))
|
59
|
+
type_parameters(:T)
|
60
|
+
.params(signal: String, handler: Method, block: T.proc.returns(T.type_parameter(:T)))
|
61
|
+
.returns(T.type_parameter(:T))
|
61
62
|
end
|
62
63
|
def twrap(signal, handler, &block)
|
63
64
|
return yield unless Signal.list.key?(signal)
|
data/lib/cli/kit/opts.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module CLI
|
4
|
+
module Kit
|
5
|
+
module ParseArgs
|
6
|
+
# because sorbet type-checking takes the pedantic route that module doesn't include Kernel, therefore
|
7
|
+
# this is necessary (even tho it's ~probably fine~)
|
8
|
+
include Kernel
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
# T.untyped is used in two places. The interpretation of dynamic values from the provided `opts`
|
12
|
+
# and the resulting args[:opts] is pretty broad. There seems to be minimal value in expressing a
|
13
|
+
# tighter subset of T.untyped.
|
14
|
+
|
15
|
+
sig { params(args: String, opts_defn: T::Hash[Symbol, T::Array[T.untyped]]).returns(T::Hash[Symbol, T.untyped]) }
|
16
|
+
def parse_args(args, opts_defn)
|
17
|
+
start_opts, parser_config = opts_defn.reduce([{}, []]) do |(ini, pcfg), (n, cfg)|
|
18
|
+
(vals, desc, short, klass) = cfg
|
19
|
+
(init_val, def_val) = Array(vals)
|
20
|
+
|
21
|
+
[
|
22
|
+
init_val.nil? ? ini : ini.merge(n => init_val),
|
23
|
+
pcfg + [[n, short, desc, def_val, klass]],
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
require('optparse')
|
28
|
+
|
29
|
+
acc_opts = {}
|
30
|
+
prsr = OptionParser.new do |opt_p|
|
31
|
+
parser_config.each do |(n, short, desc, def_val, klass)|
|
32
|
+
(_, mark) = short.split(' ')
|
33
|
+
long = "--#{n.to_s.tr("_", "-")}" + (mark.nil? ? '' : " #{mark}")
|
34
|
+
opt_args = klass.nil? ? [short, long, desc] : [short, long, klass, desc]
|
35
|
+
|
36
|
+
T.unsafe(opt_p).on(*opt_args) do |v|
|
37
|
+
acc_opts[n] = if acc_opts.key?(n)
|
38
|
+
Array(acc_opts[n]) + Array(v || def_val)
|
39
|
+
else
|
40
|
+
v || def_val
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
arg_v = args.strip.split(/\s+/).map(&:strip)
|
47
|
+
sub = prsr.parse(arg_v)
|
48
|
+
|
49
|
+
{ opts: start_opts.merge(acc_opts) }.tap do |a|
|
50
|
+
a[:sub] = sub if sub
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -94,10 +94,8 @@ module T
|
|
94
94
|
def log_info_handler=(value); end
|
95
95
|
def scalar_types; end
|
96
96
|
def scalar_types=(values); end
|
97
|
-
# rubocop:disable Naming/InclusiveLanguage
|
98
97
|
def sealed_violation_whitelist; end
|
99
98
|
def sealed_violation_whitelist=(sealed_violation_whitelist); end
|
100
|
-
# rubocop:enable Naming/InclusiveLanguage
|
101
99
|
def sig_builder_error_handler=(value); end
|
102
100
|
def sig_validation_error_handler(error, opts); end
|
103
101
|
def sig_validation_error_handler=(value); end
|
@@ -21,6 +21,8 @@ module CLI
|
|
21
21
|
def teardown
|
22
22
|
super
|
23
23
|
assert_all_commands_run
|
24
|
+
rescue Errno::EACCES
|
25
|
+
# this sometimes happens on windows builds - let's ignore it
|
24
26
|
end
|
25
27
|
|
26
28
|
module FakeConfig
|
@@ -223,7 +225,7 @@ module CLI
|
|
223
225
|
EOF
|
224
226
|
end
|
225
227
|
|
226
|
-
return
|
228
|
+
return if final_error.empty?
|
227
229
|
|
228
230
|
"\n" + final_error.join("\n") # Initial new line for formatting reasons
|
229
231
|
end
|
@@ -235,7 +237,7 @@ module CLI
|
|
235
237
|
|
236
238
|
if expected_cmd.nil?
|
237
239
|
@delegate_open3[a.join(' ')] = { unexpected: true }
|
238
|
-
return
|
240
|
+
return
|
239
241
|
end
|
240
242
|
|
241
243
|
expected_cmd[:run] = true
|
data/lib/cli/kit/system.rb
CHANGED
@@ -237,11 +237,15 @@ module CLI
|
|
237
237
|
|
238
238
|
previous_trailing = Hash.new('')
|
239
239
|
loop do
|
240
|
+
break if Process.wait(pid, Process::WNOHANG)
|
241
|
+
|
240
242
|
ios = [err_r, out_r].reject(&:closed?)
|
241
|
-
|
243
|
+
next if ios.empty?
|
244
|
+
|
245
|
+
readers, = IO.select(ios, [], [], 1)
|
246
|
+
next if readers.nil? # If IO.select times out we iterate again so we can check if the process has exited
|
242
247
|
|
243
|
-
readers
|
244
|
-
(readers || []).each do |io|
|
248
|
+
readers.each do |io|
|
245
249
|
data, trailing = split_partial_characters(io.readpartial(4096))
|
246
250
|
handlers[io].call(previous_trailing[io] + data)
|
247
251
|
previous_trailing[io] = trailing
|
@@ -250,7 +254,6 @@ module CLI
|
|
250
254
|
end
|
251
255
|
end
|
252
256
|
|
253
|
-
Process.wait(pid)
|
254
257
|
$CHILD_STATUS
|
255
258
|
end
|
256
259
|
|
@@ -297,7 +300,7 @@ module CLI
|
|
297
300
|
def os
|
298
301
|
return :mac if /darwin/.match(RUBY_PLATFORM)
|
299
302
|
return :linux if /linux/.match(RUBY_PLATFORM)
|
300
|
-
return :windows if /
|
303
|
+
return :windows if /mingw/.match(RUBY_PLATFORM)
|
301
304
|
|
302
305
|
raise "Could not determine OS from platform #{RUBY_PLATFORM}"
|
303
306
|
end
|
@@ -322,7 +325,7 @@ module CLI
|
|
322
325
|
.returns([String, T::Array[String]])
|
323
326
|
end
|
324
327
|
def apply_sudo(cmd, args, sudo)
|
325
|
-
return [cmd, args]
|
328
|
+
return [cmd, args] if !sudo || Process.uid.zero?
|
326
329
|
|
327
330
|
sudo_reason(sudo) if sudo.is_a?(String)
|
328
331
|
['sudo', args.unshift('-E', '-S', '-p', SUDO_PROMPT, '--', cmd)]
|
data/lib/cli/kit/util.rb
CHANGED
@@ -18,8 +18,8 @@ module CLI
|
|
18
18
|
# Converts a number to a human readable format on the SI scale
|
19
19
|
#
|
20
20
|
sig do
|
21
|
-
params(number: Numeric, unit: String, factor: Integer, precision: Integer,
|
22
|
-
|
21
|
+
params(number: Numeric, unit: String, factor: Integer, precision: Integer, space: T::Boolean)
|
22
|
+
.returns(String)
|
23
23
|
end
|
24
24
|
def to_si_scale(number, unit = '', factor: 1000, precision: 2, space: false)
|
25
25
|
raise ArgumentError, 'factor should only be 1000 or 1024' unless [1000, 1024].include?(factor)
|
data/lib/cli/kit/version.rb
CHANGED
data/lib/cli/kit.rb
CHANGED
@@ -23,6 +23,7 @@ module CLI
|
|
23
23
|
autoload :Levenshtein, 'cli/kit/levenshtein'
|
24
24
|
autoload :Logger, 'cli/kit/logger'
|
25
25
|
autoload :Opts, 'cli/kit/opts'
|
26
|
+
autoload :ParseArgs, 'cli/kit/parse_args'
|
26
27
|
autoload :Resolver, 'cli/kit/resolver'
|
27
28
|
autoload :Support, 'cli/kit/support'
|
28
29
|
autoload :System, 'cli/kit/system'
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cli-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burke Libbey
|
8
8
|
- Aaron Olson
|
9
9
|
- Lisa Ugray
|
10
|
-
|
10
|
+
- Don Kelly
|
11
|
+
autorequire:
|
11
12
|
bindir: exe
|
12
13
|
cert_chain: []
|
13
|
-
date:
|
14
|
+
date: 2025-03-12 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: cli-ui
|
@@ -73,6 +74,7 @@ email:
|
|
73
74
|
- burke.libbey@shopify.com
|
74
75
|
- aaron.olson@shopify.com
|
75
76
|
- lisa.ugray@shopify.com
|
77
|
+
- don.kelly@shopify.com
|
76
78
|
executables:
|
77
79
|
- cli-kit
|
78
80
|
extensions: []
|
@@ -85,6 +87,7 @@ files:
|
|
85
87
|
- ".gitignore"
|
86
88
|
- ".rubocop.sorbet.yml"
|
87
89
|
- ".rubocop.yml"
|
90
|
+
- ".ruby-version"
|
88
91
|
- Gemfile
|
89
92
|
- Gemfile.lock
|
90
93
|
- LICENSE.txt
|
@@ -144,6 +147,7 @@ files:
|
|
144
147
|
- lib/cli/kit/levenshtein.rb
|
145
148
|
- lib/cli/kit/logger.rb
|
146
149
|
- lib/cli/kit/opts.rb
|
150
|
+
- lib/cli/kit/parse_args.rb
|
147
151
|
- lib/cli/kit/resolver.rb
|
148
152
|
- lib/cli/kit/sorbet_runtime_stub.rb
|
149
153
|
- lib/cli/kit/support.rb
|
@@ -155,7 +159,7 @@ homepage: https://github.com/shopify/cli-kit
|
|
155
159
|
licenses:
|
156
160
|
- MIT
|
157
161
|
metadata: {}
|
158
|
-
post_install_message:
|
162
|
+
post_install_message:
|
159
163
|
rdoc_options: []
|
160
164
|
require_paths:
|
161
165
|
- lib
|
@@ -163,15 +167,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
167
|
requirements:
|
164
168
|
- - ">="
|
165
169
|
- !ruby/object:Gem::Version
|
166
|
-
version: '0'
|
170
|
+
version: '3.0'
|
167
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
172
|
requirements:
|
169
173
|
- - ">="
|
170
174
|
- !ruby/object:Gem::Version
|
171
175
|
version: '0'
|
172
176
|
requirements: []
|
173
|
-
rubygems_version: 3.
|
174
|
-
signing_key:
|
177
|
+
rubygems_version: 3.0.3.1
|
178
|
+
signing_key:
|
175
179
|
specification_version: 4
|
176
180
|
summary: Terminal UI framework extensions
|
177
181
|
test_files: []
|