squared 0.7.2 → 0.7.3

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.
@@ -12,8 +12,8 @@ module Squared
12
12
  installer=b o|outdir=p].freeze,
13
13
  venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
14
14
  prompt=q].freeze,
15
- virtualenv: %w[always-copy clear copies download q|quiet never-download no-download no-periodic-update no-pip
16
- no-seed no-setuptools no-vcs-ignore read-only-app-data reset-app-data symlink-app-data symlinks
15
+ virtualenv: %w[always-copy clear copies download never-download no-download no-periodic-update no-pip no-seed
16
+ no-setuptools no-vcs-ignore q|quiet read-only-app-data reset-app-data symlink-app-data symlinks
17
17
  system-site-packages with-traceback without-pip upgrade-embed-wheels v|verbose=+ activators=q
18
18
  app-data=p creator=b discovery=b extra-search-dir=p pip=b prompt=q p|python=q seeder=b
19
19
  setuptools=b try-first-with=q].freeze
@@ -34,14 +34,16 @@ module Squared
34
34
  install: %w[break-system-packages compile dry-run force-reinstall I|ignore-installed no-compile
35
35
  no-warn-conflicts no-warn-script-location U|upgrade user prefix=p report=p root=p
36
36
  root-user-action=b t|target=p upgrade-strategy=b].freeze,
37
- install_a: %w[ignore-requires-python no-index pre extra-index-url=q f|find-links=q i|index-url=q no-binary=q
38
- only-binary=q].freeze,
39
- install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps prefer-binary
40
- require-hashes use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p src=p].freeze,
37
+ install_a: %w[no-index pre prefer-binary all-releases=b extra-index-url=q f|find-links=q i|index-url=q
38
+ no-binary=q only-binary=q only-final=b].freeze,
39
+ install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps require-hashes
40
+ use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p requirements-from-script=p
41
+ src=p].freeze,
41
42
  install_c: %w[C|config-settings=q e|editable=v].freeze,
43
+ install_d: %w[ignore-requires-python uploaded-prior-to=q].freeze,
42
44
  hash: %w[a|algorithm].freeze,
43
- list: %w[e|editable exclude-editable include-editable l|local no-index not-required o|outdated pre u|uptodate
44
- user exclude=b extra-index-url=q format=b f|find-links=q i|index-url=q path=p].freeze,
45
+ list: %w[e|editable exclude-editable include-editable l|local not-required o|outdated u|uptodate user
46
+ exclude=b format=b path=p].freeze,
45
47
  lock: %w[o|output=p].freeze,
46
48
  show: %w[f|files].freeze,
47
49
  uninstall: %w[break-system-packages y|yes r|requirement=p root-user-action=b].freeze,
@@ -91,7 +93,7 @@ module Squared
91
93
  debug: %w[platform].freeze,
92
94
  install: %w[C config-settings c constraint extra-index-url no-binary only-binary platform
93
95
  r requirement].freeze,
94
- list: %w[exclude extra-index-url].freeze
96
+ list: %w[exclude extra-index-url no-binary only-binary].freeze
95
97
  }.freeze
96
98
  }.freeze
97
99
  private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE,
@@ -117,7 +119,8 @@ module Squared
117
119
  end
118
120
  end
119
121
 
120
- attr_reader :venv, :editable
122
+ attr_reader :venv
123
+ attr_accessor :editable
121
124
 
122
125
  def initialize(*, editable: '.', asdf: 'python', **kwargs)
123
126
  super
@@ -137,10 +140,10 @@ module Squared
137
140
  subtasks({
138
141
  'venv' => %i[exec create remove show].freeze,
139
142
  'pip' => %i[upgrade uninstall wheel reinstall freeze].freeze,
140
- 'install' => %i[requirement target upgrade editable poetry].freeze,
143
+ 'install' => %i[upgrade requirement target editable user poetry].freeze,
141
144
  'outdated' => %i[major minor patch].freeze,
142
145
  'build' => %i[poetry pdm hatch meson python].freeze,
143
- 'publish' => %i[poetry pdm hatch twine].freeze,
146
+ 'publish' => %i[twine poetry pdm hatch].freeze,
144
147
  'run' => nil,
145
148
  'exec' => nil
146
149
  })
@@ -348,8 +351,12 @@ module Squared
348
351
  depend(flag, args.extras, target: path)
349
352
  end
350
353
  else
351
- next if flag == :poetry && !poetry?
352
-
354
+ case flag
355
+ when :user
356
+ next if venv
357
+ when :poetry
358
+ next unless poetry?
359
+ end
353
360
  task flag do |_, args|
354
361
  install flag, args.to_a
355
362
  end
@@ -374,8 +381,11 @@ module Squared
374
381
  end
375
382
  break if be
376
383
  when 'publish'
377
- next if (be = backend?(flag)) == false
378
-
384
+ if flag == :twine
385
+ next unless twine?
386
+ elsif (be = backend?(flag)) == false
387
+ next
388
+ end
379
389
  format_desc(action, flag, 'test?,opts*', after: case flag
380
390
  when :hatch then 'artifacts?'
381
391
  when :twine then 'dist?'
@@ -588,10 +598,10 @@ module Squared
588
598
  when :editable
589
599
  op << quote_option('e', op.pop || editable || '.')
590
600
  op.clear
591
- when :upgrade
601
+ when :user, :upgrade
592
602
  op.concat(packages)
593
603
  raise_error 'no packages listed', hint: flag if op.empty?
594
- op << '--upgrade'
604
+ op << "--#{flag}"
595
605
  op.append
596
606
  python_session('-m pip', *op.to_a.drop(1)) if workspace.windows?
597
607
  end
@@ -987,7 +997,7 @@ module Squared
987
997
 
988
998
  if found
989
999
  line.chomp!($1) if line =~ /(?<=[\d"'{}\[\]]|true|false)(\s*#.*)$/
990
- break if line.match?(/^\s*\[(?:[\w.\-" ]+|".+"|'.+')\]\s*$/)
1000
+ break if line.match?(/^\s*\[(?:[\w.\-"' ]+|".+"|'.+')\]\s*$/)
991
1001
 
992
1002
  if ch
993
1003
  val = line.rstrip
@@ -1075,6 +1085,7 @@ module Squared
1075
1085
  if pip_install?(flag)
1076
1086
  ret.concat(OPT_PIP[:install_a])
1077
1087
  ret.concat(OPT_PIP[:install_b]) unless flag == :index
1088
+ ret.concat(OPT_PIP[:install_d])
1078
1089
  case flag
1079
1090
  when :install
1080
1091
  ret.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
@@ -1083,6 +1094,8 @@ module Squared
1083
1094
  when :download, :index
1084
1095
  ret.concat(OPT_PIP[:debug])
1085
1096
  end
1097
+ elsif flag == :list
1098
+ ret.concat(OPT_PIP[:install_a])
1086
1099
  end
1087
1100
  ret
1088
1101
  end
@@ -1170,9 +1183,17 @@ module Squared
1170
1183
  if poetry?
1171
1184
  requires = read_pyproject 'tool.poetry', 'requires-poetry'
1172
1185
  args << "poetry#{requires}"
1186
+ elsif setuptools? && !virtualenv?
1187
+ args << 'setuptools' << 'wheel'
1173
1188
  end
1174
1189
  pip(:install, *args, banner: false) unless args.empty?
1175
- success?(ret, banner, !status) { |ret| puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed') }
1190
+ success?(ret, banner, !status) { |out| puts(out && dir.directory? ? "Success: #{dir}" : 'Failed') }
1191
+ end
1192
+
1193
+ def venv_package?(val)
1194
+ return false unless venv
1195
+
1196
+ !Dir.glob("lib/**/site-packages/#{val}", base: venv).empty?
1176
1197
  end
1177
1198
 
1178
1199
  def pip_install?(flag)
@@ -1206,6 +1227,10 @@ module Squared
1206
1227
  dependtype == 1
1207
1228
  end
1208
1229
 
1230
+ def twine?
1231
+ venv_package?('twine')
1232
+ end
1233
+
1209
1234
  def virtualenv?
1210
1235
  @virtualenv ||= exist?('virtualenv.ini') || !ENV['VIRTUALENV_PYTHON'].nil?
1211
1236
  end
@@ -192,7 +192,7 @@ module Squared
192
192
 
193
193
  subtasks({
194
194
  'outdated' => %i[major minor patch].freeze,
195
- 'ruby' => %i[file script version].freeze,
195
+ 'ruby' => %i[file script version reshim].freeze,
196
196
  'gem' => %i[install uninstall outdated update pristine build push exec command].freeze,
197
197
  'bundle' => %i[config install update cache exec reinstall command].freeze,
198
198
  'rake' => nil,
@@ -202,6 +202,7 @@ module Squared
202
202
  })
203
203
 
204
204
  attr_reader :gemdir
205
+ attr_accessor :autodetect
205
206
 
206
207
  def initialize(*, autodetect: false, steep: 'Steepfile', rubocop: '.rubocop.yml', asdf: 'ruby', **kwargs)
207
208
  super
@@ -215,11 +216,11 @@ module Squared
215
216
  dependfile_set GEMFILE
216
217
  serve_set kwargs[:serve]
217
218
  gemfile_set kwargs[:gemspec]
218
- @autodetect = autodetect
219
+ self.autodetect = autodetect
219
220
  @steepfile = basepath! steep if steep
220
221
  @rubocopfile = Pathname.new(rubocop).realpath rescue basepath!(Dir.home, '.rubocop.yml') if rubocop
221
222
  @rubygems = kwargs.fetch(:rubygems, 0)
222
- return unless rakefile && @output[0].nil? && @copy.nil? && !version && !@autodetect
223
+ return unless rakefile && @output[0].nil? && @copy.nil? && !version && !self.autodetect
223
224
 
224
225
  begin
225
226
  File.foreach(rakefile) do |line|
@@ -528,145 +529,132 @@ module Squared
528
529
  ruby(flag, opts: args.to_a, command: command)
529
530
  end
530
531
  when :version
531
- format_desc action, flag
532
- task flag do
533
- pwd_set do
534
- out = []
535
- order = { 'rbenv' => -1, 'rvm' => -1, 'chruby' => -1, 'mise' => -1 }
536
- ENV.fetch('PATH', '').split(':').each_with_index do |val, index|
537
- order.each_key do |key|
538
- next unless val.match?(%r{[/.]#{key}/})
539
-
540
- order[key] = index
541
- break
532
+ format_desc action, flag, 'local?,alias?'
533
+ task flag, [:local, :name] do |_, args|
534
+ ver = %w[.tool-versions .ruby-version]
535
+ mise = %w[mise.local.toml mise.toml]
536
+ s = args.local
537
+ if s && (%w[system latest].include?(s) || SEM_VER.match?(s) || s.start_with?(/(path|ref):/))
538
+ rbvm = exist?(ver.last) && !exist?(ver.first)
539
+ case vmname
540
+ when nil
541
+ print_error('no version manager detected', subject: name)
542
+ next
543
+ when 'asdf'
544
+ unless rbvm
545
+ asdf(:set, **{ name: args.name, version: s, banner: verbose? }.compact)
546
+ next
542
547
  end
543
- end
544
- if @asdf
545
- [File.join(ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf'), "installs/#{@asdf.first}")]
546
- else
547
- [
548
- "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
549
- '$HOME/.rvm/bin/rvm',
550
- '$HOME/.local/bin/mise',
551
- '/usr/bin/rbenv',
552
- '/usr/bin/mise',
553
- '/usr/local/rvm/bin/rvm',
554
- '/usr/share/rvm/bin/rvm',
555
- '/usr/local/share/chruby/chruby.sh'
556
- ]
557
- .sort do |a, b|
558
- c = -1
559
- d = -1
560
- order.each do |key, val|
561
- pat = %r{/\.?#{key}}
562
- c = val if a.match?(pat)
563
- d = val if b.match?(pat)
564
- end
565
- if c == d
566
- 0
567
- elsif c == -1
568
- 1
569
- elsif d == -1
570
- -1
571
- else
572
- c < d ? -1 : 1
573
- end
548
+ when 'mise'
549
+ if mise.none? { |val| exist?(val) } && rbvm.call
550
+ save.call
551
+ else
552
+ cmd = session 'mise', 'use'
553
+ cmd << '--env local' if exist?(mise.first)
554
+ cmd << "#{args.name || 'ruby'}@#{s}"
555
+ run(banner: verbose?)
556
+ next
574
557
  end
575
- .push('')
576
558
  end
577
- .each do |val|
578
- next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
579
-
580
- trim = ->(s) { s[/^\D+\d+\.\d+(?:\.\S+)?/, 0].sub(/^([a-z]+)-/i, '\1 ') }
581
- ver = %w[.tool-versions .ruby-version]
582
- out << trim.call(case (cmd = File.basename(val))
583
- when 'rvm'
584
- ver.shift
585
- `rvm current`[/^\S+/, 0]
586
- when 'rbenv'
587
- ver.shift
588
- name = `rbenv version-name`
589
- name.match?(SEM_VER) ? "ruby #{name}" : name
590
- when 'chruby.sh'
591
- ver.shift
592
- chruby = session_output 'source', val
593
- `#{chruby.with('ruby --version')}`
594
- when 'mise'
595
- data = parse_json(`mise ls ruby --json`, kind: Array)
596
- data = data.find { |item| item['active'] } || data.first
597
- "ruby #{data['version']}"
598
- else
599
- if @asdf
600
- cmd = 'asdf'
601
- if @@asdf.config && File.exist?(@@asdf.config)
602
- pat = /legacy_version_file\s+=\s+(yes|no)/
603
- ver.pop unless File.read(@@asdf.config)[pat, 1] == 'yes'
604
- else
605
- ver.pop
606
- end
607
- opt = [@asdf.first]
608
- opt.unshift('--no-header') unless @@asdf.version == 15
609
- cur = `asdf current #{opt.join(' ')}`
610
- if cur.match?(/\sfalse\b/)
611
- `ruby --version`
612
- else
613
- cur[/^\S+\s+\S+/, 0].sub(/\s+/, ' ')
614
- end
615
- else
616
- ver = nil
617
- `ruby --version`
559
+ File.write(basepath(ver.last), "#{s}\n") if SEM_VER.match?(s)
560
+ next
561
+ end
562
+ pwd_set do
563
+ out = []
564
+ tool = args.name || (args.local && !SEM_VER.match?(args.local) ? args.local : 'ruby')
565
+ trim = ->(s) { s[/^\D+\d+\.\d+(?:\.\S+)?/, 0].sub(/^([a-z]+)-/i, '\1 ') }
566
+ out << trim.call(case (vm, bin = vmname(bin: true))
567
+ when 'rvm'
568
+ ver.shift
569
+ `rvm current`[/^\S+/, 0]
570
+ when 'rbenv'
571
+ ver.shift
572
+ name = `rbenv version-name`
573
+ (name =~ SEM_VER) == 0 ? "ruby #{name}" : name
574
+ when 'chruby'
575
+ ver.shift
576
+ chruby = session_output 'source', bin
577
+ `#{chruby.with('ruby --version')}`
578
+ when 'mise'
579
+ data = parse_json(`mise ls #{tool} --json`, kind: Array)
580
+ cur = `mise current #{tool}`.split.find do |val|
581
+ data.any? do |item|
582
+ item['version'] == val && item['installed'] && item['active']
618
583
  end
619
- end)
620
- break if workspace.windows?
621
-
622
- unless val.empty?
623
- out << trim.call(case cmd
624
- when 'chruby.sh'
584
+ end
585
+ "ruby #{cur || data.first['version']}"
586
+ when 'asdf'
587
+ if @@asdf.config && File.exist?(@@asdf.config)
588
+ pat = /legacy_version_file\s+=\s+(yes|no)/
589
+ ver.pop unless File.read(@@asdf.config)[pat, 1] == 'yes'
590
+ else
591
+ ver.pop
592
+ end
593
+ opt = [@asdf.first]
594
+ opt.unshift('--no-header') unless @@asdf.version == 15
595
+ cur = `asdf current #{opt.join(' ')}`
596
+ if cur.match?(/\sfalse\b/)
597
+ `ruby --version`
598
+ else
599
+ cur[/^\S+\s+\S+/, 0].sub(/\s+/, ' ')
600
+ end
601
+ else
602
+ ver = nil
603
+ `ruby --version`
604
+ end)
605
+ unless workspace.windows?
606
+ if vm
607
+ out << trim.call(case vm
608
+ when 'chruby'
625
609
  `#{chruby.with('chruby --version')}`.sub(':', '')
626
610
  when 'asdf'
627
611
  "asdf #{`asdf version`.delete_prefix('v')}"
628
612
  when 'mise'
629
- data = parse_json `mise version --json`
630
- "mise #{data['latest']}"
613
+ "mise #{parse_json(`mise version --json`, key: 'latest')}"
631
614
  else
632
- `#{cmd} --version`
615
+ `#{vm} --version`
633
616
  end)
634
617
  end
635
618
  begin
636
- out << ('which %s' % case cmd
619
+ out << ('which %s' % case vm
637
620
  when 'rbenv'
638
- `rbenv which ruby`
639
- when 'chruby.sh'
621
+ `rbenv which #{tool}`
622
+ when 'chruby'
640
623
  `#{chruby.with('which ruby')}`
641
624
  when 'asdf'
642
625
  `asdf which #{@asdf.first}`
643
626
  when 'mise'
644
- `mise which ruby`
627
+ `mise which #{tool}`
645
628
  else
646
- `which ruby`
629
+ `which #{tool}`
647
630
  end)
648
631
  rescue => e
649
632
  log.debug e
650
633
  end
651
634
  if ver
635
+ ver = mise + ver if vm == 'mise'
652
636
  catch :found do
653
637
  path.ascend do |dir|
654
638
  ver.filter { |val| dir.join(val).exist? }.each do |val|
655
639
  dir += val
656
- hint = File.read(dir)
657
- .lines
658
- .map { |s| s.sub(/#.*$/, '').strip }
659
- .reject(&:empty?)
660
- .join(', ')
640
+ file = File.read(dir)
641
+ hint = if val.include?('mise')
642
+ line = file[/^\s*#{tool}\s*=\s*\[?(.+?)\]?\s*$/, 1]
643
+ line&.gsub(/["']/, '')
644
+ else
645
+ file.lines
646
+ .map { |line| line.sub(/#.*$/, '').strip }
647
+ .reject(&:empty?)
648
+ .join(', ')
649
+ end
661
650
  out << message("found #{dir}", hint: hint)
662
- throw :found if hint.include?(out.first[/^ruby (.+)$/, 1])
651
+ throw :found if hint&.include?(out.first[/^(?:j|truffle)?ruby ([\d.]+)/, 1])
663
652
  rescue
664
653
  nil
665
654
  end
666
655
  end
667
656
  end
668
657
  end
669
- break
670
658
  end
671
659
  out.map!(&:split)
672
660
  pad = as_a(out, :first, :size).max
@@ -674,6 +662,21 @@ module Squared
674
662
  puts(out.map { |line| '%*s %s' % [pad, line.first, line[1..-1].join(' ')] })
675
663
  end
676
664
  end
665
+ when :reshim
666
+ format_desc action, flag, 'name?'
667
+ task flag, [:name] do |_, args|
668
+ case vmname
669
+ when 'rbenv'
670
+ cmd = session 'rbenv', 'rehash'
671
+ when 'asdf'
672
+ asdf(:reshim, **{ name: args.name, banner: verbose? }.compact)
673
+ when 'mise'
674
+ cmd = session('mise', 'reshim', args.name || 'ruby')
675
+ else
676
+ print_error('not supported by version manager', subject: args.name)
677
+ end
678
+ success?(run(banner: verbose?), verbose?) if cmd
679
+ end
677
680
  end
678
681
  end
679
682
  end
@@ -906,7 +909,7 @@ module Squared
906
909
  items.map(&:last)
907
910
  end
908
911
  if dryrun
909
- print_run bundle_output("update --#{flag}", *gems.quote!), false
912
+ print_run bundle_output("update --#{flag}", *gems.quote!(escape: true)), false
910
913
  else
911
914
  bundle(:update, *gems, opts: [flag.to_s])
912
915
  end
@@ -1151,7 +1154,7 @@ module Squared
1151
1154
  end
1152
1155
  end
1153
1156
  if filter[:dryrun]
1154
- print_run gem_output('update -f', *update.quote!), false
1157
+ print_run gem_output('update -f', *update.quote!(escape: true)), false
1155
1158
  else
1156
1159
  gem(:update, *update, opts: opts)
1157
1160
  end
@@ -1227,7 +1230,7 @@ module Squared
1227
1230
  if op.arg?('system')
1228
1231
  op.add_first(quote: false) { |val| val if val.match?(SEM_VER) }
1229
1232
  else
1230
- op.append
1233
+ op.append(escape: true)
1231
1234
  end
1232
1235
  when :install, :uninstall, :pristine
1233
1236
  if flag == :install
@@ -1241,18 +1244,18 @@ module Squared
1241
1244
  args.join(' ')
1242
1245
  end
1243
1246
  elsif ia
1244
- name = op.shift || args.shift || (s = readline('Enter gem name', force: true))
1247
+ name = op.shift || args.shift || (out = readline('Enter gem name', force: true))
1245
1248
  list = []
1246
1249
  pwd_set do
1247
1250
  pat = /^#{name}\s+\((.+)\)$/
1248
1251
  IO.popen(gem_output("list -a #{shell_quote(name)}").to_s).each do |val|
1249
1252
  next unless val =~ pat
1250
1253
 
1251
- split_escape($1).each { |val| list << val unless val.start_with?('default:') }
1254
+ split_escape($1).each { |s| list << s unless s.start_with?('default:') }
1252
1255
  break
1253
1256
  end
1254
1257
  end
1255
- ver = choice_index('Select version', list, force: s.nil?) unless list.empty?
1258
+ ver = choice_index('Select version', list, force: out.nil?) unless list.empty?
1256
1259
  if ver
1257
1260
  op << '--force'
1258
1261
  op.unshift("#{name}@#{ver}")
@@ -1280,9 +1283,9 @@ module Squared
1280
1283
  .clear
1281
1284
  end
1282
1285
  if flag == :install
1283
- op.append_any
1286
+ op.append_any(escape: true)
1284
1287
  else
1285
- op.append
1288
+ op.append(escape: true)
1286
1289
  end
1287
1290
  op.delim << post if post
1288
1291
  when :check, :cleanup, :contents, :fetch, :list, :lock, :rdoc
@@ -1562,7 +1565,7 @@ module Squared
1562
1565
  run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :rubocop)
1563
1566
  end
1564
1567
 
1565
- def serve(root, *, bind: nil, port: nil, **kwargs)
1568
+ def serve(root, *, bind: nil, port: 3000, **kwargs)
1566
1569
  require 'webrick'
1567
1570
  config = kwargs.merge({ DocumentRoot: root })
1568
1571
  config[:BindAddress] = bind if bind
@@ -1574,6 +1577,61 @@ module Squared
1574
1577
  server.start
1575
1578
  end
1576
1579
 
1580
+ def vmname(bin: false)
1581
+ order = { 'rbenv' => -1, 'rvm' => -1, 'chruby' => -1, 'mise' => -1 }
1582
+ ENV.fetch('PATH', '').split(':').each_with_index do |val, index|
1583
+ order.each_key do |key|
1584
+ next unless val.match?(%r{[/.]#{key}/})
1585
+
1586
+ order[key] = index
1587
+ break
1588
+ end
1589
+ end
1590
+ if @asdf
1591
+ [File.join(ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf'), "installs/#{@asdf.first}")]
1592
+ else
1593
+ [
1594
+ "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
1595
+ '$HOME/.rvm/bin/rvm',
1596
+ '$HOME/.local/bin/mise',
1597
+ '/usr/bin/rbenv',
1598
+ '/usr/bin/mise',
1599
+ '/usr/local/rvm/bin/rvm',
1600
+ '/usr/share/rvm/bin/rvm',
1601
+ '/usr/local/share/chruby/chruby.sh'
1602
+ ]
1603
+ .sort do |a, b|
1604
+ c = -1
1605
+ d = -1
1606
+ order.each do |key, val|
1607
+ pat = %r{/\.?#{key}}
1608
+ c = val if a.match?(pat)
1609
+ d = val if b.match?(pat)
1610
+ end
1611
+ if c == d
1612
+ 0
1613
+ elsif c == -1
1614
+ 1
1615
+ elsif d == -1
1616
+ -1
1617
+ else
1618
+ c < d ? -1 : 1
1619
+ end
1620
+ end
1621
+ end
1622
+ .each do |val|
1623
+ next unless File.exist?(val = val.sub('$HOME', Dir.home))
1624
+
1625
+ case (ret = File.basename(val, '.*'))
1626
+ when 'rvm', 'rbenv', 'mise', 'chruby'
1627
+ return bin ? [ret, val] : ret
1628
+ else
1629
+ return bin ? ['asdf', val] : 'asdf' if @asdf
1630
+ end
1631
+ end
1632
+ nil
1633
+ end
1634
+
1577
1635
  def gemspec
1578
1636
  @gemspec = !gemfile.nil? && Gem::Specification.load(gemfile.to_s) rescue false if @gemspec.nil?
1579
1637
  @gemspec || nil
@@ -1596,7 +1654,7 @@ module Squared
1596
1654
  def copy?
1597
1655
  return true if @copy.is_a?(Hash) ? copy[:into] : super
1598
1656
  return gemdir? if gemdir
1599
- return false unless @autodetect
1657
+ return false unless autodetect
1600
1658
 
1601
1659
  set = lambda do |val, path|
1602
1660
  base = Pathname.new(path.strip)
@@ -1609,7 +1667,7 @@ module Squared
1609
1667
  end
1610
1668
  if version
1611
1669
  begin
1612
- case @autodetect
1670
+ case autodetect
1613
1671
  when 'rvm'
1614
1672
  pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
1615
1673
  when 'rbenv'
@@ -1617,8 +1675,10 @@ module Squared
1617
1675
  File.join($1, 'lib/ruby/gems', "#{$2}.0")
1618
1676
  end
1619
1677
  when 'asdf', 'mise'
1620
- val = pwd_set { `#{@autodetect} where ruby`.chomp }
1621
- File.join(val, 'lib/ruby/gems', "#{$1}.0") if val =~ /(\d\.\d)\.[^.]+$/
1678
+ pwd_set do
1679
+ val = `#{autodetect} where ruby`.chomp
1680
+ File.join(val, 'lib/ruby/gems', "#{$1}.0") if val =~ /(\d\.\d)\.[^.]+$/
1681
+ end
1622
1682
  when /bundler?/
1623
1683
  pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1].split(File::PATH_SEPARATOR).find do |val|
1624
1684
  Dir.exist?(File.join(val, 'gems'))
@@ -1667,7 +1727,7 @@ module Squared
1667
1727
  log.error e
1668
1728
  self.version = nil
1669
1729
  @gemdir = nil
1670
- @autodetect = false
1730
+ self.autodetect = false
1671
1731
  else
1672
1732
  gemdir?
1673
1733
  end
@@ -1768,7 +1828,7 @@ module Squared
1768
1828
 
1769
1829
  def unpack_get(tag, ext)
1770
1830
  if ext == 'gem'
1771
- "https://rubygems.org/downloads/#{File.basename(tag, '.gem')}.gem"
1831
+ "https://rubygems.org/downloads/#{tag.sub_ext('.gem')}"
1772
1832
  else
1773
1833
  super
1774
1834
  end
@@ -27,7 +27,7 @@ module Squared
27
27
  def multiple=(val)
28
28
  case val
29
29
  when Enumerable
30
- @multiple.concat(val.to_a.map { |val| val.is_a?(Regexp) ? val : val.to_s })
30
+ @multiple.concat(val.to_a.map { |pat| pat.is_a?(Regexp) ? pat : pat.to_s })
31
31
  when String, Symbol, Pathname
32
32
  @multiple << val.to_s
33
33
  when Regexp