squared 0.4.25 → 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 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,
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,
29
30
  outdated: %w[filter-major filter-minor filter-patch groups local parseable pre only-explicit strict
30
- update-strict group=q source=b].freeze,
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=b].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].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,7 +91,7 @@ module Squared
93
91
  'irb' => nil
94
92
  })
95
93
 
96
- def initialize(*, autodetect: false, gemspec: nil, **kwargs)
94
+ def initialize(*, autodetect: false, **kwargs)
97
95
  super
98
96
  if @pass.include?(Ruby.ref)
99
97
  initialize_ref Ruby.ref
@@ -104,15 +102,11 @@ module Squared
104
102
  end
105
103
  dependfile_set GEMFILE
106
104
  @autodetect = autodetect
107
- @gemfile = if gemspec == false
108
- false
109
- elsif gemspec
110
- basepath(gemspec.include?('.') ? gemspec : "#{gemspec}.gemspec")
111
- end
112
- 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?
113
107
 
114
108
  begin
115
- File.foreach(rakefile) do |line|
109
+ File.foreach(file) do |line|
116
110
  next unless line.match?(%r{\brequire\s+(["'])bundler/gem_tasks\1})
117
111
 
118
112
  cmd = bundle_output('exec rake').to_s
@@ -132,59 +126,54 @@ module Squared
132
126
 
133
127
  def populate(*, **)
134
128
  super
135
- return unless (outdated? && ref?(Ruby.ref)) || @only
129
+ return unless outdated? && ref?(Ruby.ref)
136
130
 
137
131
  namespace name do
138
132
  Ruby.subtasks do |action, flags|
139
- next if task_pass?(action)
133
+ next if @pass.include?(action)
140
134
 
141
135
  if flags.nil?
142
136
  case action
143
137
  when 'rake'
144
138
  next unless rakefile
145
139
 
146
- format_desc action, nil, "task+,opts*|#{indexchar}index+|#,pattern*"
140
+ format_desc action, nil, 'tasks*,opts*|^index|#,pattern*'
147
141
  task action, [:command] do |_, args|
148
142
  if args.command == '#'
149
- format_list(raketasks, "rake[#{indexchar}N]", 'tasks', grep: args.extras, from: rakefile,
150
- each: ->(val) { val[0] + val[1].to_s })
151
- else
152
- args, opts = args.to_a.partition { |val| indexitem(val) }
153
- if args.empty?
154
- 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
155
151
  else
156
- tasks = raketasks
157
- while (n, pre = indexitem(args.shift))
158
- if (item = tasks[n - 1])
159
- cmd = pre ? "#{pre} #{item.first}" : item.first
160
- elsif exception
161
- indexerror n, tasks
162
- else
163
- log.warn "rake task #{n} of #{tasks.size} (out of range)"
164
- next
165
- end
166
- if opts.empty?
167
- rake cmd
168
- else
169
- rake(cmd + shell_escape("[#{opts.join(',')}]"))
170
- opts.clear
171
- end
172
- end
152
+ log.warn "rake task #{n} of #{list.size} (out of range)"
153
+ next
173
154
  end
155
+ rake(args.extras.empty? ? cmd : cmd + shell_escape("[#{args.extras.join(',')}]"))
156
+ else
157
+ rake(opts: args.to_a)
174
158
  end
175
159
  end
176
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
+
177
164
  format_desc action, nil, 'opts*,args*|:'
178
165
  task action do |_, args|
179
166
  args = args.to_a
180
- name = gemlib.any? { |file| basepath(file).join("#{gemname}.rb").exist? } ? gemname : nil
181
- 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)
182
172
  end
183
173
  else
184
- format_desc(action, nil, 'opts*', before: case action
185
- when 'cache', 'check' then nil
186
- else 'command+'
187
- end)
174
+ format_desc(action, nil, OPT_BUNDLE[action.to_sym], after: case action
175
+ when 'cache', 'check' then nil
176
+ else 'command+' end)
188
177
  task action do |_, args|
189
178
  bundle(action, *args.to_a)
190
179
  end
@@ -206,24 +195,20 @@ module Squared
206
195
  case (filter = args.semver)
207
196
  when 'major', 'minor', 'patch', 'interactive', 'i'
208
197
  filter = 'interactive' if filter == 'i'
209
- args = args.extras
198
+ args = args.to_a.drop(1)
210
199
  else
211
200
  filter = nil
212
201
  args = args.to_a
213
202
  end
214
203
  gem!(flag, args, filter: filter)
215
204
  end
216
- when :build, :push, :exec, :update
217
- format_desc(action, flag, 'opts*', after: case flag
218
- when :exec then 'command,args*'
219
- when :push then 'file?'
220
- when :update then 'name*'
221
- end)
205
+ when :build, :push, :exec
206
+ format_desc(action, flag, 'opts*', before: flag == :exec ? 'command,args*' : nil)
222
207
  task flag do |_, args|
223
208
  gem! flag, args.to_a
224
209
  end
225
210
  else
226
- format_desc(action, flag, 'opts*', after: flag == :pristine ? 'name*|name?@version' : 'name*')
211
+ format_desc action, flag, "opts*,name+#{flag == :pristine ? '|name?@version' : ''}"
227
212
  task flag do |_, args|
228
213
  args = param_guard(action, flag, args: args.to_a)
229
214
  gem! flag, args
@@ -235,26 +220,22 @@ module Squared
235
220
  format_desc action, flag, 'path,opts*,args*'
236
221
  task flag, [:rb] do |_, args|
237
222
  file = args.rb
238
- opts = args.extras
239
- args = if file && !file.include?('*')
240
- ENV['RUBY_ARGS']
241
- else
242
- a, b, c = choice_index('Select a file', Dir.glob(file || path.join('*.rb')),
243
- values: (file ? [] : ['Options']).push('Arguments'),
244
- force: true, series: true)
245
- if file
246
- file = a
247
- b
248
- else
249
- file = a
250
- opts.concat(OptionPartition.strip(b))
251
- c
252
- end
253
- end
254
- 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)
255
236
  end
256
237
  when :script
257
- format_desc action, flag, 'opts*'
238
+ format_desc action, flag, 'opts*,args*'
258
239
  task flag do |_, args|
259
240
  command = ENV['RUBY_E'] || readline('Enter script', force: true, multiline: ['##', ';'])
260
241
  ruby(flag, args.to_a, command: command)
@@ -287,7 +268,7 @@ module Squared
287
268
  end
288
269
  end
289
270
 
290
- def copy(from: gemlib, into: @gemdir, override: false, **kwargs)
271
+ def copy(from: 'lib', into: @gemdir, override: false, **kwargs)
291
272
  glob = kwargs[:include]
292
273
  pass = kwargs[:exclude]
293
274
  if @copy && !override
@@ -305,16 +286,18 @@ module Squared
305
286
  on :first, :copy
306
287
  dest = Pathname.new(into).realpath
307
288
  print_item unless @output[0] || task_invoked?(/^copy(?::#{Ruby.ref}|$)/)
308
- glob = Array(glob || '**/*')
309
- Array(from).each_with_index do |val, i|
310
- a = basepath val
289
+ glob = as_a(glob || '**/*')
290
+ as_a(from).each_with_index do |val, i|
291
+ a = path + val
311
292
  b = dest + val
312
293
  c = glob[i] || glob.first
313
294
  log.info "cp #{a + c} #{b}"
314
295
  begin
315
- copy_dir(a, b, c, pass: pass, verbose: verbosetype > 0)
296
+ copy_dir(a, b, c, pass: pass, verbose: verbose)
316
297
  rescue StandardError => e
317
- on_error e, :copy
298
+ log.error e
299
+ ret = on(:error, :copy, e)
300
+ raise if exception && ret != true
318
301
  end
319
302
  end
320
303
  on :last, :copy
@@ -328,7 +311,7 @@ module Squared
328
311
  end
329
312
  log.info cmd.to_s
330
313
  on :first, :outdated
331
- banner = format_banner(cmd.to_s)
314
+ banner = format_banner cmd.to_s
332
315
  print_item banner if sync
333
316
  pwd_set(from: :outdated) do
334
317
  start = 0
@@ -419,7 +402,7 @@ module Squared
419
402
  end
420
403
  if found > 0
421
404
  begin
422
- 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+))/
423
406
  status = ($2 || $3).chomp('/')
424
407
  right = true
425
408
  end
@@ -438,23 +421,14 @@ module Squared
438
421
 
439
422
  def install(flag, opts = [])
440
423
  bundle_session 'install', "--#{flag}"
441
- op = append_bundle opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:install] + OPT_BUNDLE[:common]
442
- if op.arg?('force')
443
- op.delete('--force')
444
- if flag != :redownload
445
- op << '--redownload'
446
- elsif (lock = basepath('Gemfile.lock')).exist?
447
- config = basepath '.bundle', 'config'
448
- lock.delete unless config.exist? && config.read.match?(/\bBUNDLE_FROZEN:\s+"true"/)
449
- end
450
- end
424
+ append_bundle opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:install] + OPT_BUNDLE[:common]
451
425
  run_rb(from: :install)
452
426
  end
453
427
 
454
428
  def update(flag, opts = [])
455
429
  bundle_session 'update', "--#{flag}"
456
430
  append_bundle(opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:update] + OPT_BUNDLE[:common],
457
- append: flag == :all ? nil : /\A[a-z-]+=/)
431
+ append: flag == :all ? nil : /\A[a-z\-]+=/)
458
432
  run_rb(from: :update)
459
433
  end
460
434
 
@@ -463,23 +437,23 @@ module Squared
463
437
  when :file, :script
464
438
  op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, args: true)
465
439
  if file
466
- op.unshift(shell_quote(basepath(file)))
440
+ op.extras.prepend(shell_quote(path + file))
467
441
  elsif command
468
442
  op << quote_option('e', command, option: false)
469
443
  end
470
- op.push(args) if args
444
+ op.extras << args if (args = ENV.fetch('RUBY_ARGS', args))
471
445
  op.append(delim: true, escape: false, quote: false) unless op.empty?
472
446
  when :version
473
447
  pwd_set do
474
448
  out = []
475
449
  [
476
- "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
477
450
  '$HOME/.rvm/bin/rvm',
478
- "#{ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf')}/plugins/ruby/bin/install",
479
- '/usr/bin/rbenv',
480
451
  '/usr/local/rvm/bin/rvm',
481
452
  '/usr/share/rvm/bin/rvm',
453
+ "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
454
+ '/usr/bin/rbenv',
482
455
  '/usr/local/share/chruby/chruby.sh',
456
+ "#{ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf')}/plugins/ruby/bin/install",
483
457
  ''
484
458
  ].each do |val|
485
459
  next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
@@ -490,8 +464,9 @@ module Squared
490
464
  when 'rvm'
491
465
  `rvm current`[/^\S+/, 0]
492
466
  when 'rbenv'
493
- name = `rbenv version-name`
494
- name =~ SEM_VER ? "ruby #{name}" : name
467
+ `rbenv version-name`.yield_self do |name|
468
+ name.match?(SEM_VER) ? "ruby #{name}" : name
469
+ end
495
470
  when 'chruby.sh'
496
471
  chruby = session_output 'source', val
497
472
  `#{chruby.with('ruby --version')}`
@@ -502,14 +477,12 @@ module Squared
502
477
  ver = nil
503
478
  `ruby --version`
504
479
  end)
505
- break if workspace.windows?
506
-
507
480
  unless val.empty?
508
481
  out << trim.call(case cmd
509
482
  when 'chruby.sh'
510
483
  `#{chruby.with('chruby --version')}`.sub(':', '')
511
484
  when 'install'
512
- "asdf #{`asdf version`.sub(/^v/, '')}"
485
+ "asdf #{`asdf version`.delete_prefix('v')}"
513
486
  else
514
487
  `#{cmd} --version`
515
488
  end)
@@ -544,14 +517,16 @@ module Squared
544
517
  end
545
518
  return
546
519
  end
547
- run_rb(banner: false, from: :"ruby:#{flag}")
520
+ run_rb(banner: op.arg?('v'), from: :"ruby:#{flag}")
548
521
  end
549
522
 
550
523
  def gem!(flag, opts = [], filter: nil)
551
524
  cmd = gem_session
552
525
  case flag
553
526
  when :outdated
554
- cmd << gempwd << flag
527
+ cmd << gempwd << 'outdated'
528
+ when :push
529
+ cmd << 'push' << project
555
530
  else
556
531
  cmd << flag
557
532
  end
@@ -560,11 +535,19 @@ module Squared
560
535
  case flag
561
536
  when :install, :update
562
537
  list.concat(OPT_GEM[:install_base])
538
+ first = ['=']
539
+ when :uninstall, :pristine
540
+ first = ['=']
563
541
  end
564
542
  cmd.merge(preopts)
565
- op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GEM[:no][flag])
543
+ op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GEM[:no][flag], first: first)
566
544
  op.each do |opt|
567
- 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)
568
551
  op.errors << opt
569
552
  else
570
553
  op.found << opt
@@ -573,18 +556,17 @@ module Squared
573
556
  op.swap
574
557
  case flag
575
558
  when :outdated
559
+ log.info cmd.to_s
576
560
  op.clear
577
- cmd = cmd.done
578
- log.info cmd
579
561
  on :first, from
580
- print_item format_banner(cmd)
562
+ print_item format_banner(cmd.to_s)
581
563
  major = 0
582
564
  minor = 0
583
565
  patch = 0
584
566
  update = []
585
- pwd_set(pass: !gempwd.nil?, from: from) do
567
+ pwd_set(pass: !pwd.nil?, from: from) do
586
568
  items = [[%w[Gem Current Latest], nil]]
587
- IO.popen(cmd).each do |line|
569
+ IO.popen(cmd.done).each do |line|
588
570
  if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
589
571
  cur = semscan $2
590
572
  lat = semscan $3
@@ -659,8 +641,7 @@ module Squared
659
641
  styles = %i[yellow]
660
642
  pat = pat.last
661
643
  end
662
- b = b.rjust(e)
663
- b = sub_style(b, *colormap(styles), pat: pat, index: 2)
644
+ b = sub_style(b.rjust(e), *colormap(styles), pat: pat, index: 2)
664
645
  h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
665
646
  j += 1
666
647
  if queue
@@ -678,15 +659,15 @@ module Squared
678
659
  else
679
660
  unless update.empty?
680
661
  cmd = gem_output 'update', '-f'
681
- if (val = option('document', prefix: 'gem', ignore: false))
662
+ option('document', prefix: 'gem', ignore: false) do |val|
682
663
  cmd << case val
683
664
  when '0', 'false'
684
665
  '--no-document'
685
666
  else
686
- basic_option('document', val)
667
+ basic_option 'document', val
687
668
  end
688
669
  end
689
- if (val = option('user-install', prefix: 'gem', ignore: false))
670
+ option('user-install', prefix: 'gem', ignore: false) do |val|
690
671
  cmd << case val
691
672
  when '0', 'false'
692
673
  '--no-user-install'
@@ -697,84 +678,58 @@ module Squared
697
678
  cmd.merge(update)
698
679
  run(cmd, banner: false, from: :'gem:update')
699
680
  end
700
- 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
701
692
  end
702
693
  on :last, from
703
694
  return
704
- when :build
705
- if op.empty?
706
- raise_error('gemspec not found', hint: project) unless gemfile
707
- op.add_path(gemfile)
708
- else
709
- op.add_path(op.shift)
710
- .clear(pass: false)
711
- end
712
- when :push
713
- if op.empty?
714
- file = basepath(if (spec = gemspec)
715
- "#{spec.name}-#{spec.version}.gem"
716
- else
717
- gems = Dir.glob(basepath('*.gem')).map { |val| File.basename(val) }
718
- choice_index('Select a file', gems, force: true)
719
- end)
720
- else
721
- file = op.shift
722
- 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) })
723
705
  end
724
- raise_error('gem not found', hint: file) unless op.exist?(file)
725
- op.add_path(file)
726
- run_rb(from: from, interactive: "Push #{sub_style(gemname, styles: theme[:active])}")
727
- return
728
706
  when :exec
729
- min = if op.arg?('g', 'gem')
730
- 1
731
- elsif op.empty?
732
- op << basic_option('gem', gemname)
733
- 1
734
- else
735
- op << op.shift
736
- 0
737
- end
738
- 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))
739
710
  op.push(args)
740
711
  end
741
- op.append(quote: false)
742
- when :update
743
- unless op.arg?('system')
744
- if op.empty?
745
- op << gemname
746
- else
747
- op.append
748
- end
749
- end
750
- op.clear(errors: true)
751
- when :install, :uninstall, :pristine
752
- raise_error('missing gemname', hint: flag) if op.empty?
753
- if op.arg?('all')
754
- 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')
755
717
  append_repeat 'skip', op.extras
756
- op.reset
757
- 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)
758
729
  op.clear
759
730
  end
760
- elsif (n = op.index { |val| val.match?(/(\A|[a-z])@\d/) })
761
- name = op.delete_at(n)
762
- pre, ver = if (n = name.index('@')) == 0
763
- [gemname, name[1..-1]]
764
- else
765
- [name[0, n], name[(n + 1)..-1]]
766
- end
767
- op.adjoin(pre, shell_option('version', ver))
768
- .clear
769
- elsif flag == :install
770
- op.append_any
771
- else
772
- op.append
773
731
  end
774
- op.clear(errors: true)
775
- op << '--' << readline('Enter command [args]', force: true) if flag == :install && op.remove(':')
776
- else
777
- op.append
732
+ op.append.clear(errors: true)
778
733
  end
779
734
  run_rb(from: from)
780
735
  end
@@ -784,24 +739,26 @@ module Squared
784
739
  args = case flag
785
740
  when 'exec', 'cache', 'check'
786
741
  list = OPT_BUNDLE[flag.to_sym] + OPT_BUNDLE[:common]
787
- OptionPartition.new(args, list, cmd, project: self, args: flag == 'exec').extras
742
+ OptionPartition.new(args, list, cmd, project: self, args: flag == :exec).extras
788
743
  else
789
744
  args.flatten
790
745
  end
791
746
  case flag
792
747
  when 'exec', 'config'
793
- cmd << readline('Enter arguments', force: true) if args.empty?
794
- 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
795
755
  option_clear args
796
- args.clear
797
756
  end
798
- cmd.merge(args)
799
757
  run(from: :"bundle:#{flag}")
800
758
  end
801
759
 
802
760
  def rake(*args, opts: [])
803
- op = OptionPartition.new(opts, OPT_RUBY[:rake], [(quote_option('f', rakefile) if rakefile)].compact,
804
- project: self)
761
+ op = OptionPartition.new(opts, OPT_RUBY[:rake], [quote_option('f', rakefile)], project: self)
805
762
  args.concat(op.extras)
806
763
  if args.empty?
807
764
  args << nil
@@ -813,14 +770,14 @@ module Squared
813
770
  run_s(args, banner: false, from: :rake)
814
771
  end
815
772
 
816
- def irb(name = nil, opts = [], path: gemlib, args: nil)
773
+ def irb(name, opts = [], path: @path + 'lib', load: nil)
817
774
  op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
818
- r = args ? [] : ['bundler/setup']
819
- r << name if name
775
+ r = as_a name
776
+ r.prepend('bundler/setup') unless load
820
777
  r.each { |val| op << shell_option('r', val, merge: true) }
821
- Array(path).each { |val| op << quote_option('I', val, merge: true) }
822
- if args
823
- op << '--' << args
778
+ as_a(path).each { |val| op << quote_option('I', val, merge: true) }
779
+ if load
780
+ op << '--' << load
824
781
  op.clear
825
782
  else
826
783
  op.append(delim: true)
@@ -828,29 +785,15 @@ module Squared
828
785
  run(banner: false)
829
786
  end
830
787
 
831
- def gemspec
832
- return @gemspec unless @gemspec.nil?
833
-
834
- @gemspec = if gemfile
835
- Gem::Specification.load(gemfile.to_s) rescue false
836
- else
837
- false
838
- end
839
- end
840
-
841
- def gemname
842
- @gemname ||= ((spec = gemspec) ? spec.name : project)
843
- end
844
-
845
788
  def depend?
846
789
  @depend != false && (!@depend.nil? || outdated?)
847
790
  end
848
791
 
849
792
  def copy?
850
- return true if @copy.is_a?(Hash) ? copy[:into] : super
793
+ return true if super || (@copy.is_a?(Hash) && copy.fetch(:into, nil))
851
794
  return gemdir? if @gemdir
852
795
 
853
- if version
796
+ if @version
854
797
  begin
855
798
  case @autodetect
856
799
  when 'rvm'
@@ -875,46 +818,43 @@ module Squared
875
818
  return false unless @autodetect
876
819
 
877
820
  set = lambda do |val, path|
878
- if (ver = version) && ver != val
879
- log.warn "using version #{val} (given #{ver})"
880
- end
881
- self.version = val
821
+ log.warn "using version #{val} (given #{@version})" if @version && @version != val
822
+ @version = val
882
823
  @gemdir = Pathname.new(path.strip) + gempath
883
824
  end
884
- if version
885
- opt = gempwd
886
- pwd_set(pass: !opt.nil?) do
887
- out = `#{gem_output(opt, 'list --local -d', gemname)}`
888
- if out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
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)} \(([^)]+)\)/
889
830
  $1.split(/\s*,\s*/)
890
- .unshift(@version)
831
+ .prepend(@version)
891
832
  .uniq
892
833
  .each do |val|
893
834
  next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
894
835
 
895
836
  set.call(val, $1)
896
- return gemdir? if @gemdir
837
+ break
897
838
  end
898
839
  end
899
840
  end
900
- @gemdir = Pathname.new(Gem.dir) + gempath
901
- else
841
+ end
842
+ unless @gemdir
902
843
  parse = lambda do |path|
903
844
  next unless path
904
845
 
905
- lib = Regexp.new(['', 'gems', "#{gemname}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
846
+ lib = Regexp.new(['', 'gems', "#{project}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
906
847
  if (ver = path[lib, 1]) && (val = path[/\A(.+)#{gempath(ver[1])}/, 1])
907
848
  set.call(ver, val)
908
849
  end
909
850
  end
910
851
  if RUBY_VERSION >= '2.6'
911
852
  target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
912
- parse.call(target.resolve_feature_path(gemname)&.last)
913
- end
914
- if !@gemdir && !pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
915
- raise_error 'gems directory not found'
853
+ parse.call(target.resolve_feature_path(project)&.last)
916
854
  end
855
+ pwd_set { parse.call(`#{bundle_output('show', project)}`) } unless @gemdir
917
856
  end
857
+ raise_error('parse failed', hint: @version || 'path') unless @gemdir
918
858
  rescue StandardError => e
919
859
  log.error e
920
860
  @version = nil
@@ -931,7 +871,7 @@ module Squared
931
871
  private
932
872
 
933
873
  def run_rb(**kwargs)
934
- run(banner: !@session&.include?('--quiet'), **kwargs)
874
+ run(banner: !@session.include?('--quiet'), **kwargs)
935
875
  end
936
876
 
937
877
  def append_bundle(opts, list, target: @session, append: nil)
@@ -951,7 +891,6 @@ module Squared
951
891
  else
952
892
  op.clear
953
893
  end
954
- op
955
894
  end
956
895
 
957
896
  def ruby_session(*cmd, **kwargs)
@@ -993,73 +932,54 @@ module Squared
993
932
  session_output('rake', *cmd, **kwargs)
994
933
  end
995
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
+
996
950
  def preopts
997
951
  verbosetype > 1 && !session_arg?('quiet') ? ['--verbose'] : []
998
952
  end
999
953
 
954
+ def gemdir?
955
+ !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
956
+ end
957
+
1000
958
  def variables
1001
- (super + %i[autodetect]).freeze
959
+ (super + %i[version autodetect]).freeze
1002
960
  end
1003
961
 
1004
962
  def rakefile
1005
- return @rakefile unless @rakefile.nil?
963
+ return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
1006
964
 
1007
- file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? }
1008
- @rakefile = file ? basepath(file) : false
965
+ path + file
1009
966
  end
1010
967
 
1011
968
  def rakepwd
1012
- return unless !pwd? && semgte?(Rake::VERSION, '13.0.4')
969
+ return unless Rake::VERSION >= '13.0.4'
1013
970
 
1014
971
  quote_option 'C', path
1015
972
  end
1016
973
 
1017
- def raketasks
1018
- @raketasks ||= [].tap do |ret|
1019
- opt = rakepwd
1020
- pwd_set(pass: !opt.nil?) do
1021
- IO.popen(rake_output(opt, '-AT').to_s).each do |line|
1022
- next unless line =~ /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/
1023
-
1024
- ret << [$1, $2]
1025
- end
1026
- end
1027
- end
1028
- end
1029
-
1030
974
  def gempwd
1031
- return unless !pwd? && semgte?(Gem::VERSION, '3.4.2')
975
+ return unless Gem::VERSION >= '3.4.2'
1032
976
 
1033
977
  quote_option 'C', path
1034
978
  end
1035
979
 
1036
- def gemfile
1037
- return @gemfile unless @gemfile.nil?
1038
-
1039
- @gemfile = [project, name].map! { |val| basepath("#{val}.gemspec") }
1040
- .concat(Dir.glob(basepath('*.gemspec')))
1041
- .find { |file| File.exist?(file) } || false
980
+ def gempath(val = @version)
981
+ File.join('gems', "#{project}-#{val}")
1042
982
  end
1043
-
1044
- def gemlib
1045
- @gemlib ||= begin
1046
- lib = Set.new(['lib'])
1047
- if (spec = gemspec)
1048
- lib.merge(spec.require_paths || [])
1049
- end
1050
- lib.select { |file| basepath(file).exist? }
1051
- end
1052
- end
1053
-
1054
- def gempath(val = version)
1055
- File.join('gems', "#{gemname}-#{val}")
1056
- end
1057
-
1058
- def gemdir?
1059
- !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
1060
- end
1061
-
1062
- alias read_rakefile raketasks
1063
983
  end
1064
984
 
1065
985
  Application.implement Ruby