squared 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,44 +4,61 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Ruby < Git
7
- VAR_SET = %i[version autodetect].freeze
8
7
  GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
9
- RUBY_DIR = (GEMFILE + Rake::Application::DEFAULT_RAKEFILES + ['README.rdoc']).freeze
10
- OPT_INSTALL = %w[system frozen no-cache no-prune].freeze
11
- OPT_UPDATE = %w[all redownload conservative local strict group=s].freeze
12
- OPT_OUTDATED = %w[pre only-explicit local strict group=s].freeze
13
- private_constant :VAR_SET, :GEMFILE, :RUBY_DIR, :OPT_INSTALL, :OPT_UPDATE, :OPT_OUTDATED
8
+ DIR_RUBY = (GEMFILE + Rake::Application::DEFAULT_RAKEFILES + ['README.rdoc']).freeze
9
+ FOR_INSTALL = %w[full-index quiet retry gemfile=s j=i jobs=i retry=i].freeze
10
+ OPT_INSTALL = %w[binstubs frozen system no-cache no-prune path=s binstubs=? standalone=? target-rbconfig=s
11
+ trust-policy=s with=s without=s].freeze
12
+ OPT_UPDATE = %w[conservative local pre redownload ruby strict bundler=? g=s group=s source=s].freeze
13
+ OPT_OUTDATED = %w[filter-major filter-minor filter-patch groups local parseable pre only-explicit strict
14
+ update-strict g=s group=s source=s].freeze
15
+ OPT_GEM = {
16
+ COMMON: %w[V backtrace debug q quiet norc silent verbose no-verbose config-file=s].freeze,
17
+ INSTALL: ['version=s'].freeze,
18
+ UPDATE: ['system=?'].freeze,
19
+ OUTDATED: %w[b both clear-sources l local no-http-proxy r remote B bulk-threshold=i p=s http-proxy=?
20
+ platform=s source=s].freeze,
21
+ PRISTINE: %w[all env-shebang no-env-shebang extensions no-extensions only-missing-extensions only-executables
22
+ only-plugins n=s bindir=s i=s install-dir=s skip=s v=s version=s].freeze,
23
+ NO_GENERAL: %w[env-shebang force format-executable http-proxy lock minimal-deps post-install-message
24
+ prerelease suggestions user-install wrappers].freeze,
25
+ GENERAL: %w[f g w b both clear-sources conservative document=? default development development-all E explain
26
+ ignore-dependencies l local N no-document r remote vendor n=s bindir=s build-root=s
27
+ bulk-threshold=i document=s g=s file=? p=s http-proxy=s i=s install-dir=s platform=s s=s source=s
28
+ target-rbconfig=? P=s trust-policy=s without=s].freeze
29
+ }.freeze
30
+ private_constant :GEMFILE, :DIR_RUBY, :FOR_INSTALL, :OPT_INSTALL, :OPT_UPDATE, :OPT_OUTDATED, :OPT_GEM
14
31
 
15
32
  class << self
16
33
  def populate(*); end
17
34
  def batchargs(*); end
18
35
 
19
36
  def tasks
20
- %i[outdated].freeze
37
+ [:outdated].freeze
21
38
  end
22
39
 
23
40
  def bannerargs
24
- %i[dependfile].freeze
41
+ [:dependfile].freeze
25
42
  end
26
43
 
27
44
  def config?(val)
28
45
  return false unless (val = as_path(val))
29
46
 
30
- RUBY_DIR.any? { |file| val.join(file).exist? }
47
+ DIR_RUBY.any? { |file| val.join(file).exist? }
31
48
  end
32
49
  end
33
50
 
34
51
  @@tasks[ref] = {
35
- install: %i[redownload local prefer-local gem with without].freeze,
36
- update: %i[all patch minor major].freeze,
37
- outdated: %i[patch minor major].freeze,
38
- pristine: %i[gem all version].freeze,
39
- exec: nil,
40
- config: nil,
41
- rake: nil
52
+ 'install' => %i[redownload local prefer-local].freeze,
53
+ 'update' => %i[patch minor major all].freeze,
54
+ 'outdated' => %i[patch minor major].freeze,
55
+ 'gem' => %i[install user-install update outdated pristine].freeze,
56
+ 'exec' => nil,
57
+ 'config' => nil,
58
+ 'rake' => nil
42
59
  }.freeze
43
60
 
44
- def initialize(*, version: nil, autodetect: false, **kwargs)
61
+ def initialize(*, autodetect: false, **kwargs)
45
62
  super
46
63
  if @pass.include?(Ruby.ref)
47
64
  initialize_ref(Ruby.ref)
@@ -50,7 +67,6 @@ module Squared
50
67
  initialize_build(Ruby.ref, **kwargs)
51
68
  initialize_env(**kwargs)
52
69
  end
53
- @version = env('BUILD', version, suffix: 'VERSION')
54
70
  @autodetect = autodetect
55
71
  @dependindex = GEMFILE.index { |file| basepath(file).exist? }
56
72
  @dependfile = basepath(GEMFILE[@dependindex || 0])
@@ -60,9 +76,10 @@ module Squared
60
76
  File.foreach(file) do |line|
61
77
  next unless line =~ %r{\brequire\s+(["'])bundler/gem_tasks\1}
62
78
 
63
- @output[0] = 'bundle exec rake build'
64
- @copy = 'bundle exec rake install'
65
- @clean = 'bundle exec rake clean' if @clean.nil?
79
+ cmd = bundle_output('exec', 'rake').to_s
80
+ @output[0] = "#{cmd} build"
81
+ @copy = "#{cmd} install"
82
+ @clean = "#{cmd} clean" if @clean.nil?
66
83
  break
67
84
  end
68
85
  rescue StandardError => e
@@ -74,23 +91,26 @@ module Squared
74
91
  Ruby.ref
75
92
  end
76
93
 
77
- def populate(*)
94
+ def populate(*, **)
78
95
  super
79
96
  return unless outdated? && ref?(Ruby.ref)
80
97
 
81
98
  namespace name do
82
99
  @@tasks[Ruby.ref].each do |action, flags|
100
+ next if @pass.include?(action)
101
+
83
102
  if flags.nil?
84
103
  case action
85
- when :exec, :config
86
- desc format_desc(action, nil, 'command+')
87
- task action, [:command] do |_, args|
88
- bundle(action, args.to_a)
104
+ when 'exec', 'config'
105
+ format_desc action, nil, 'command+'
106
+ task action do |_, args|
107
+ args = param_guard('bundle', action, args: args.to_a)
108
+ bundle(action, *args)
89
109
  end
90
- when :rake
110
+ when 'rake'
91
111
  next unless rakefile
92
112
 
93
- desc format_desc(action, nil, 'command*|^index,args*|#,pattern*')
113
+ format_desc action, nil, 'command*|^index,args*|#,pattern*'
94
114
  task action, [:command] do |_, args|
95
115
  if args.command == '#'
96
116
  format_list(read_rakefile, 'rake[^N]', 'tasks', grep: args.extras, from: rakefile.to_s,
@@ -116,49 +136,33 @@ module Squared
116
136
  namespace action do
117
137
  flags.each do |flag|
118
138
  case action
119
- when :install
120
- case flag
121
- when :gem
122
- desc format_desc(action, flag, 'name+')
123
- task flag, [:name] do |_, args|
124
- opts = guard_params(action, flag, args: args.to_a)
125
- depend(flag, opts: opts)
126
- end
127
- when :with, :without
128
- desc format_desc(action, flag, 'group+')
129
- task flag, [:group] do |_, args|
130
- opts = guard_params(action, flag, args: args.to_a)
131
- depend(flag, opts: opts)
132
- end
133
- else
134
- desc format_desc(action, flag, OPT_INSTALL)
135
- task flag, [:opts] do |_, args|
136
- depend(flag, opts: args.to_a)
137
- end
139
+ when 'install'
140
+ format_desc(action, flag, FOR_INSTALL + OPT_INSTALL) if @@task_desc
141
+ task flag do |_, args|
142
+ depend(flag, opts: args.to_a)
143
+ end
144
+ when 'update', 'outdated'
145
+ if @@task_desc
146
+ format_desc(action, flag, action == 'update' ? FOR_INSTALL + OPT_UPDATE : OPT_OUTDATED)
138
147
  end
139
- when :update, :outdated
140
- desc format_desc(action, flag, action == :update ? OPT_UPDATE : OPT_OUTDATED)
141
- task flag, [:opts] do |_, args|
148
+ task flag do |_, args|
142
149
  __send__(action, flag, opts: args.to_a)
143
150
  end
144
- when :pristine
151
+ when 'gem'
145
152
  case flag
146
- when :gem
147
- desc format_desc(action, flag, 'name+')
148
- task flag, [:name] do |_, args|
149
- opts = guard_params(action, flag, args: args.to_a)
150
- pristine(flag, opts: opts)
153
+ when :outdated
154
+ format_desc action, flag, gemoption(flag) if @@task_desc
155
+ task flag do |_, args|
156
+ gemx(flag, opts: args.to_a)
151
157
  end
152
- when :all
153
- desc format_desc(action, flag, 'skip*')
154
- task flag, [:skip] do |_, args|
155
- pristine(flag, opts: args.to_a)
158
+ else
159
+ if @@task_desc
160
+ format_desc(action, flag, gemoption(flag),
161
+ after: "name+#{flag == :pristine ? '|name?@version' : ''}")
156
162
  end
157
- when :version
158
- desc format_desc(action, flag, 'version?')
159
- task flag, [:version] do |_, args|
160
- version = guard_params(action, flag, args: args, key: :version)
161
- pristine(flag, version: version)
163
+ task flag, [:name] do |_, args|
164
+ opts = param_guard(action, flag, args: args.to_a)
165
+ gemx(flag, opts: opts)
162
166
  end
163
167
  end
164
168
  end
@@ -173,37 +177,18 @@ module Squared
173
177
  if @depend && !flag
174
178
  super
175
179
  elsif outdated?
176
- case flag
177
- when :gem
178
- gem_session 'install'
179
- append_value opts
180
- when :with, :without
181
- bundle_session 'install'
182
- append_repeat flag, opts
183
- when :redownload, :local, :'prefer-local'
184
- cmd = bundle_session 'install', "--#{flag}"
185
- if (val = option('trust-policy', ignore: false))
186
- cmd << shell_option('trust-policy', case val
187
- when '0'
188
- 'NoSecurity'
189
- when '1'
190
- 'AlmostNoSecurity'
191
- when '2'
192
- 'LowSecurity'
193
- when '3'
194
- 'MediumSecurity'
195
- when '4'
196
- 'HighSecurity'
197
- else
198
- val
199
- end, escape: false)
200
- end
201
- append_bundle opts, OPT_INSTALL
180
+ cmd = bundle_session 'install'
181
+ if flag
182
+ cmd << "--#{flag}"
183
+ append_bundle opts, FOR_INSTALL + OPT_INSTALL
184
+ from = :install
202
185
  else
203
- bundle_session 'install'
204
- append_bundle
186
+ if (n = option('jobs')).to_i > 0
187
+ cmd << "-j#{n}"
188
+ end
189
+ from = :depend
205
190
  end
206
- run_rb(sync: sync)
191
+ run_rb(from: from, sync: sync)
207
192
  end
208
193
  end
209
194
 
@@ -218,32 +203,43 @@ module Squared
218
203
  end
219
204
  return unless into
220
205
 
206
+ on :first, :copy
221
207
  dest = Pathname.new(into).realpath
222
- print_item unless @output[0] || task_invoked?(/\Acopy(?::#{Ruby.ref}|\z)/)
208
+ print_item unless @output[0] || task_invoked?(/^copy(?::#{Ruby.ref}|$)/)
223
209
  glob = as_a(glob || '**/*')
224
210
  as_a(from).each_with_index do |val, i|
225
211
  a = basepath(val)
226
212
  b = dest.join(val)
227
213
  c = glob[i] || glob[0]
228
214
  log.info "cp #{a.join(c)} #{b}"
229
- copy_d(a, b, glob: c, pass: exclude, verbose: verbose)
215
+ begin
216
+ copy_dir(a, b, c, pass: exclude, verbose: verbose)
217
+ rescue StandardError => e
218
+ log.error e
219
+ ret = on(:error, :copy, e)
220
+ raise if exception && ret != true
221
+ end
230
222
  end
223
+ on :last, :copy
231
224
  end
232
225
 
233
- def outdated(rev = nil, opts: [], sync: invoked_sync?('outdated', rev))
234
- cmd = bundle_session 'outdated', rev && "--#{rev}"
235
- append_bundle opts, OPT_OUTDATED
236
- cmd = session_done(cmd)
237
- log.info cmd
238
- banner = format_banner(cmd)
226
+ def outdated(flag = nil, opts: [], sync: invoked_sync?('outdated', flag))
227
+ cmd = bundle_output 'outdated'
228
+ if flag
229
+ cmd << "--#{flag}"
230
+ append_bundle(opts, OPT_OUTDATED, target: cmd)
231
+ end
232
+ log.info cmd.to_s
233
+ on :first, :outdated
234
+ banner = format_banner(cmd.to_s)
239
235
  print_item banner if sync
240
- start = 0
241
- found = 0
242
- major = 0
243
- pwd_set do
236
+ pwd_set(from: :outdated) do
237
+ start = 0
238
+ found = 0
239
+ major = 0
244
240
  buffer = []
245
241
  out = ->(val) { sync ? puts(val) : buffer << val }
246
- IO.popen("#{cmd} --no-color").each do |line|
242
+ IO.popen(cmd.temp('--no-color')).each do |line|
247
243
  if start > 0
248
244
  unless stdin?
249
245
  data = line.scan(SEM_VER)
@@ -295,26 +291,31 @@ module Squared
295
291
  end
296
292
  end
297
293
  unless styles.empty?
298
- case styles[0]
294
+ case styles.first
299
295
  when :green
300
- line = sub_style(line, pat: /^(\S+)(.+)$/, styles: theme[styles[1] == :bold ? :major : :active])
296
+ line = sub_style(line, pat: /^(\S+)(.+)$/, styles: theme[styles.last == :bold ? :major : :active])
301
297
  found += 1
302
298
  when :yellow
303
299
  found += 1
304
300
  end
305
- styles = styles.compact.map { |s| color(s) }.flatten
306
- line = sub_style(line, pat: /^((?:\S+\s+){2})(#{Regexp.escape(l)})(.*)$/, index: 2, styles: styles)
301
+ if theme[:current]
302
+ line = sub_style(line, styles: theme[:current], pat: /^(.+)(#{Regexp.escape(c)})(.+)$/,
303
+ index: 2)
304
+ end
305
+ line = sub_style(line, *colormap(styles), pat: /^((?:\S+\s+){2})(#{Regexp.escape(l)})(.*)$/,
306
+ index: 2)
307
307
  end
308
308
  end
309
309
  out.("#{start.to_s.rjust(2)}. #{line}")
310
- start += 1
311
310
  elsif line =~ /^Gem /
312
311
  unless stdin?
313
312
  sub = { pat: /^(.+)(?<!\dm)(Gem|Latest)(.+)$/, styles: theme[:header], index: 2 }
314
313
  out.(print_footer(" # #{line.chomp}", reverse: true, sub: [sub, sub]))
315
314
  end
316
- start += 1
315
+ else
316
+ next
317
317
  end
318
+ start += 1
318
319
  end
319
320
  unless sync
320
321
  print_item banner
@@ -336,39 +337,159 @@ module Squared
336
337
  puts 'No updates were found'
337
338
  end
338
339
  end
340
+ on :last, :outdated
339
341
  end
340
342
 
341
343
  def update(flag, opts: [])
342
344
  bundle_session 'update', "--#{flag}"
343
- append_bundle opts, OPT_UPDATE
344
- run_rb
345
+ append_bundle opts, FOR_INSTALL + OPT_UPDATE
346
+ run_rb(from: :update)
345
347
  end
346
348
 
347
- def pristine(flag, version: nil, opts: [])
348
- cmd = gem_session 'pristine'
349
+ def gemx(flag, opts: [])
350
+ cmd = gem_session
349
351
  case flag
350
- when :gem
351
- append_value opts
352
- when :all
353
- cmd << '--all'
354
- append_repeat 'skip', opts
355
- when :version
356
- cmd << project << shell_option('version', version)
352
+ when :outdated
353
+ cmd << "-C #{shell_quote(path)}" if (pass = Gem::VERSION >= '3.4.2')
354
+ cmd << flag
355
+ when :'user-install'
356
+ cmd << 'install' << "--#{flag}"
357
+ else
358
+ cmd << flag
359
+ end
360
+ no = flag == :pristine || flag == :outdated ? [] : OPT_GEM[:NO_GENERAL]
361
+ opts, pat = option_partition(opts, gemoption(flag), no: no, first: true)
362
+ out = []
363
+ opts.each do |opt|
364
+ if opt =~ pat
365
+ case $1
366
+ when 'build-root', 'config-file', 'target-rbconfig',
367
+ 'n', 'bindir', 'g', 'file', 'i', 'install-dir'
368
+ cmd << quote_option($1, basepath($2))
369
+ when 'p', 'http-proxy', 's', 'source'
370
+ cmd << shell_quote($1, $2)
371
+ when 'bulk-threshold'
372
+ cmd << basic_option($1, $2) if $2.to_i > 0
373
+ else
374
+ cmd << shell_option($1, $2)
375
+ end
376
+ else
377
+ out << opt
378
+ end
379
+ end
380
+ from = :"gem:#{flag == :'user-install' ? 'install' : flag}"
381
+ if flag == :outdated
382
+ log.info cmd.to_s
383
+ on :first, from
384
+ print_item format_banner(cmd.to_s)
385
+ pwd_set(pass: pass, from: from) do
386
+ items = [[%w[Gem Current Latest], nil]]
387
+ IO.popen(cmd.done).each do |line|
388
+ if (data = line.match(/^(\S+) \((\S+) < ([^)]+)\)$/))
389
+ cur = semscan(data[2])
390
+ lat = semscan(data[3])
391
+ items << [data.to_a.drop(1), if semmajor?(cur, lat)
392
+ %i[green bold]
393
+ else
394
+ cur[2] == lat[2] ? [:yellow] : [:green]
395
+ end]
396
+ else
397
+ puts line
398
+ end
399
+ end
400
+ if items.size == 1
401
+ puts 'No updates were found'
402
+ else
403
+ pad = [items.size.to_s.size + 1, 3].max
404
+ d = 0
405
+ e = 0
406
+ f = 0
407
+ items.each do |item|
408
+ a, b, c = item.first
409
+ d = a.size if a.size > d
410
+ e = b.size if b.size > e
411
+ f = c.size if c.size > f
412
+ end
413
+ major = 0
414
+ minor = 0
415
+ patch = 0
416
+ items.each_with_index do |item, i|
417
+ next if i == 0 && stdin?
418
+
419
+ a, b, c = item.first
420
+ if i == 0
421
+ line = "#{' #'.ljust(pad)} #{a.ljust(d)} #{b.rjust(e)} #{c.rjust(f)}"
422
+ n = line.size
423
+ 2.times do
424
+ line = sub_style(line, pat: /^(.+)(?<!\dm)(#{a}|#{c})(.*)$/, styles: theme[:header], index: 2)
425
+ end
426
+ puts line
427
+ puts '-' * n
428
+ else
429
+ styles = item.last
430
+ a = a.ljust(d)
431
+ if styles.first == :green
432
+ a = sub_style(a, styles: if styles.size == 2
433
+ major += 1
434
+ theme[:major]
435
+ else
436
+ minor += 1
437
+ theme[:active]
438
+ end)
439
+ else
440
+ patch += 1
441
+ end
442
+ b = b.rjust(e)
443
+ b = sub_style(b, styles: theme[:current]) if theme[:current]
444
+ c = sub_style(c.rjust(f), *colormap(styles))
445
+ puts "#{"#{i}.".rjust(pad)} #{a} #{b} #{c}"
446
+ end
447
+ end
448
+ unless stdin?
449
+ status = print_footer("major #{major} / minor #{minor} / patch #{patch}", right: true).split("\n")
450
+ status[1] = sub_style(status[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
451
+ status[1] = sub_style(status[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
452
+ puts status
453
+ end
454
+ end
455
+ end
456
+ on :last, from
457
+ else
458
+ if out.empty? && !cmd.find { |val| val =~ /^--system(?:=|$)/ }
459
+ raise_error('gem', flag, hint: 'no gemname given')
460
+ else
461
+ if flag == :pristine
462
+ if cmd.include?('--all')
463
+ append_repeat 'skip', out
464
+ out.clear
465
+ elsif (n = out.first =~ /@/)
466
+ name = out.first
467
+ if n == 0
468
+ cmd << shell_escape(project)
469
+ version = name[1..-1]
470
+ else
471
+ cmd << shell_escape(name[0..n - 1])
472
+ version = name[n + 1..-1]
473
+ end
474
+ cmd << shell_option('version', version)
475
+ out.clear
476
+ end
477
+ end
478
+ append_value out
479
+ end
480
+ run_rb(from: from)
357
481
  end
358
- run_rb
359
482
  end
360
483
 
361
- def bundle(flag, cmd)
362
- guard_params('bundle', flag, args: cmd)
363
- run_s "bundle #{flag} #{cmd.join(' ')}"
484
+ def bundle(cmd, *args)
485
+ run_s(bundle_session(cmd, *args), from: :bundle)
364
486
  end
365
487
 
366
488
  def rake(*cmd)
367
- rakefile = shell_option('rakefile', Rake.application.rakefile, quote: true, escape: false)
368
489
  if cmd.empty?
369
- run_s("rake #{rakefile}", chdir: workspace.pwd)
490
+ run_s(rake_output(rakeapp), from: :rake, chdir: workspace.pwd)
370
491
  else
371
- run_s(*cmd.map { |val| "rake #{rakefile} #{val}" }, chdir: workspace.pwd, banner: false)
492
+ run_s(*cmd.map { |val| rake_output(rakeapp, val) }, from: :rake, chdir: workspace.pwd, banner: false)
372
493
  end
373
494
  end
374
495
 
@@ -380,25 +501,37 @@ module Squared
380
501
  return true if super || (@copy.is_a?(Hash) && copy.fetch(:into, nil))
381
502
  return gemdir? if @gemdir
382
503
 
383
- if @version && (val = ENV['GEM_HOME'])
384
- @gemdir = Pathname.new(val).join(gempath)
504
+ if @version && (home = ENV['GEM_HOME'])
505
+ @gemdir = Pathname.new(home).join(gempath)
385
506
  return true if gemdir?
386
507
  end
387
508
  return false unless @autodetect
388
509
 
389
- unsafe = ->(hint) { raise_error('failed to parse', hint: hint) }
390
- out = pwd_set { `gem list --local -d #{project}` }
391
- unsafe.('version') unless (data = /#{Regexp.escape(project)} \(([^)]+)\)/.match(out))
392
- ver = data[1].split(/\s*,\s*/)
393
- ver.unshift(@version).uniq! if @version
394
- ver.each do |v|
395
- next unless (data = /\(#{Regexp.escape(v)}(?:,[^)]+|\b)\):([^\n]+)/.match(out))
396
-
397
- log.warn "using version #{v} (given #{@version})" if @version && @version != v
398
- @version = v
399
- break
510
+ set = lambda do |val|
511
+ log.warn "using version #{val} (given #{@version})" if @version && @version != val
512
+ @version = val
513
+ end
514
+ out = pwd_set { `#{gem_output('list', '--local', '-d', shell_escape(project, quote: true))}` }
515
+ if (data = /#{Regexp.escape(project)} \(([^)]+)\)/.match(out))
516
+ ver = data[1].split(/\s*,\s*/)
517
+ ver.unshift(@version).uniq! if @version
518
+ ver.each do |val|
519
+ next unless (data = /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/.match(out))
520
+
521
+ set.(val)
522
+ break
523
+ end
400
524
  end
401
- unsafe.('path') unless data
525
+ unless data || RUBY_VERSION < '2.6'
526
+ target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
527
+ if (path = target.resolve_feature_path(project)&.last)
528
+ gems = ['', 'gems', "#{project}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR)
529
+ if (ver = Regexp.new(gems).match(path)) && (data = /\A(.+)#{gempath}/.match(path))
530
+ set.(ver[1])
531
+ end
532
+ end
533
+ end
534
+ raise_error('failed to parse', hint: @version || 'path') unless data
402
535
  @gemdir = Pathname.new(data[1].strip).join(gempath)
403
536
  rescue StandardError => e
404
537
  log.error e
@@ -415,38 +548,58 @@ module Squared
415
548
 
416
549
  private
417
550
 
418
- def run_rb(sync: true)
419
- run(sync: sync, banner: !@session.include?('--quiet'))
551
+ def run_rb(**kwargs)
552
+ run(banner: !@session.include?('--quiet'), **kwargs)
420
553
  end
421
554
 
422
- def append_bundle(opts = nil, list = nil)
423
- if (val = option('jobs')).to_i > 0
424
- @session << "-j#{val}"
425
- end
426
- return unless opts && list
427
-
555
+ def append_bundle(opts, list, target: @session)
556
+ opts, pat = option_partition(opts, list, target: target)
557
+ out = []
428
558
  opts.each do |opt|
429
- if list.include?(opt)
430
- @session << "--#{opt}"
431
- elsif opt.match(/^g(?:roup)?=(.+)$/)
432
- @session << shell_option('group', $1)
559
+ if opt =~ pat
560
+ case $1
561
+ when 'path', 'gemfile', 'binstubs', 'target-rbconfig'
562
+ target << quote_option($1, basepath($2))
563
+ when 'standalone', 'with', 'without', 'g', 'group'
564
+ target << shell_quote($1, $2)
565
+ when 'retry', 'j', 'jobs'
566
+ target << basic_option($1, $2) if $2.to_i > 0
567
+ else
568
+ target << shell_option($1, $2)
569
+ end
570
+ else
571
+ out << opt
433
572
  end
434
573
  end
574
+ option_clear(out, target: target)
435
575
  end
436
576
 
437
- def gem_session(*cmd)
438
- ret = session('gem', *cmd)
439
- if (val = option('config-file', ignore: false))
440
- ret << shell_option('config-file', basepath(val), quote: true)
441
- end
442
- ret << '--norc' if option('norc')
577
+ def gem_session(*cmd, **kwargs)
578
+ ret = session('gem', *cmd, **kwargs)
579
+ ret << '--no-verbose' unless verbose
443
580
  ret
444
581
  end
445
582
 
446
- def bundle_session(*cmd)
447
- session('bundle', *cmd)
448
- append_nocolor option('no-color')
449
- @session
583
+ def bundle_session(*cmd, **kwargs)
584
+ ret = session('bundle', *cmd, **kwargs)
585
+ append_nocolor(target: ret)
586
+ ret
587
+ end
588
+
589
+ def rake_session(*cmd, **kwargs)
590
+ session('rake', *cmd, **kwargs)
591
+ end
592
+
593
+ def gem_output(*cmd, **kwargs)
594
+ session_output('gem', *cmd, **kwargs)
595
+ end
596
+
597
+ def bundle_output(*cmd, **kwargs)
598
+ session_output('bundle', *cmd, **kwargs)
599
+ end
600
+
601
+ def rake_output(*cmd, **kwargs)
602
+ session_output('rake', *cmd, **kwargs)
450
603
  end
451
604
 
452
605
  def read_rakefile
@@ -455,8 +608,8 @@ module Squared
455
608
  ret = []
456
609
  pass = Rake::VERSION >= '13.0.4'
457
610
  pwd_set(pass: pass) do
458
- IO.popen("rake#{pass ? " -C #{shell_quote(path)}" : ''} -AT").each do |line|
459
- next unless (data = /\Arake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/.match(line))
611
+ IO.popen(rake_output(pass ? "-C #{shell_quote(path)}" : nil, '-AT').to_s).each do |line|
612
+ next unless (data = /^rake ((?:[^\[: ]+:?)+)(\[[^\]]+\])?/.match(line))
460
613
 
461
614
  ret << [data[1], data[2]]
462
615
  end
@@ -469,8 +622,7 @@ module Squared
469
622
  end
470
623
 
471
624
  def variables
472
- ret = super + VAR_SET
473
- ret.freeze
625
+ (super + %i[version autodetect]).freeze
474
626
  end
475
627
 
476
628
  def rakefile
@@ -478,9 +630,23 @@ module Squared
478
630
  basepath(file) if file
479
631
  end
480
632
 
633
+ def rakeapp
634
+ quote_option 'rakefile', Rake.application.rakefile
635
+ end
636
+
481
637
  def gempath
482
638
  File.join('gems', "#{project}-#{@version}")
483
639
  end
640
+
641
+ def gemoption(flag)
642
+ target = flag == :'user-install' ? :INSTALL : flag.upcase
643
+ OPT_GEM[:COMMON] + OPT_GEM[target] + case flag
644
+ when :pristine, :outdated
645
+ []
646
+ else
647
+ OPT_GEM[:GENERAL] + OPT_GEM[:NO_GENERAL]
648
+ end
649
+ end
484
650
  end
485
651
 
486
652
  Application.implement Ruby