squared 0.4.30 → 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,10 +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
- 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)
565
544
  op.each do |opt|
566
- 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)
567
551
  op.errors << opt
568
552
  else
569
553
  op.found << opt
@@ -572,18 +556,17 @@ module Squared
572
556
  op.swap
573
557
  case flag
574
558
  when :outdated
559
+ log.info cmd.to_s
575
560
  op.clear
576
- cmd = cmd.done
577
- log.info cmd
578
561
  on :first, from
579
- print_item format_banner(cmd)
562
+ print_item format_banner(cmd.to_s)
580
563
  major = 0
581
564
  minor = 0
582
565
  patch = 0
583
566
  update = []
584
- pwd_set(pass: !gempwd.nil?, from: from) do
567
+ pwd_set(pass: !pwd.nil?, from: from) do
585
568
  items = [[%w[Gem Current Latest], nil]]
586
- IO.popen(cmd).each do |line|
569
+ IO.popen(cmd.done).each do |line|
587
570
  if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
588
571
  cur = semscan $2
589
572
  lat = semscan $3
@@ -658,8 +641,7 @@ module Squared
658
641
  styles = %i[yellow]
659
642
  pat = pat.last
660
643
  end
661
- b = b.rjust(e)
662
- b = sub_style(b, *colormap(styles), pat: pat, index: 2)
644
+ b = sub_style(b.rjust(e), *colormap(styles), pat: pat, index: 2)
663
645
  h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
664
646
  j += 1
665
647
  if queue
@@ -677,15 +659,15 @@ module Squared
677
659
  else
678
660
  unless update.empty?
679
661
  cmd = gem_output 'update', '-f'
680
- if (val = option('document', prefix: 'gem', ignore: false))
662
+ option('document', prefix: 'gem', ignore: false) do |val|
681
663
  cmd << case val
682
664
  when '0', 'false'
683
665
  '--no-document'
684
666
  else
685
- basic_option('document', val)
667
+ basic_option 'document', val
686
668
  end
687
669
  end
688
- if (val = option('user-install', prefix: 'gem', ignore: false))
670
+ option('user-install', prefix: 'gem', ignore: false) do |val|
689
671
  cmd << case val
690
672
  when '0', 'false'
691
673
  '--no-user-install'
@@ -696,84 +678,58 @@ module Squared
696
678
  cmd.merge(update)
697
679
  run(cmd, banner: false, from: :'gem:update')
698
680
  end
699
- 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
700
692
  end
701
693
  on :last, from
702
694
  return
703
- when :build
704
- if op.empty?
705
- raise_error('gemspec not found', hint: project) unless gemfile
706
- op.add_path(gemfile)
707
- else
708
- op.add_path(op.shift)
709
- .clear(pass: false)
710
- end
711
- when :push
712
- if op.empty?
713
- file = basepath(if (spec = gemspec)
714
- "#{spec.name}-#{spec.version}.gem"
715
- else
716
- gems = Dir.glob(basepath('*.gem')).map { |val| File.basename(val) }
717
- choice_index('Select a file', gems, force: true)
718
- end)
719
- else
720
- file = op.shift
721
- 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) })
722
705
  end
723
- raise_error('gem not found', hint: file) unless op.exist?(file)
724
- op.add_path(file)
725
- run_rb(from: from, interactive: "Push #{sub_style(gemname, styles: theme[:active])}")
726
- return
727
706
  when :exec
728
- min = if op.arg?('g', 'gem')
729
- 1
730
- elsif op.empty?
731
- op << basic_option('gem', gemname)
732
- 1
733
- else
734
- op << op.shift
735
- 0
736
- end
737
- 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))
738
710
  op.push(args)
739
711
  end
740
- op.append(quote: false)
741
- when :update
742
- unless op.arg?('system')
743
- if op.empty?
744
- op << gemname
745
- else
746
- op.append
747
- end
748
- end
749
- op.clear(errors: true)
750
- when :install, :uninstall, :pristine
751
- raise_error('missing gemname', hint: flag) if op.empty?
752
- if op.arg?('all')
753
- 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')
754
717
  append_repeat 'skip', op.extras
755
- op.reset
756
- 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)
757
729
  op.clear
758
730
  end
759
- elsif (n = op.index { |val| val.match?(/(\A|[a-z])@\d/) })
760
- name = op.delete_at(n)
761
- pre, ver = if (n = name.index('@')) == 0
762
- [gemname, name[1..-1]]
763
- else
764
- [name[0, n], name[(n + 1)..-1]]
765
- end
766
- op.adjoin(pre, shell_option('version', ver))
767
- .clear
768
- elsif flag == :install
769
- op.append_any
770
- else
771
- op.append
772
731
  end
773
- op.clear(errors: true)
774
- op << '--' << readline('Enter command [args]', force: true) if flag == :install && op.remove(':')
775
- else
776
- op.append
732
+ op.append.clear(errors: true)
777
733
  end
778
734
  run_rb(from: from)
779
735
  end
@@ -783,24 +739,26 @@ module Squared
783
739
  args = case flag
784
740
  when 'exec', 'cache', 'check'
785
741
  list = OPT_BUNDLE[flag.to_sym] + OPT_BUNDLE[:common]
786
- OptionPartition.new(args, list, cmd, project: self, args: flag == 'exec').extras
742
+ OptionPartition.new(args, list, cmd, project: self, args: flag == :exec).extras
787
743
  else
788
744
  args.flatten
789
745
  end
790
746
  case flag
791
747
  when 'exec', 'config'
792
- cmd << readline('Enter arguments', force: true) if args.empty?
793
- 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
794
755
  option_clear args
795
- args.clear
796
756
  end
797
- cmd.merge(args)
798
757
  run(from: :"bundle:#{flag}")
799
758
  end
800
759
 
801
760
  def rake(*args, opts: [])
802
- op = OptionPartition.new(opts, OPT_RUBY[:rake], [(quote_option('f', rakefile) if rakefile)].compact,
803
- project: self)
761
+ op = OptionPartition.new(opts, OPT_RUBY[:rake], [quote_option('f', rakefile)], project: self)
804
762
  args.concat(op.extras)
805
763
  if args.empty?
806
764
  args << nil
@@ -812,14 +770,14 @@ module Squared
812
770
  run_s(args, banner: false, from: :rake)
813
771
  end
814
772
 
815
- def irb(name = nil, opts = [], path: gemlib, args: nil)
773
+ def irb(name, opts = [], path: @path + 'lib', load: nil)
816
774
  op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
817
- r = args ? [] : ['bundler/setup']
818
- r << name if name
775
+ r = as_a name
776
+ r.prepend('bundler/setup') unless load
819
777
  r.each { |val| op << shell_option('r', val, merge: true) }
820
- Array(path).each { |val| op << quote_option('I', val, merge: true) }
821
- if args
822
- op << '--' << args
778
+ as_a(path).each { |val| op << quote_option('I', val, merge: true) }
779
+ if load
780
+ op << '--' << load
823
781
  op.clear
824
782
  else
825
783
  op.append(delim: true)
@@ -827,29 +785,15 @@ module Squared
827
785
  run(banner: false)
828
786
  end
829
787
 
830
- def gemspec
831
- return @gemspec unless @gemspec.nil?
832
-
833
- @gemspec = if gemfile
834
- Gem::Specification.load(gemfile.to_s) rescue false
835
- else
836
- false
837
- end
838
- end
839
-
840
- def gemname
841
- @gemname ||= ((spec = gemspec) ? spec.name : project)
842
- end
843
-
844
788
  def depend?
845
789
  @depend != false && (!@depend.nil? || outdated?)
846
790
  end
847
791
 
848
792
  def copy?
849
- return true if @copy.is_a?(Hash) ? copy[:into] : super
793
+ return true if super || (@copy.is_a?(Hash) && copy.fetch(:into, nil))
850
794
  return gemdir? if @gemdir
851
795
 
852
- if version
796
+ if @version
853
797
  begin
854
798
  case @autodetect
855
799
  when 'rvm'
@@ -874,46 +818,43 @@ module Squared
874
818
  return false unless @autodetect
875
819
 
876
820
  set = lambda do |val, path|
877
- if (ver = version) && ver != val
878
- log.warn "using version #{val} (given #{ver})"
879
- end
880
- self.version = val
821
+ log.warn "using version #{val} (given #{@version})" if @version && @version != val
822
+ @version = val
881
823
  @gemdir = Pathname.new(path.strip) + gempath
882
824
  end
883
- if version
884
- opt = gempwd
885
- pwd_set(pass: !opt.nil?) do
886
- out = `#{gem_output(opt, 'list --local -d', gemname)}`
887
- if out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
888
- split_escape($1)
889
- .unshift(@version)
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)
890
832
  .uniq
891
833
  .each do |val|
892
834
  next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
893
835
 
894
836
  set.call(val, $1)
895
- return gemdir? if @gemdir
837
+ break
896
838
  end
897
839
  end
898
840
  end
899
- @gemdir = Pathname.new(Gem.dir) + gempath
900
- else
841
+ end
842
+ unless @gemdir
901
843
  parse = lambda do |path|
902
844
  next unless path
903
845
 
904
- lib = Regexp.new(['', 'gems', "#{gemname}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
846
+ lib = Regexp.new(['', 'gems', "#{project}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
905
847
  if (ver = path[lib, 1]) && (val = path[/\A(.+)#{gempath(ver[1])}/, 1])
906
848
  set.call(ver, val)
907
849
  end
908
850
  end
909
851
  if RUBY_VERSION >= '2.6'
910
852
  target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
911
- parse.call(target.resolve_feature_path(gemname)&.last)
912
- end
913
- if !@gemdir && !pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
914
- raise_error 'gems directory not found'
853
+ parse.call(target.resolve_feature_path(project)&.last)
915
854
  end
855
+ pwd_set { parse.call(`#{bundle_output('show', project)}`) } unless @gemdir
916
856
  end
857
+ raise_error('parse failed', hint: @version || 'path') unless @gemdir
917
858
  rescue StandardError => e
918
859
  log.error e
919
860
  @version = nil
@@ -930,7 +871,7 @@ module Squared
930
871
  private
931
872
 
932
873
  def run_rb(**kwargs)
933
- run(banner: !@session&.include?('--quiet'), **kwargs)
874
+ run(banner: !@session.include?('--quiet'), **kwargs)
934
875
  end
935
876
 
936
877
  def append_bundle(opts, list, target: @session, append: nil)
@@ -950,7 +891,6 @@ module Squared
950
891
  else
951
892
  op.clear
952
893
  end
953
- op
954
894
  end
955
895
 
956
896
  def ruby_session(*cmd, **kwargs)
@@ -958,11 +898,18 @@ module Squared
958
898
  end
959
899
 
960
900
  def gem_session(*cmd, **kwargs)
961
- session('gem', *cmd, *preopts, **kwargs)
901
+ ret = session('gem', *cmd, **kwargs)
902
+ return ret if cmd.empty?
903
+
904
+ ret.merge(preopts)
962
905
  end
963
906
 
964
907
  def bundle_session(*cmd, **kwargs)
965
- 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)
966
913
  end
967
914
 
968
915
  def rake_session(*cmd, **kwargs)
@@ -985,75 +932,54 @@ module Squared
985
932
  session_output('rake', *cmd, **kwargs)
986
933
  end
987
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
+
988
950
  def preopts
989
- verbosetype > 1 ? ['--verbose'] : []
951
+ verbosetype > 1 && !session_arg?('quiet') ? ['--verbose'] : []
952
+ end
953
+
954
+ def gemdir?
955
+ !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
990
956
  end
991
957
 
992
958
  def variables
993
- (super + %i[autodetect]).freeze
959
+ (super + %i[version autodetect]).freeze
994
960
  end
995
961
 
996
962
  def rakefile
997
- return @rakefile unless @rakefile.nil?
963
+ return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
998
964
 
999
- file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? }
1000
- @rakefile = file ? basepath(file) : false
965
+ path + file
1001
966
  end
1002
967
 
1003
968
  def rakepwd
1004
- return unless !pwd? && semgte?(Rake::VERSION, '13.0.4')
969
+ return unless Rake::VERSION >= '13.0.4'
1005
970
 
1006
971
  quote_option 'C', path
1007
972
  end
1008
973
 
1009
- def raketasks
1010
- @raketasks ||= [].tap do |ret|
1011
- opt = rakepwd
1012
- pwd_set(pass: !opt.nil?) do
1013
- IO.popen(rake_output(opt, '-AT').to_s).each do |line|
1014
- next unless line =~ /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/
1015
-
1016
- ret << [$1, $2]
1017
- end
1018
- end
1019
- end
1020
- end
1021
-
1022
974
  def gempwd
1023
- return unless !pwd? && semgte?(Gem::VERSION, '3.4.2')
975
+ return unless Gem::VERSION >= '3.4.2'
1024
976
 
1025
977
  quote_option 'C', path
1026
978
  end
1027
979
 
1028
- def gemfile
1029
- return @gemfile unless @gemfile.nil?
1030
-
1031
- @gemfile = [project, name].map! { |val| basepath("#{val}.gemspec") }
1032
- .concat(Dir.glob(basepath('*.gemspec')))
1033
- .find { |file| File.exist?(file) } || false
1034
- end
1035
-
1036
- def gemlib
1037
- @gemlib ||= begin
1038
- lib = Set.new(['lib'])
1039
- if (spec = gemspec)
1040
- lib.merge(spec.require_paths || [])
1041
- end
1042
- lib.select { |file| basepath(file).exist? }
1043
- end
1044
- end
1045
-
1046
- def gempath(val = version)
1047
- File.join('gems', "#{gemname}-#{val}")
980
+ def gempath(val = @version)
981
+ File.join('gems', "#{project}-#{val}")
1048
982
  end
1049
-
1050
- def gemdir?
1051
- return false unless @gemdir
1052
-
1053
- @gemdir.exist? && !@gemdir.empty?
1054
- end
1055
-
1056
- alias read_rakefile raketasks
1057
983
  end
1058
984
 
1059
985
  Application.implement Ruby