squared 0.4.36 → 0.5.0

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.
@@ -4,16 +4,17 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Ruby < Git
7
- GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb gems.rb Isolate].freeze
7
+ GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
8
8
  DIR_RUBY = (GEMFILE + Rake::Application::DEFAULT_RAKEFILES + ['README.rdoc']).freeze
9
9
  OPT_RUBY = {
10
- ruby: %w[0=im? a c C=pm e=q E=bm F=qm i=bm? I=pm l n p r=bm s S w W=bm? x=pm? d|debug jit rjit verbose
11
- y|yydebug backtrace-limit=i crash-report=q disable=q dump=q enable=q encoding=b external-encoding=b
10
+ ruby: %w[0=im? a c e=q E=bm F=qm i=bm? I=pm l n p r=bm s S w W=bm? x=pm? d|debug jit rjit v|verbose y|yydebug
11
+ backtrace-limit=i crash-report=q disable=q dump=q enable=q encoding=b external-encoding=b
12
12
  internal-encoding=b parser=b].freeze,
13
- rake: %w[A|all B|build-all comments n|dry-run m|multitask P|prereqs q|quiet X|no-deprecation-warnings
14
- N|no-search G|no-system nosearch nosystem rules s|silent g|system v|verbose backtrace=b?
15
- D|describe=q? e|execute=q E|execute-continue=q p|execute-print=q job-stats=b? j|jobs=i? I|libdir=p
16
- R|rakelib=p rakelibdir=p r|require=b suppress-backtrace=q T|tasks=q? t|trace=b? W|where=q?].freeze,
13
+ rake: %w[A|all B|build-all comments n|dry-run p|execute-print=q m|multitask P|prereqs q|quiet
14
+ X|no-deprecation-warnings N|no-search G|no-system nosearch nosystem rules s|silent g|system
15
+ v|verbose backtrace=b? D|describe=q? e|execute=q E|execute-continue=q job-stats=b? j|jobs=i?
16
+ I|libdir=p R|rakelib=p rakelibdir=p r|require=b suppress-backtrace=q T|tasks=q? t|trace=b?
17
+ W|where=q?].freeze,
17
18
  irb: %w[d f U w E=b I=p r=b W=im? autocomplete colorize echo echo-on-assignment extra-doc-dir inf-ruby-mode
18
19
  inspect multiline no-pager noautocomplete nocolorize noecho noecho-on-assignment noinspect
19
20
  nomultiline noprompt noscript nosingleline noverbose regexp-completor sample-book-mode script
@@ -21,41 +22,38 @@ module Squared
21
22
  back-trace-limit=i context-mode=i prompt=b prompt-mode=b].freeze
22
23
  }.freeze
23
24
  OPT_BUNDLE = {
24
- common: %w[no-color V|verbose r|retry=i].freeze,
25
+ common: %w[no-color V|verbose retry=i].freeze,
25
26
  install: %w[frozen no-cache no-prune system binstubs=p? path=p standalone=q? target-rbconfig=p trust-policy=b
26
27
  with=q without=q].freeze,
27
- install_base: %w[force full-index local quiet redownload gemfile=p j|jobs=i].freeze,
28
- update: %w[all conservative local major minor patch pre ruby strict bundler=b? g|group=q source=b].freeze,
29
- outdated: %w[filter-major filter-minor filter-patch filter-strict groups local parseable porcelain pre
30
- only-explicit strict update-strict group=q source=b].freeze,
28
+ install_base: %w[full-index quiet retry gemfile=p j|jobs=i].freeze,
29
+ update: %w[conservative local pre redownload ruby strict bundler=b? g|group=q source=b].freeze,
30
+ outdated: %w[filter-major filter-minor filter-patch groups local parseable pre only-explicit strict
31
+ update-strict g|group=q source=b].freeze,
31
32
  exec: %w[gemfile=p].freeze,
32
- cache: %w[all all-platforms frozen no-all no-install no-prune quiet cache-path=p gemfile=p path=p].freeze,
33
- check: %w[dry-run gemfile=p path=p].freeze
33
+ cache: %w[all-platforms frozen no-install no-prune quiet cache-path=p gemfile=p path=p].freeze,
34
+ check: %w[dry-run gemfile=p].freeze
34
35
  }.freeze
35
36
  OPT_GEM = {
36
37
  common: %w[backtrace debug q|quiet no-verbose norc silent V|verbose config-file=p].freeze,
37
- install: %w[version=q].freeze,
38
- install_base: %w[E f w b|both clear-sources conservative default development development-all explain
39
- ignore-dependencies l|local N|no-document r|remote vendor n|bindir=p build-root=p
40
- B|bulk-threshold=i document=b? g|file=p? p|http-proxy=q? i|install-dir=p platform=q
41
- s|source=q target-rbconfig=p? P|trust-policy=b without=q].freeze,
38
+ install: %w[version=b].freeze,
39
+ install_base: %w[f b|both clear-sources conservative default development development-all E|explain
40
+ ignore-dependencies l|local N|no-document r|remote w|vendor n|bindir=p build-root=p
41
+ bulk-threshold=i document=b? g|file=p? p|http-proxy=q i|install-dir=p platform=q s|source=q
42
+ target-rbconfig=p? P|trust-policy=b without=b].freeze,
42
43
  update: %w[system=b?].freeze,
43
- uninstall: %w[a D I x vendor n|bindir=p i|install-dir=p platform=b v|version=q].freeze,
44
- outdated: %w[b|both clear-sources l|local r|remote B|bulk-threshold=i p|http-proxy=q? platform=q
44
+ uninstall: %w[a D I x vendor n|bindir=p i|install-dir=p platform=b v|version=b].freeze,
45
+ outdated: %w[b|both clear-sources l|local no-http-proxy r|remote B|bulk-threshold=i p|http-proxy=q? platform=q
45
46
  source=q].freeze,
46
- push: %w[attestation=p host=q p|http-proxy=q? k|key=b otp=b].freeze,
47
- build: %w[C=p force strict o|output=p platform=q].freeze,
48
- exec: %w[conservative g|gem=b v|version=q].freeze,
49
- pristine: %w[E all only-executables only-missing-extensions only-plugins n|bindir=p i|install-dir=p skip=b
50
- v|version=q].freeze,
47
+ push: %w[no-http-proxy attestation=p host=q p|http-proxy=q? key=b otp=b].freeze,
48
+ build: %w[force strict o|output=p platform=q].freeze,
49
+ exec: %w[conservative no-prerelease prerelease g|gem=v version=b].freeze,
50
+ pristine: %w[all only-executables only-missing-extensions only-plugins n|bindir=p i|install-dir=p skip=b
51
+ v|version=b].freeze,
51
52
  no: {
52
53
  install: %w[env-shebang force format-executable http-proxy lock minimal-deps post-install-message prerelease
53
54
  suggestions user-install wrappers].freeze,
54
55
  uninstall: %w[abort-on-dependent all check-development executables force format-executable
55
56
  ignore-dependencies user-install].freeze,
56
- outdated: %w[http-proxy].freeze,
57
- push: %w[http-proxy].freeze,
58
- exec: %w[prerelease].freeze,
59
57
  pristine: %w[env-shebang extensions].freeze
60
58
  }.freeze
61
59
  }.freeze
@@ -69,7 +67,7 @@ module Squared
69
67
  end
70
68
 
71
69
  def bannerargs
72
- %i[dependfile gemname gemdir].freeze
70
+ [:dependfile].freeze
73
71
  end
74
72
 
75
73
  def config?(val)
@@ -83,7 +81,7 @@ module Squared
83
81
  'install' => %i[redownload local prefer-local].freeze,
84
82
  'update' => %i[patch minor major all].freeze,
85
83
  'outdated' => %i[patch minor major].freeze,
86
- 'gem' => %i[install uninstall update pristine outdated build push exec].freeze,
84
+ 'gem' => %i[install uninstall update pristine outdated push build exec].freeze,
87
85
  'ruby' => %i[file script version].freeze,
88
86
  'exec' => nil,
89
87
  'cache' => nil,
@@ -93,9 +91,7 @@ module Squared
93
91
  'irb' => nil
94
92
  })
95
93
 
96
- attr_reader :gemdir
97
-
98
- def initialize(*, autodetect: false, gemspec: nil, **kwargs)
94
+ def initialize(*, autodetect: false, **kwargs)
99
95
  super
100
96
  if @pass.include?(Ruby.ref)
101
97
  initialize_ref Ruby.ref
@@ -106,15 +102,11 @@ module Squared
106
102
  end
107
103
  dependfile_set GEMFILE
108
104
  @autodetect = autodetect
109
- @gemfile = if gemspec == false
110
- false
111
- elsif gemspec
112
- basepath(gemspec.include?('.') ? gemspec : "#{gemspec}.gemspec")
113
- end
114
- return if !@output[0].nil? || !@copy.nil? || version || @autodetect || !rakefile
105
+ @rakelist = nil
106
+ return if !@output[0].nil? || !@copy.nil? || @version || @autodetect || (file = rakefile).nil?
115
107
 
116
108
  begin
117
- File.foreach(rakefile) do |line|
109
+ File.foreach(file) do |line|
118
110
  next unless line.match?(%r{\brequire\s+(["'])bundler/gem_tasks\1})
119
111
 
120
112
  cmd = bundle_output('exec rake').to_s
@@ -128,73 +120,60 @@ module Squared
128
120
  end
129
121
  end
130
122
 
131
- def gemdir=(val)
132
- @gemdir = if val.is_a?(Pathname)
133
- val
134
- else
135
- Pathname.new(val).realdirpath rescue nil
136
- end
137
- end
138
-
139
123
  def ref
140
124
  Ruby.ref
141
125
  end
142
126
 
143
127
  def populate(*, **)
144
128
  super
145
- return unless (outdated? && ref?(Ruby.ref)) || @only
129
+ return unless outdated? && ref?(Ruby.ref)
146
130
 
147
131
  namespace name do
148
132
  Ruby.subtasks do |action, flags|
149
- next if task_pass?(action)
133
+ next if @pass.include?(action)
150
134
 
151
135
  if flags.nil?
152
136
  case action
153
137
  when 'rake'
154
138
  next unless rakefile
155
139
 
156
- format_desc action, nil, "task+,opts*|#{indexchar}index+|#,pattern*"
140
+ format_desc action, nil, 'tasks*,opts*|^index|#,pattern*'
157
141
  task action, [:command] do |_, args|
158
142
  if args.command == '#'
159
- format_list(raketasks, "rake[#{indexchar}N]", 'tasks', grep: args.extras, from: rakefile,
160
- each: ->(val) { val[0] + val[1].to_s })
161
- else
162
- args, opts = args.to_a.partition { |val| indexitem(val) }
163
- if args.empty?
164
- rake(opts: opts)
143
+ format_list(read_rakefile, 'rake[^N]', 'tasks', grep: args.extras, from: rakefile.to_s,
144
+ each: ->(val) { val[0] + val[1].to_s })
145
+ elsif (n, opts = indexitem(args.command))
146
+ list = read_rakefile
147
+ if (item = list[n - 1])
148
+ cmd = opts ? "#{opts} #{item.first}" : item.first
149
+ elsif exception
150
+ indexerror n, list
165
151
  else
166
- tasks = raketasks
167
- while (n, pre = indexitem(args.shift))
168
- if (item = tasks[n - 1])
169
- cmd = pre ? "#{pre} #{item.first}" : item.first
170
- elsif exception
171
- indexerror n, tasks
172
- else
173
- log.warn "rake task #{n} of #{tasks.size} (out of range)"
174
- next
175
- end
176
- if opts.empty?
177
- rake cmd
178
- else
179
- rake(cmd + shell_escape("[#{opts.join(',')}]"))
180
- opts.clear
181
- end
182
- end
152
+ log.warn "rake task #{n} of #{list.size} (out of range)"
153
+ next
183
154
  end
155
+ rake(args.extras.empty? ? cmd : cmd + shell_escape("[#{args.extras.join(',')}]"))
156
+ else
157
+ rake(opts: args.to_a)
184
158
  end
185
159
  end
186
160
  when 'irb'
161
+ next unless (spec = basepath("#{project}.gemspec") || basepath("#{name}.gemspec"))
162
+ next unless basepath('lib').join("#{gemname = stripext(spec)}.rb").exist?
163
+
187
164
  format_desc action, nil, 'opts*,args*|:'
188
165
  task action do |_, args|
189
166
  args = args.to_a
190
- name = gemlib.any? { |file| basepath(file).join("#{gemname}.rb").exist? } ? gemname : nil
191
- irb(name, args, args: (readline('Enter file [arguments]', force: false) if args.delete(':')))
167
+ if args.last == ':'
168
+ args.pop
169
+ load = readline('Enter file and arguments', force: false)
170
+ end
171
+ irb(gemname, args, load: load)
192
172
  end
193
173
  else
194
- format_desc(action, nil, 'opts*', before: case action
195
- when 'cache', 'check' then nil
196
- else 'command+'
197
- end)
174
+ format_desc(action, nil, OPT_BUNDLE[action.to_sym], after: case action
175
+ when 'cache', 'check' then nil
176
+ else 'command+' end)
198
177
  task action do |_, args|
199
178
  bundle(action, *args.to_a)
200
179
  end
@@ -216,24 +195,20 @@ module Squared
216
195
  case (filter = args.semver)
217
196
  when 'major', 'minor', 'patch', 'interactive', 'i'
218
197
  filter = 'interactive' if filter == 'i'
219
- args = args.extras
198
+ args = args.to_a.drop(1)
220
199
  else
221
200
  filter = nil
222
201
  args = args.to_a
223
202
  end
224
203
  gem!(flag, args, filter: filter)
225
204
  end
226
- when :build, :push, :exec, :update
227
- format_desc(action, flag, 'opts*', after: case flag
228
- when :exec then 'command,args*'
229
- when :push then 'file?'
230
- when :update then 'name*'
231
- end)
205
+ when :build, :push, :exec
206
+ format_desc(action, flag, 'opts*', before: flag == :exec ? 'command,args*' : nil)
232
207
  task flag do |_, args|
233
208
  gem! flag, args.to_a
234
209
  end
235
210
  else
236
- format_desc(action, flag, 'opts*', after: flag == :pristine ? 'name*|name?@version' : 'name*')
211
+ format_desc action, flag, "opts*,name+#{flag == :pristine ? '|name?@version' : ''}"
237
212
  task flag do |_, args|
238
213
  args = param_guard(action, flag, args: args.to_a)
239
214
  gem! flag, args
@@ -245,26 +220,22 @@ module Squared
245
220
  format_desc action, flag, 'path,opts*,args*'
246
221
  task flag, [:rb] do |_, args|
247
222
  file = args.rb
248
- opts = args.extras
249
- args = if file && !file.include?('*')
250
- ENV['RUBY_ARGS']
251
- else
252
- a, b, c = choice_index('Select a file', Dir.glob(file || path.join('*.rb')),
253
- values: (file ? [] : ['Options']).push('Arguments'),
254
- series: true)
255
- if file
256
- file = a
257
- b
258
- else
259
- file = a
260
- opts.concat(OptionPartition.strip(b))
261
- c
262
- end
263
- end
264
- ruby(flag, opts, file: file, args: args)
223
+ args = args.to_a.drop(1)
224
+ unless file && !file.include?('*')
225
+ values = ['Arguments']
226
+ values.prepend('Options') unless file
227
+ file, opts, extra = choice_index('Select a file', Dir.glob(file || '*.rb', base: path),
228
+ values: values, force: true, series: !args.include?('v'))
229
+ if file
230
+ extra = opts
231
+ else
232
+ args.concat(OptionPartition.strip(opts))
233
+ end
234
+ end
235
+ ruby(flag, args, file: file, args: extra)
265
236
  end
266
237
  when :script
267
- format_desc action, flag, 'opts*'
238
+ format_desc action, flag, 'opts*,args*'
268
239
  task flag do |_, args|
269
240
  command = ENV['RUBY_E'] || readline('Enter script', force: true, multiline: ['##', ';'])
270
241
  ruby(flag, args.to_a, command: command)
@@ -297,9 +268,7 @@ module Squared
297
268
  end
298
269
  end
299
270
 
300
- def copy(from: gemlib, into: gemdir, override: false, **kwargs)
301
- return if @copy == false
302
-
271
+ def copy(from: 'lib', into: @gemdir, override: false, **kwargs)
303
272
  glob = kwargs[:include]
304
273
  pass = kwargs[:exclude]
305
274
  if @copy && !override
@@ -309,22 +278,26 @@ module Squared
309
278
  glob = @copy[:include] if @copy.key?(:include)
310
279
  pass = @copy[:exclude] if @copy.key?(:exclude)
311
280
  into = @copy[:into] if @copy.key?(:into)
281
+ elsif @copy == false
282
+ return
312
283
  end
313
284
  return unless into
314
285
 
315
286
  on :first, :copy
316
287
  dest = Pathname.new(into).realpath
317
288
  print_item unless @output[0] || task_invoked?(/^copy(?::#{Ruby.ref}|$)/)
318
- glob = Array(glob || '**/*')
319
- Array(from).each_with_index do |val, i|
320
- a = basepath val
289
+ glob = as_a(glob || '**/*')
290
+ as_a(from).each_with_index do |val, i|
291
+ a = path + val
321
292
  b = dest + val
322
293
  c = glob[i] || glob.first
323
294
  log.info "cp #{a + c} #{b}"
324
295
  begin
325
- copy_dir(a, b, c, pass: pass, verbose: verbosetype > 0)
296
+ copy_dir(a, b, c, pass: pass, verbose: verbose)
326
297
  rescue StandardError => e
327
- on_error e, :copy
298
+ log.error e
299
+ ret = on(:error, :copy, e)
300
+ raise if exception && ret != true
328
301
  end
329
302
  end
330
303
  on :last, :copy
@@ -338,7 +311,7 @@ module Squared
338
311
  end
339
312
  log.info cmd.to_s
340
313
  on :first, :outdated
341
- banner = format_banner(cmd.to_s)
314
+ banner = format_banner cmd.to_s
342
315
  print_item banner if sync
343
316
  pwd_set(from: :outdated) do
344
317
  start = 0
@@ -429,7 +402,7 @@ module Squared
429
402
  end
430
403
  if found > 0
431
404
  begin
432
- if major == 0 && dependfile.read =~ /\b(?:source\s+(["'])(.+?)\1|remote:\s+(\S+))/
405
+ if major == 0 && dependfile.read =~ /\b(?:source\s+(["'])((?~\1))\1|remote:\s+(\S+))/
433
406
  status = ($2 || $3).chomp('/')
434
407
  right = true
435
408
  end
@@ -448,23 +421,14 @@ module Squared
448
421
 
449
422
  def install(flag, opts = [])
450
423
  bundle_session 'install', "--#{flag}"
451
- op = append_bundle opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:install] + OPT_BUNDLE[:common]
452
- if op.arg?('force')
453
- op.delete('--force')
454
- if flag != :redownload
455
- op << '--redownload'
456
- elsif (lock = basepath('Gemfile.lock')).exist?
457
- config = basepath '.bundle', 'config'
458
- lock.delete unless config.exist? && config.read.match?(/\bBUNDLE_FROZEN:\s+"true"/)
459
- end
460
- end
424
+ append_bundle opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:install] + OPT_BUNDLE[:common]
461
425
  run_rb(from: :install)
462
426
  end
463
427
 
464
428
  def update(flag, opts = [])
465
429
  bundle_session 'update', "--#{flag}"
466
430
  append_bundle(opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:update] + OPT_BUNDLE[:common],
467
- append: flag == :all ? nil : /\A[a-z-]+=/)
431
+ append: flag == :all ? nil : /\A[a-z\-]+=/)
468
432
  run_rb(from: :update)
469
433
  end
470
434
 
@@ -472,26 +436,24 @@ module Squared
472
436
  case flag
473
437
  when :file, :script
474
438
  op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, args: true)
475
- if command
439
+ if file
440
+ op.extras.prepend(shell_quote(path + file))
441
+ elsif command
476
442
  op << quote_option('e', command, option: false)
477
- elsif file
478
- op.unshift(basepath(file))
479
- end
480
- unless op.arg?('e')
481
- op.push(args) if args
482
- op.append(delim: true, escape: false, quote: false) unless op.empty?
483
443
  end
444
+ op.extras << args if (args = ENV.fetch('RUBY_ARGS', args))
445
+ op.append(delim: true, escape: false, quote: false) unless op.empty?
484
446
  when :version
485
447
  pwd_set do
486
448
  out = []
487
449
  [
488
- "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
489
450
  '$HOME/.rvm/bin/rvm',
490
- "#{ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf')}/plugins/ruby/bin/install",
491
- '/usr/bin/rbenv',
492
451
  '/usr/local/rvm/bin/rvm',
493
452
  '/usr/share/rvm/bin/rvm',
453
+ "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
454
+ '/usr/bin/rbenv',
494
455
  '/usr/local/share/chruby/chruby.sh',
456
+ "#{ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf')}/plugins/ruby/bin/install",
495
457
  ''
496
458
  ].each do |val|
497
459
  next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
@@ -502,8 +464,9 @@ module Squared
502
464
  when 'rvm'
503
465
  `rvm current`[/^\S+/, 0]
504
466
  when 'rbenv'
505
- name = `rbenv version-name`
506
- (name =~ SEM_VER) == 0 ? "ruby #{name}" : name
467
+ `rbenv version-name`.yield_self do |name|
468
+ name.match?(SEM_VER) ? "ruby #{name}" : name
469
+ end
507
470
  when 'chruby.sh'
508
471
  chruby = session_output 'source', val
509
472
  `#{chruby.with('ruby --version')}`
@@ -514,14 +477,12 @@ module Squared
514
477
  ver = nil
515
478
  `ruby --version`
516
479
  end)
517
- break if workspace.windows?
518
-
519
480
  unless val.empty?
520
481
  out << trim.call(case cmd
521
482
  when 'chruby.sh'
522
483
  `#{chruby.with('chruby --version')}`.sub(':', '')
523
484
  when 'install'
524
- "asdf #{`asdf version`.sub(/^v/, '')}"
485
+ "asdf #{`asdf version`.delete_prefix('v')}"
525
486
  else
526
487
  `#{cmd} --version`
527
488
  end)
@@ -556,14 +517,16 @@ module Squared
556
517
  end
557
518
  return
558
519
  end
559
- run_rb(banner: false, from: :"ruby:#{flag}")
520
+ run_rb(banner: op.arg?('v'), from: :"ruby:#{flag}")
560
521
  end
561
522
 
562
523
  def gem!(flag, opts = [], filter: nil)
563
524
  cmd = gem_session
564
525
  case flag
565
526
  when :outdated
566
- cmd << gempwd << flag
527
+ cmd << gempwd << 'outdated'
528
+ when :push
529
+ cmd << 'push' << project
567
530
  else
568
531
  cmd << flag
569
532
  end
@@ -572,10 +535,19 @@ module Squared
572
535
  case flag
573
536
  when :install, :update
574
537
  list.concat(OPT_GEM[:install_base])
538
+ first = ['=']
539
+ when :uninstall, :pristine
540
+ first = ['=']
575
541
  end
576
- op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GEM[:no][flag])
542
+ cmd.merge(preopts)
543
+ op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GEM[:no][flag], first: first)
577
544
  op.each do |opt|
578
- if !opt.match?(/\A[A-Za-z\d][A-Za-z\d_.-]*\z/) && %i[install uninstall update pristine].include?(flag)
545
+ if opt =~ op.values
546
+ case $1
547
+ when 'g', 'gem'
548
+ op << (flag == :exec ? shell_option($1, $2) : quote_option($1, path + $2))
549
+ end
550
+ elsif opt.include?('=') && !%i[outdated build push exec].include?(flag)
579
551
  op.errors << opt
580
552
  else
581
553
  op.found << opt
@@ -584,18 +556,17 @@ module Squared
584
556
  op.swap
585
557
  case flag
586
558
  when :outdated
559
+ log.info cmd.to_s
587
560
  op.clear
588
- cmd = cmd.done
589
- log.info cmd
590
561
  on :first, from
591
- print_item format_banner(cmd)
562
+ print_item format_banner(cmd.to_s)
592
563
  major = 0
593
564
  minor = 0
594
565
  patch = 0
595
566
  update = []
596
- pwd_set(pass: !gempwd.nil?, from: from) do
567
+ pwd_set(pass: !pwd.nil?, from: from) do
597
568
  items = [[%w[Gem Current Latest], nil]]
598
- IO.popen(cmd).each do |line|
569
+ IO.popen(cmd.done).each do |line|
599
570
  if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
600
571
  cur = semscan $2
601
572
  lat = semscan $3
@@ -670,8 +641,7 @@ module Squared
670
641
  styles = %i[yellow]
671
642
  pat = pat.last
672
643
  end
673
- b = b.rjust(e)
674
- b = sub_style(b, *colormap(styles), pat: pat, index: 2)
644
+ b = sub_style(b.rjust(e), *colormap(styles), pat: pat, index: 2)
675
645
  h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
676
646
  j += 1
677
647
  if queue
@@ -689,15 +659,15 @@ module Squared
689
659
  else
690
660
  unless update.empty?
691
661
  cmd = gem_output 'update', '-f'
692
- if (val = option('document', prefix: 'gem', ignore: false))
662
+ option('document', prefix: 'gem', ignore: false) do |val|
693
663
  cmd << case val
694
664
  when '0', 'false'
695
665
  '--no-document'
696
666
  else
697
- basic_option('document', val)
667
+ basic_option 'document', val
698
668
  end
699
669
  end
700
- if (val = option('user-install', prefix: 'gem', ignore: false))
670
+ option('user-install', prefix: 'gem', ignore: false) do |val|
701
671
  cmd << case val
702
672
  when '0', 'false'
703
673
  '--no-user-install'
@@ -708,84 +678,58 @@ module Squared
708
678
  cmd.merge(update)
709
679
  run(cmd, banner: false, from: :'gem:update')
710
680
  end
711
- print_status(major, minor, patch, from: :outdated)
681
+ unless stdin?
682
+ status = print_footer("major #{major} / minor #{minor} / patch #{patch}", right: true).split("\n")
683
+ status[1] = status[1]
684
+ .yield_self do |s|
685
+ sub_style(s, pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
686
+ end
687
+ .yield_self do |s|
688
+ sub_style(s, pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
689
+ end
690
+ puts status
691
+ end
712
692
  end
713
693
  on :last, from
714
694
  return
715
- when :build
716
- if op.empty?
717
- raise_error('gemspec not found', hint: project) unless gemfile
718
- op.add_path(gemfile)
719
- else
720
- op.add_path(op.shift)
721
- .clear(pass: false)
722
- end
723
- when :push
724
- if op.empty?
725
- file = basepath(if (spec = gemspec)
726
- "#{spec.name}-#{spec.version}.gem"
727
- else
728
- gems = Dir.glob(basepath('*.gem')).map { |val| File.basename(val) }
729
- choice_index 'Select a file', gems
730
- end)
731
- else
732
- file = op.shift
733
- raise_error("unknown args: #{op.join(', ')}", hint: flag) unless op.empty?
695
+ when :build, :push
696
+ if !op.empty?
697
+ if flag == :build && op.size == 1
698
+ op << shell_quote(path + op.first)
699
+ else
700
+ raise_error("unknown args: #{op.join(', ')}", hint: flag)
701
+ end
702
+ elsif flag == :build
703
+ spec = [path + "#{project}.gemspec", path + "#{name}.gemspec", *path.glob('*.gemspec')]
704
+ op << File.basename(spec) if (spec = spec.find { |file| File.exist?(file) })
734
705
  end
735
- raise_error('gem not found', hint: file) unless op.exist?(file)
736
- op.add_path(file)
737
- run_rb(from: from, interactive: "Push #{sub_style(gemname, styles: theme[:active])}")
738
- return
739
706
  when :exec
740
- min = if op.arg?('g', 'gem')
741
- 1
742
- elsif op.empty?
743
- op << basic_option('gem', gemname)
744
- 1
745
- else
746
- op << op.shift
747
- 0
748
- end
749
- if (args = command_args(op.extras, min: min, force: min == 1 && op.empty?))
707
+ raise_error('missing command', hint: flag) if op.empty?
708
+ op << basic_option('gem', project) unless op.arg?('g', 'gem')
709
+ if (args = command_args(op.extras))
750
710
  op.push(args)
751
711
  end
752
- op.append(quote: false)
753
- when :update
754
- unless op.arg?('system')
755
- if op.empty?
756
- op << gemname
757
- else
758
- op.append
759
- end
760
- end
761
- op.clear(errors: true)
762
- when :install, :uninstall, :pristine
763
- raise_error('missing gemname', hint: flag) if op.empty?
764
- if op.arg?('all')
765
- if flag == :pristine
712
+ op.append(delim: true, quote: false)
713
+ else
714
+ raise_error('missing gemname', hint: flag) if op.empty? && !op.arg?('system')
715
+ if flag == :pristine
716
+ if op.arg?('all')
766
717
  append_repeat 'skip', op.extras
767
- op.reset
768
- else
718
+ op.extras.clear
719
+ elsif (n = op.first.index('@'))
720
+ name = op.shift
721
+ if n == 0
722
+ op << project
723
+ ver = name[1..-1]
724
+ else
725
+ op << shell_escape(name[0, n])
726
+ ver = name[n + 1..-1]
727
+ end
728
+ op << shell_option('version', ver)
769
729
  op.clear
770
730
  end
771
- elsif (n = op.index { |val| val.match?(/(\A|[\w.-])@\d/) })
772
- name = op.delete_at(n)
773
- pre, ver = if (n = name.index('@')) == 0
774
- [gemname, name[1..-1]]
775
- else
776
- [name[0, n], name[(n + 1)..-1]]
777
- end
778
- op.adjoin(pre, basic_option('version', ver))
779
- .clear
780
- elsif flag == :install
781
- op.append_any
782
- else
783
- op.append
784
731
  end
785
- op.clear(errors: true)
786
- op << '--' << readline('Enter command [args]', force: true) if flag == :install && op.remove(':')
787
- else
788
- op.append
732
+ op.append.clear(errors: true)
789
733
  end
790
734
  run_rb(from: from)
791
735
  end
@@ -795,24 +739,26 @@ module Squared
795
739
  args = case flag
796
740
  when 'exec', 'cache', 'check'
797
741
  list = OPT_BUNDLE[flag.to_sym] + OPT_BUNDLE[:common]
798
- OptionPartition.new(args, list, cmd, project: self, args: flag == 'exec').extras
742
+ OptionPartition.new(args, list, cmd, project: self, args: flag == :exec).extras
799
743
  else
800
744
  args.flatten
801
745
  end
802
746
  case flag
803
747
  when 'exec', 'config'
804
- cmd << readline('Enter arguments', force: true) if args.empty?
805
- when 'cache', 'check'
748
+ if args.empty?
749
+ cmd << readline('Enter arguments', force: true)
750
+ else
751
+ args << command_args(args)
752
+ cmd.merge(args)
753
+ end
754
+ else
806
755
  option_clear args
807
- args.clear
808
756
  end
809
- cmd.merge(args)
810
757
  run(from: :"bundle:#{flag}")
811
758
  end
812
759
 
813
760
  def rake(*args, opts: [])
814
- op = OptionPartition.new(opts, OPT_RUBY[:rake], [(quote_option('f', rakefile) if rakefile)].compact,
815
- project: self)
761
+ op = OptionPartition.new(opts, OPT_RUBY[:rake], [quote_option('f', rakefile)], project: self)
816
762
  args.concat(op.extras)
817
763
  if args.empty?
818
764
  args << nil
@@ -824,14 +770,14 @@ module Squared
824
770
  run_s(args, banner: false, from: :rake)
825
771
  end
826
772
 
827
- def irb(name = nil, opts = [], path: gemlib, args: nil)
773
+ def irb(name, opts = [], path: @path + 'lib', load: nil)
828
774
  op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
829
- r = args ? [] : ['bundler/setup']
830
- r << name if name
775
+ r = as_a name
776
+ r.prepend('bundler/setup') unless load
831
777
  r.each { |val| op << shell_option('r', val, merge: true) }
832
- Array(path).each { |val| op << quote_option('I', val, merge: true) }
833
- if args
834
- op << '--' << args
778
+ as_a(path).each { |val| op << quote_option('I', val, merge: true) }
779
+ if load
780
+ op << '--' << load
835
781
  op.clear
836
782
  else
837
783
  op.append(delim: true)
@@ -839,85 +785,76 @@ module Squared
839
785
  run(banner: false)
840
786
  end
841
787
 
842
- def gemspec
843
- @gemspec = !gemfile.nil? && Gem::Specification.load(gemfile.to_s) rescue false if @gemspec.nil?
844
- @gemspec || nil
845
- end
846
-
847
- def gemname
848
- @gemname ||= ((spec = gemspec) ? spec.name : project)
849
- end
850
-
851
788
  def depend?
852
789
  @depend != false && (!@depend.nil? || outdated?)
853
790
  end
854
791
 
855
792
  def copy?
856
- return true if @copy.is_a?(Hash) ? copy[:into] : super
857
- return gemdir? if gemdir
858
- return false unless @autodetect
859
-
860
- set = lambda do |val, path|
861
- base = Pathname.new(path.strip)
862
- return false unless base.join(gempath(val, 'specifications')).exist?
793
+ return true if super || (@copy.is_a?(Hash) && copy.fetch(:into, nil))
794
+ return gemdir? if @gemdir
863
795
 
864
- log.warn "using version #{val} (given #{version})" if version && version != val
865
- self.version = val
866
- self.gemdir = base + gempath
867
- end
868
- if version
796
+ if @version
869
797
  begin
870
798
  case @autodetect
871
799
  when 'rvm'
872
- self.gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
800
+ @gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
873
801
  when 'rbenv'
874
802
  if pwd_set { `rbenv which ruby` } =~ %r{^(.+[\\/]versions[\\/](\d\.\d)\.[^\\/]+)[\\/]bin[\\/]ruby$}
875
- self.gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
803
+ @gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
876
804
  end
877
805
  when 'asdf'
878
- val = pwd_set { `asdf where ruby`.chomp }
879
- self.gemdir = File.join(val, 'lib/ruby/gems', "#{$1}.0") if val =~ /(\d\.\d)\.[^.]+$/
806
+ @gemdir = pwd_set { `asdf where ruby` }
807
+ @gemdir = @gemdir =~ /(\d\.\d)\.[^.]+$/ && File.join(@gemdir, 'lib/ruby/gems', "#{$1}.0")
880
808
  when /bundler?/
881
- path = pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1]
882
- self.gemdir = path.split(File::PATH_SEPARATOR).find { |val| Dir.exist?(val) }
883
- else
884
- self.gemdir = ENV['GEM_HOME'] || ENV['GEM_ROOT']
809
+ @gemdir = pwd_set { `bundle env` }[/^\s+Gem Home\s+(.+)$/, 1]
885
810
  end
886
- return true if gemdir?
887
811
  rescue StandardError => e
888
812
  log.debug e
813
+ else
814
+ @gemdir = Pathname.new(@gemdir) if @gemdir
889
815
  end
890
- pwd_set(pass: !gempwd.nil?) do
891
- out = `#{gem_output(gempwd, 'list --local -d', gemname)}`
892
- if out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
893
- split_escape($1)
894
- .unshift(@version)
816
+ return true if gemdir?
817
+ end
818
+ return false unless @autodetect
819
+
820
+ set = lambda do |val, path|
821
+ log.warn "using version #{val} (given #{@version})" if @version && @version != val
822
+ @version = val
823
+ @gemdir = Pathname.new(path.strip) + gempath
824
+ end
825
+ if @version
826
+ pwd = gempwd
827
+ pwd_set(pass: !pwd.nil?) do
828
+ out = `#{gem_output(pwd, 'list --local -d', project)}`
829
+ if out =~ /#{Regexp.escape(project)} \(([^)]+)\)/
830
+ $1.split(/\s*,\s*/)
831
+ .prepend(@version)
895
832
  .uniq
896
833
  .each do |val|
897
- next unless out =~ /(?:\(#{Regexp.escape(val)}[^)]*\)|Installed at):\s+(.+)$/
834
+ next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
898
835
 
899
- return gemdir? if set.call(val, $1)
836
+ set.call(val, $1)
837
+ break
900
838
  end
901
839
  end
902
840
  end
903
- self.gemdir = Pathname.new(Gem.dir) + gempath
904
- else
841
+ end
842
+ unless @gemdir
905
843
  parse = lambda do |path|
906
844
  next unless path
907
845
 
908
- lib = Regexp.new(['', 'gems', "#{gemname}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
909
- if (ver = path[lib, 1]) && (val = path[/\A(.+)#{Regexp.escape(gempath(ver))}/, 1])
846
+ lib = Regexp.new(['', 'gems', "#{project}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
847
+ if (ver = path[lib, 1]) && (val = path[/\A(.+)#{gempath(ver[1])}/, 1])
910
848
  set.call(ver, val)
911
849
  end
912
850
  end
913
851
  if RUBY_VERSION >= '2.6'
914
852
  target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
915
- parse.call(target.resolve_feature_path(gemname)&.last)
916
- end
917
- if !gemdir && !pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
918
- raise_error 'gems directory not found'
853
+ parse.call(target.resolve_feature_path(project)&.last)
919
854
  end
855
+ pwd_set { parse.call(`#{bundle_output('show', project)}`) } unless @gemdir
920
856
  end
857
+ raise_error('parse failed', hint: @version || 'path') unless @gemdir
921
858
  rescue StandardError => e
922
859
  log.error e
923
860
  @version = nil
@@ -928,13 +865,13 @@ module Squared
928
865
  end
929
866
 
930
867
  def outdated?
931
- dependtype > 0 && !task_pass?('outdated')
868
+ dependtype > 0
932
869
  end
933
870
 
934
871
  private
935
872
 
936
873
  def run_rb(**kwargs)
937
- run(banner: !@session&.include?('--quiet'), **kwargs)
874
+ run(banner: !@session.include?('--quiet'), **kwargs)
938
875
  end
939
876
 
940
877
  def append_bundle(opts, list, target: @session, append: nil)
@@ -954,7 +891,6 @@ module Squared
954
891
  else
955
892
  op.clear
956
893
  end
957
- op
958
894
  end
959
895
 
960
896
  def ruby_session(*cmd, **kwargs)
@@ -962,11 +898,18 @@ module Squared
962
898
  end
963
899
 
964
900
  def gem_session(*cmd, **kwargs)
965
- session('gem', *cmd, *preopts, **kwargs)
901
+ ret = session('gem', *cmd, **kwargs)
902
+ return ret if cmd.empty?
903
+
904
+ ret.merge(preopts)
966
905
  end
967
906
 
968
907
  def bundle_session(*cmd, **kwargs)
969
- session('bundle', *cmd, *preopts, **kwargs).tap { append_nocolor }
908
+ ret = session('bundle', *cmd, **kwargs)
909
+ return ret if cmd.empty?
910
+
911
+ append_nocolor
912
+ ret.merge(preopts)
970
913
  end
971
914
 
972
915
  def rake_session(*cmd, **kwargs)
@@ -989,79 +932,54 @@ module Squared
989
932
  session_output('rake', *cmd, **kwargs)
990
933
  end
991
934
 
935
+ def read_rakefile
936
+ return @rakelist if @rakelist
937
+
938
+ ret = []
939
+ pwd = rakepwd
940
+ pwd_set(pass: !pwd.nil?) do
941
+ IO.popen(rake_output(pwd, '-AT').to_s).each do |line|
942
+ next unless line =~ /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/
943
+
944
+ ret << [$1, $2]
945
+ end
946
+ end
947
+ @rakelist = ret
948
+ end
949
+
992
950
  def preopts
993
- verbosetype > 1 ? ['--verbose'] : []
951
+ verbosetype > 1 && !session_arg?('quiet') ? ['--verbose'] : []
952
+ end
953
+
954
+ def gemdir?
955
+ !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
994
956
  end
995
957
 
996
958
  def variables
997
- (super + %i[autodetect]).freeze
959
+ (super + %i[version autodetect]).freeze
998
960
  end
999
961
 
1000
962
  def rakefile
1001
- if @rakefile.nil?
1002
- file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? }
1003
- @rakefile = !file.nil? && basepath(file)
1004
- end
1005
- @rakefile || nil
963
+ return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
964
+
965
+ path + file
1006
966
  end
1007
967
 
1008
968
  def rakepwd
1009
- return unless !pwd? && semgte?(Rake::VERSION, '13.0.4')
969
+ return unless Rake::VERSION >= '13.0.4'
1010
970
 
1011
971
  quote_option 'C', path
1012
972
  end
1013
973
 
1014
- def raketasks
1015
- @raketasks ||= [].tap do |ret|
1016
- opt = rakepwd
1017
- pwd_set(pass: !opt.nil?) do
1018
- IO.popen(rake_output(opt, '-AT').to_s).each do |line|
1019
- next unless line =~ /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/
1020
-
1021
- ret << [$1, $2]
1022
- end
1023
- end
1024
- end
1025
- end
1026
-
1027
974
  def gempwd
1028
- return unless !pwd? && semgte?(Gem::VERSION, '3.4.2')
975
+ return unless Gem::VERSION >= '3.4.2'
1029
976
 
1030
977
  quote_option 'C', path
1031
978
  end
1032
979
 
1033
- def gemfile
1034
- if @gemfile.nil?
1035
- @gemfile = [project, name].map! { |val| basepath("#{val}.gemspec") }
1036
- .concat(Dir.glob(basepath('*.gemspec')))
1037
- .find { |file| File.exist?(file) } || false
1038
- end
1039
- @gemfile || nil
980
+ def gempath(val = @version)
981
+ File.join('gems', "#{project}-#{val}")
1040
982
  end
1041
-
1042
- def gemlib
1043
- @gemlib ||= begin
1044
- lib = Set.new(['lib'])
1045
- if (spec = gemspec)
1046
- lib.merge(spec.require_paths || [])
1047
- end
1048
- lib.select { |file| basepath(file).exist? }
1049
- end
1050
- end
1051
-
1052
- def gempath(val = version, dir = 'gems')
1053
- ret = File.join(dir, "#{gemname}-#{val}")
1054
- ret += '.gemspec' if dir == 'specifications'
1055
- ret
1056
- end
1057
-
1058
- def gemdir?
1059
- return false unless gemdir
1060
-
1061
- gemdir.exist? && !gemdir.empty?
1062
- end
1063
-
1064
- alias read_rakefile raketasks
1065
983
  end
1066
984
 
1067
985
  Application.implement Ruby