squared 0.4.37 → 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,27 +464,25 @@ 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')}`
510
473
  when 'install'
511
474
  ver = '.tool-versions'
512
- exit 1 unless (cur = `asdf current ruby`[/ruby\s+\S+/, 0])
513
- cur.sub(/\s+/, ' ')
475
+ `asdf current ruby`[/ruby\s+\S+/, 0].sub(/\s+/, ' ')
514
476
  else
515
477
  ver = nil
516
478
  `ruby --version`
517
479
  end)
518
- break if workspace.windows?
519
-
520
480
  unless val.empty?
521
481
  out << trim.call(case cmd
522
482
  when 'chruby.sh'
523
483
  `#{chruby.with('chruby --version')}`.sub(':', '')
524
484
  when 'install'
525
- "asdf #{`asdf version`.sub(/^v/, '')}"
485
+ "asdf #{`asdf version`.delete_prefix('v')}"
526
486
  else
527
487
  `#{cmd} --version`
528
488
  end)
@@ -557,14 +517,16 @@ module Squared
557
517
  end
558
518
  return
559
519
  end
560
- run_rb(banner: false, from: :"ruby:#{flag}")
520
+ run_rb(banner: op.arg?('v'), from: :"ruby:#{flag}")
561
521
  end
562
522
 
563
523
  def gem!(flag, opts = [], filter: nil)
564
524
  cmd = gem_session
565
525
  case flag
566
526
  when :outdated
567
- cmd << gempwd << flag
527
+ cmd << gempwd << 'outdated'
528
+ when :push
529
+ cmd << 'push' << project
568
530
  else
569
531
  cmd << flag
570
532
  end
@@ -573,10 +535,19 @@ module Squared
573
535
  case flag
574
536
  when :install, :update
575
537
  list.concat(OPT_GEM[:install_base])
538
+ first = ['=']
539
+ when :uninstall, :pristine
540
+ first = ['=']
576
541
  end
577
- 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)
578
544
  op.each do |opt|
579
- 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)
580
551
  op.errors << opt
581
552
  else
582
553
  op.found << opt
@@ -585,18 +556,17 @@ module Squared
585
556
  op.swap
586
557
  case flag
587
558
  when :outdated
559
+ log.info cmd.to_s
588
560
  op.clear
589
- cmd = cmd.done
590
- log.info cmd
591
561
  on :first, from
592
- print_item format_banner(cmd)
562
+ print_item format_banner(cmd.to_s)
593
563
  major = 0
594
564
  minor = 0
595
565
  patch = 0
596
566
  update = []
597
- pwd_set(pass: !gempwd.nil?, from: from) do
567
+ pwd_set(pass: !pwd.nil?, from: from) do
598
568
  items = [[%w[Gem Current Latest], nil]]
599
- IO.popen(cmd).each do |line|
569
+ IO.popen(cmd.done).each do |line|
600
570
  if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
601
571
  cur = semscan $2
602
572
  lat = semscan $3
@@ -671,8 +641,7 @@ module Squared
671
641
  styles = %i[yellow]
672
642
  pat = pat.last
673
643
  end
674
- b = b.rjust(e)
675
- b = sub_style(b, *colormap(styles), pat: pat, index: 2)
644
+ b = sub_style(b.rjust(e), *colormap(styles), pat: pat, index: 2)
676
645
  h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
677
646
  j += 1
678
647
  if queue
@@ -690,15 +659,15 @@ module Squared
690
659
  else
691
660
  unless update.empty?
692
661
  cmd = gem_output 'update', '-f'
693
- if (val = option('document', prefix: 'gem', ignore: false))
662
+ option('document', prefix: 'gem', ignore: false) do |val|
694
663
  cmd << case val
695
664
  when '0', 'false'
696
665
  '--no-document'
697
666
  else
698
- basic_option('document', val)
667
+ basic_option 'document', val
699
668
  end
700
669
  end
701
- if (val = option('user-install', prefix: 'gem', ignore: false))
670
+ option('user-install', prefix: 'gem', ignore: false) do |val|
702
671
  cmd << case val
703
672
  when '0', 'false'
704
673
  '--no-user-install'
@@ -709,84 +678,58 @@ module Squared
709
678
  cmd.merge(update)
710
679
  run(cmd, banner: false, from: :'gem:update')
711
680
  end
712
- 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
713
692
  end
714
693
  on :last, from
715
694
  return
716
- when :build
717
- if op.empty?
718
- raise_error('gemspec not found', hint: project) unless gemfile
719
- op.add_path(gemfile)
720
- else
721
- op.add_path(op.shift)
722
- .clear(pass: false)
723
- end
724
- when :push
725
- if op.empty?
726
- file = basepath(if (spec = gemspec)
727
- "#{spec.name}-#{spec.version}.gem"
728
- else
729
- gems = Dir.glob(basepath('*.gem')).map { |val| File.basename(val) }
730
- choice_index 'Select a file', gems
731
- end)
732
- else
733
- file = op.shift
734
- 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) })
735
705
  end
736
- raise_error('gem not found', hint: file) unless op.exist?(file)
737
- op.add_path(file)
738
- run_rb(from: from, interactive: "Push #{sub_style(gemname, styles: theme[:active])}")
739
- return
740
706
  when :exec
741
- min = if op.arg?('g', 'gem')
742
- 1
743
- elsif op.empty?
744
- op << basic_option('gem', gemname)
745
- 1
746
- else
747
- op << op.shift
748
- 0
749
- end
750
- 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))
751
710
  op.push(args)
752
711
  end
753
- op.append(quote: false)
754
- when :update
755
- unless op.arg?('system')
756
- if op.empty?
757
- op << gemname
758
- else
759
- op.append
760
- end
761
- end
762
- op.clear(errors: true)
763
- when :install, :uninstall, :pristine
764
- raise_error('missing gemname', hint: flag) if op.empty?
765
- if op.arg?('all')
766
- 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')
767
717
  append_repeat 'skip', op.extras
768
- op.reset
769
- 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)
770
729
  op.clear
771
730
  end
772
- elsif (n = op.index { |val| val.match?(/(\A|[\w.-])@\d/) })
773
- name = op.delete_at(n)
774
- pre, ver = if (n = name.index('@')) == 0
775
- [gemname, name[1..-1]]
776
- else
777
- [name[0, n], name[(n + 1)..-1]]
778
- end
779
- op.adjoin(pre, basic_option('version', ver))
780
- .clear
781
- elsif flag == :install
782
- op.append_any
783
- else
784
- op.append
785
731
  end
786
- op.clear(errors: true)
787
- op << '--' << readline('Enter command [args]', force: true) if flag == :install && op.remove(':')
788
- else
789
- op.append
732
+ op.append.clear(errors: true)
790
733
  end
791
734
  run_rb(from: from)
792
735
  end
@@ -796,24 +739,26 @@ module Squared
796
739
  args = case flag
797
740
  when 'exec', 'cache', 'check'
798
741
  list = OPT_BUNDLE[flag.to_sym] + OPT_BUNDLE[:common]
799
- OptionPartition.new(args, list, cmd, project: self, args: flag == 'exec').extras
742
+ OptionPartition.new(args, list, cmd, project: self, args: flag == :exec).extras
800
743
  else
801
744
  args.flatten
802
745
  end
803
746
  case flag
804
747
  when 'exec', 'config'
805
- cmd << readline('Enter arguments', force: true) if args.empty?
806
- 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
807
755
  option_clear args
808
- args.clear
809
756
  end
810
- cmd.merge(args)
811
757
  run(from: :"bundle:#{flag}")
812
758
  end
813
759
 
814
760
  def rake(*args, opts: [])
815
- op = OptionPartition.new(opts, OPT_RUBY[:rake], [(quote_option('f', rakefile) if rakefile)].compact,
816
- project: self)
761
+ op = OptionPartition.new(opts, OPT_RUBY[:rake], [quote_option('f', rakefile)], project: self)
817
762
  args.concat(op.extras)
818
763
  if args.empty?
819
764
  args << nil
@@ -825,14 +770,14 @@ module Squared
825
770
  run_s(args, banner: false, from: :rake)
826
771
  end
827
772
 
828
- def irb(name = nil, opts = [], path: gemlib, args: nil)
773
+ def irb(name, opts = [], path: @path + 'lib', load: nil)
829
774
  op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
830
- r = args ? [] : ['bundler/setup']
831
- r << name if name
775
+ r = as_a name
776
+ r.prepend('bundler/setup') unless load
832
777
  r.each { |val| op << shell_option('r', val, merge: true) }
833
- Array(path).each { |val| op << quote_option('I', val, merge: true) }
834
- if args
835
- op << '--' << args
778
+ as_a(path).each { |val| op << quote_option('I', val, merge: true) }
779
+ if load
780
+ op << '--' << load
836
781
  op.clear
837
782
  else
838
783
  op.append(delim: true)
@@ -840,85 +785,76 @@ module Squared
840
785
  run(banner: false)
841
786
  end
842
787
 
843
- def gemspec
844
- @gemspec = !gemfile.nil? && Gem::Specification.load(gemfile.to_s) rescue false if @gemspec.nil?
845
- @gemspec || nil
846
- end
847
-
848
- def gemname
849
- @gemname ||= ((spec = gemspec) ? spec.name : project)
850
- end
851
-
852
788
  def depend?
853
789
  @depend != false && (!@depend.nil? || outdated?)
854
790
  end
855
791
 
856
792
  def copy?
857
- return true if @copy.is_a?(Hash) ? copy[:into] : super
858
- return gemdir? if gemdir
859
- return false unless @autodetect
860
-
861
- set = lambda do |val, path|
862
- base = Pathname.new(path.strip)
863
- 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
864
795
 
865
- log.warn "using version #{val} (given #{version})" if version && version != val
866
- self.version = val
867
- self.gemdir = base + gempath
868
- end
869
- if version
796
+ if @version
870
797
  begin
871
798
  case @autodetect
872
799
  when 'rvm'
873
- self.gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
800
+ @gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
874
801
  when 'rbenv'
875
802
  if pwd_set { `rbenv which ruby` } =~ %r{^(.+[\\/]versions[\\/](\d\.\d)\.[^\\/]+)[\\/]bin[\\/]ruby$}
876
- self.gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
803
+ @gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
877
804
  end
878
805
  when 'asdf'
879
- val = pwd_set { `asdf where ruby`.chomp }
880
- 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")
881
808
  when /bundler?/
882
- path = pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1]
883
- self.gemdir = path.split(File::PATH_SEPARATOR).find { |val| Dir.exist?(val) }
884
- else
885
- self.gemdir = ENV['GEM_HOME'] || ENV['GEM_ROOT']
809
+ @gemdir = pwd_set { `bundle env` }[/^\s+Gem Home\s+(.+)$/, 1]
886
810
  end
887
- return true if gemdir?
888
811
  rescue StandardError => e
889
812
  log.debug e
813
+ else
814
+ @gemdir = Pathname.new(@gemdir) if @gemdir
890
815
  end
891
- pwd_set(pass: !gempwd.nil?) do
892
- out = `#{gem_output(gempwd, 'list --local -d', gemname)}`
893
- if out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
894
- split_escape($1)
895
- .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)
896
832
  .uniq
897
833
  .each do |val|
898
- next unless out =~ /(?:\(#{Regexp.escape(val)}[^)]*\)|Installed at):\s+(.+)$/
834
+ next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
899
835
 
900
- return gemdir? if set.call(val, $1)
836
+ set.call(val, $1)
837
+ break
901
838
  end
902
839
  end
903
840
  end
904
- self.gemdir = Pathname.new(Gem.dir) + gempath
905
- else
841
+ end
842
+ unless @gemdir
906
843
  parse = lambda do |path|
907
844
  next unless path
908
845
 
909
- lib = Regexp.new(['', 'gems', "#{gemname}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
910
- 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])
911
848
  set.call(ver, val)
912
849
  end
913
850
  end
914
851
  if RUBY_VERSION >= '2.6'
915
852
  target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
916
- parse.call(target.resolve_feature_path(gemname)&.last)
917
- end
918
- if !gemdir && !pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
919
- raise_error 'gems directory not found'
853
+ parse.call(target.resolve_feature_path(project)&.last)
920
854
  end
855
+ pwd_set { parse.call(`#{bundle_output('show', project)}`) } unless @gemdir
921
856
  end
857
+ raise_error('parse failed', hint: @version || 'path') unless @gemdir
922
858
  rescue StandardError => e
923
859
  log.error e
924
860
  @version = nil
@@ -929,13 +865,13 @@ module Squared
929
865
  end
930
866
 
931
867
  def outdated?
932
- dependtype > 0 && !task_pass?('outdated')
868
+ dependtype > 0
933
869
  end
934
870
 
935
871
  private
936
872
 
937
873
  def run_rb(**kwargs)
938
- run(banner: !@session&.include?('--quiet'), **kwargs)
874
+ run(banner: !@session.include?('--quiet'), **kwargs)
939
875
  end
940
876
 
941
877
  def append_bundle(opts, list, target: @session, append: nil)
@@ -955,7 +891,6 @@ module Squared
955
891
  else
956
892
  op.clear
957
893
  end
958
- op
959
894
  end
960
895
 
961
896
  def ruby_session(*cmd, **kwargs)
@@ -963,11 +898,18 @@ module Squared
963
898
  end
964
899
 
965
900
  def gem_session(*cmd, **kwargs)
966
- session('gem', *cmd, *preopts, **kwargs)
901
+ ret = session('gem', *cmd, **kwargs)
902
+ return ret if cmd.empty?
903
+
904
+ ret.merge(preopts)
967
905
  end
968
906
 
969
907
  def bundle_session(*cmd, **kwargs)
970
- 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)
971
913
  end
972
914
 
973
915
  def rake_session(*cmd, **kwargs)
@@ -990,79 +932,54 @@ module Squared
990
932
  session_output('rake', *cmd, **kwargs)
991
933
  end
992
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
+
993
950
  def preopts
994
- verbosetype > 1 ? ['--verbose'] : []
951
+ verbosetype > 1 && !session_arg?('quiet') ? ['--verbose'] : []
952
+ end
953
+
954
+ def gemdir?
955
+ !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
995
956
  end
996
957
 
997
958
  def variables
998
- (super + %i[autodetect]).freeze
959
+ (super + %i[version autodetect]).freeze
999
960
  end
1000
961
 
1001
962
  def rakefile
1002
- if @rakefile.nil?
1003
- file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? }
1004
- @rakefile = !file.nil? && basepath(file)
1005
- end
1006
- @rakefile || nil
963
+ return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
964
+
965
+ path + file
1007
966
  end
1008
967
 
1009
968
  def rakepwd
1010
- return unless !pwd? && semgte?(Rake::VERSION, '13.0.4')
969
+ return unless Rake::VERSION >= '13.0.4'
1011
970
 
1012
971
  quote_option 'C', path
1013
972
  end
1014
973
 
1015
- def raketasks
1016
- @raketasks ||= [].tap do |ret|
1017
- opt = rakepwd
1018
- pwd_set(pass: !opt.nil?) do
1019
- IO.popen(rake_output(opt, '-AT').to_s).each do |line|
1020
- next unless line =~ /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/
1021
-
1022
- ret << [$1, $2]
1023
- end
1024
- end
1025
- end
1026
- end
1027
-
1028
974
  def gempwd
1029
- return unless !pwd? && semgte?(Gem::VERSION, '3.4.2')
975
+ return unless Gem::VERSION >= '3.4.2'
1030
976
 
1031
977
  quote_option 'C', path
1032
978
  end
1033
979
 
1034
- def gemfile
1035
- if @gemfile.nil?
1036
- @gemfile = [project, name].map! { |val| basepath("#{val}.gemspec") }
1037
- .concat(Dir.glob(basepath('*.gemspec')))
1038
- .find { |file| File.exist?(file) } || false
1039
- end
1040
- @gemfile || nil
980
+ def gempath(val = @version)
981
+ File.join('gems', "#{project}-#{val}")
1041
982
  end
1042
-
1043
- def gemlib
1044
- @gemlib ||= begin
1045
- lib = Set.new(['lib'])
1046
- if (spec = gemspec)
1047
- lib.merge(spec.require_paths || [])
1048
- end
1049
- lib.select { |file| basepath(file).exist? }
1050
- end
1051
- end
1052
-
1053
- def gempath(val = version, dir = 'gems')
1054
- ret = File.join(dir, "#{gemname}-#{val}")
1055
- ret += '.gemspec' if dir == 'specifications'
1056
- ret
1057
- end
1058
-
1059
- def gemdir?
1060
- return false unless gemdir
1061
-
1062
- gemdir.exist? && !gemdir.empty?
1063
- end
1064
-
1065
- alias read_rakefile raketasks
1066
983
  end
1067
984
 
1068
985
  Application.implement Ruby