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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e576da52278c6b0596840691bffbb12546b54bf2238145455a45333d6101f773
4
- data.tar.gz: 24243f1a2d66ad3b12fb2728b73b608038950d958ffc31dc0ab7951c3714533a
3
+ metadata.gz: af93e4820420cf1704d8cca5d63107f7bd83961100daa6db8e7f8548680cd10e
4
+ data.tar.gz: 4894fe464e5be800e850a9543978bb80f3353837ed8e52b63a8cd60f1167f951
5
5
  SHA512:
6
- metadata.gz: 8e7f4f5c4cc6620a2d98eca89e85ad57e6a9a0bd94ec704503ac0c9ba84f631984beb7c71c60e8b24ddbd2c4cf88b30cc298d3b05009f565450348a5b82c8d7f
7
- data.tar.gz: ac1c63ad107ca13fda07413a17054a17bb69ec6ae793f2a0abb97a5c2616c15fe7aaeaf7c3328b7ce035136dd72007df51fe7f5aab15e0c90199ede7ddd8d1e0
6
+ metadata.gz: 5d47834888929cf73123f2ecb5ca47676f530fbc51355f54b1dd4ef098f6f1afa5f0603d4e6c468326d114324ff467487085dced9cd24bf67ac87890ec4eadb8
7
+ data.tar.gz: f49180d83cf371a0e5f8870c95a5dcfdb44add7ab4938ba6cb24adb1de034a2526c9505b5eba1cd731d28e8b2089fbce748dec6c5191dcdc140a44713f6f6c79
@@ -8,3 +8,6 @@ updates:
8
8
  time: "07:00"
9
9
  timezone: America/Toronto
10
10
  open-pull-requests-limit: 99
11
+ groups:
12
+ dev-dependencies:
13
+ dependency-type: "development"
@@ -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: ['2.7', '3.0']
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
- TargetRubyVersion: 2.7
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', git: 'https://github.com/Shopify/cli-ui', ref: '0eefd57248f42ec163639884e77a071d82bfbda8'
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.1', require: false
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 (4.0.0)
12
- cli-ui (>= 1.1.4)
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
- builder (3.2.4)
12
+ benchmark (0.4.0)
13
+ builder (3.3.0)
20
14
  byebug (11.1.3)
21
- diff-lcs (1.5.0)
22
- docile (1.4.0)
23
- json (2.6.2)
24
- method_source (1.0.0)
25
- minitest (5.16.3)
26
- minitest-reporters (1.5.0)
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.0.2)
29
+ mocha (2.4.5)
32
30
  ruby2_keywords (>= 0.0.5)
33
31
  netrc (0.11.0)
34
- parallel (1.22.1)
35
- parser (3.1.2.1)
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.0.6)
39
- rbi (0.0.16)
40
- ast
41
- parser (>= 2.6.4.0)
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
- unparser
44
- regexp_parser (2.6.0)
45
- rexml (3.2.5)
46
- rubocop (1.39.0)
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.1.2.1)
52
+ parser (>= 3.3.0.2)
50
53
  rainbow (>= 2.2.2, < 4.0)
51
- regexp_parser (>= 1.8, < 3.0)
52
- rexml (>= 3.2.5, < 4.0)
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 (>= 1.4.0, < 3.0)
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)
64
- ruby-progressbar (1.11.0)
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.21.2)
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.12.3)
74
+ simplecov-html (0.13.1)
71
75
  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)
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.10.3)
93
- bundler (>= 1.17.3)
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.0.0, >= 0.0.16)
97
- sorbet-static-and-runtime (>= 0.5.9892)
98
- spoom (~> 1.1.0, >= 1.1.11)
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.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)
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.1)
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.2.24
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 = ['burke.libbey@shopify.com', 'aaron.olson@shopify.com', 'lisa.ugray@shopify.com']
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: 3.0.4
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'
@@ -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(Class.new(BaseCommand) do
13
- sig { params(_args: T::Array[String], _name: String).void }
14
- def call(_args, _name)
15
- puts 'hello, world!'
16
- end
17
- end, 'hello')
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)
@@ -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(/__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)
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
 
@@ -1,3 +1,3 @@
1
1
  up:
2
- - ruby: 2.5.0
2
+ - ruby: 3.2.2
3
3
  - bundler
@@ -1,4 +1,4 @@
1
1
  up:
2
- - ruby: 2.5.0
2
+ - ruby: 3.2.2
3
3
 
4
4
  build: bin/update-deps
@@ -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
- if opt.short
203
- opts = T.cast(
204
- parse.select { |node| node.is_a?(Parser::Node::ShortOption) },
205
- T::Array[Parser::Node::ShortOption],
206
- )
207
- matches = opts.select { |node| node.name == opt.short }
208
- if (last = matches.last)
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
 
@@ -149,7 +149,7 @@ module CLI
149
149
  o = opts.new
150
150
  o.define!(@defn)
151
151
 
152
- return nil if @defn.options.empty? && @defn.flags.empty?
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 nil unless @examples
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 nil unless klass
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 nil unless found
128
+ return unless found
129
129
 
130
130
  [@contextual_resolver.command_class(name), name]
131
131
  end
@@ -1,4 +1,4 @@
1
- # typed: strong
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Exception
@@ -56,8 +56,9 @@ module CLI
56
56
  end
57
57
 
58
58
  sig do
59
- type_parameters(:T).params(signal: String, handler: Method,
60
- block: T.proc.returns(T.type_parameter(:T))).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
@@ -183,7 +183,7 @@ module CLI
183
183
  sig { returns(Symbol) }
184
184
  def infer_name
185
185
  to_skip = 1
186
- Kernel.caller_locations&.each do |loc|
186
+ Kernel.caller_locations.each do |loc|
187
187
  next if loc.path =~ /sorbet-runtime/
188
188
 
189
189
  if to_skip > 0
@@ -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 nil if final_error.empty?
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 nil
240
+ return
239
241
  end
240
242
 
241
243
  expected_cmd[:run] = true
@@ -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
- break if ios.empty?
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, = IO.select(ios)
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 /mingw32/.match(RUBY_PLATFORM)
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] unless sudo
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
- space: T::Boolean).returns(String)
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)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CLI
4
4
  module Kit
5
- VERSION = '5.0.0'
5
+ VERSION = '5.0.1'
6
6
  end
7
7
  end
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.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
- autorequire:
10
+ - Don Kelly
11
+ autorequire:
11
12
  bindir: exe
12
13
  cert_chain: []
13
- date: 2022-11-18 00:00:00.000000000 Z
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.2.33
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: []