squared 0.1.4 → 0.2.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,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