squared 0.8.6 → 0.9.0.pre2

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,7 +4,7 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Python < Git
7
- DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
7
+ DEP_PYTHON = %w[poetry.lock pdm.lock pylock.toml setup.cfg pyproject.toml setup.py requirements.txt].freeze
8
8
  DIR_PYTHON = (DEP_PYTHON + %w[meson.build README.rst]).freeze
9
9
  OPT_PYTHON = {
10
10
  common: %w[b=+ B d E h i I O P q=+ s S u v=+ V=+ x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
@@ -58,8 +58,8 @@ module Squared
58
58
  u|username=qq].freeze
59
59
  }.freeze
60
60
  OPT_PDM = {
61
- common: %w[I|ignore-python no-cache n|non-interactive].freeze,
62
- build: %w[C=bm no-clean no-isolation no-sdist no-wheel q|quiet v|verbose=+ config-setting=q d|dest=p
61
+ common: %w[c|config I|ignore-python no-cache n|non-interactive].freeze,
62
+ build: %w[C=bm no-clean no-isolation no-sdist no-wheel q|quiet v|verbose=+ config-setting=qq d|dest=p
63
63
  p|project=p k|skip=b].freeze,
64
64
  publish: %w[no-build no-very-ssl q|quiet S|sign skip-existing v|verbose=+ ca-certs=p c|comment=q d|dest=p
65
65
  i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
@@ -131,7 +131,7 @@ module Squared
131
131
  initialize_build(Python.ref, **kwargs)
132
132
  initialize_env(**kwargs)
133
133
  end
134
- dependfile_set(DEP_PYTHON, default: 2)
134
+ dependfile_set(DEP_PYTHON, default: 4)
135
135
  serve_set kwargs[:serve]
136
136
  editable_set editable
137
137
  venv_set kwargs[:venv]
@@ -297,7 +297,7 @@ module Squared
297
297
  install flag, ['upgrade', *args.to_a, 'pip']
298
298
  end
299
299
  when :freeze
300
- format_desc action, flag, "file?=#{DEP_PYTHON[4]},u/ninstall?,opts*"
300
+ format_desc action, flag, "file?=#{DEP_PYTHON[6]},u/ninstall?,opts*"
301
301
  task flag do |_, args|
302
302
  opts = args.to_a
303
303
  if has_value!(opts, 'u', 'uninstall')
@@ -351,7 +351,7 @@ module Squared
351
351
  'eager'
352
352
  when /^only-if|needed$/
353
353
  'only-if-needed'
354
- end.yield_self do |val|
354
+ end.then do |val|
355
355
  if val
356
356
  args.extras << "upgrade-strategy=#{val}"
357
357
  else
@@ -430,7 +430,17 @@ module Squared
430
430
  workspace.rev_clear(name, sync: sync)
431
431
  if !flag && poetry?
432
432
  cmd = poetry_session 'install -n'
433
+ if prod?
434
+ cmd << '--only=main'
435
+ else
436
+ option('with') { |val| cmd << basic_option('with', val) }
437
+ option('without') { |val| cmd << basic_option('without', val) }
438
+ end
433
439
  cmd << '--no-root' if option('no-root')
440
+ elsif !flag && pdm?
441
+ cmd = pdm_session 'install'
442
+ cmd << '--prod' if prod?
443
+ option('G', 'group') { |val| cmd << basic_option('G', val) }
434
444
  else
435
445
  cmd = pip_session 'install'
436
446
  cmd << '--upgrade-strategy=eager' if env('UPDATE') || env('PYTHON_UPDATE')
@@ -447,9 +457,13 @@ module Squared
447
457
  else
448
458
  append_global
449
459
  end
450
- if exist?(DEP_PYTHON[4]) && !session_arg?('r', 'requirement')
451
- cmd << basic_option('r', DEP_PYTHON[4])
452
- cmd << basic_option('c', 'constraints.txt') if exist?('constraints.txt')
460
+ unless session_arg?('r', 'requirement')
461
+ if exist?(DEP_PYTHON[2])
462
+ cmd << basic_option('r', DEP_PYTHON[2])
463
+ elsif exist?(DEP_PYTHON[6])
464
+ cmd << basic_option('r', DEP_PYTHON[6])
465
+ cmd << basic_option('c', 'constraints.txt') if exist?('constraints.txt')
466
+ end
453
467
  end
454
468
  append_editable
455
469
  end
@@ -569,8 +583,9 @@ module Squared
569
583
  end
570
584
  if found > 0
571
585
  items = if se
572
- choice('Select a package', items.map(&:first),
573
- multiple: true, force: false, index: true, border: true).map { |n| items[n.pred].last }
586
+ choice('Select a package', items.map(&:first), multiple: true, force: false, index: true,
587
+ border: true, **parse_select)
588
+ .map { |n| items[n.pred].last }
574
589
  elsif ia
575
590
  items.map(&:last)
576
591
  else
@@ -734,8 +749,8 @@ module Squared
734
749
  def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
735
750
  op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
736
751
  session('python', path: !venv?),
737
- project: self, strict: strict?, multiple: [/^-c/], single: singleopt(:python),
738
- args: true, stdin: true)
752
+ project: self, strict: strict?, auto: %w[help V|version],
753
+ multiple: [/^-c/], single: singleopt(:python), args: true, stdin: true)
739
754
  op.concat(args)
740
755
  if op.include?('-')
741
756
  op.exist?(add: true)
@@ -748,8 +763,8 @@ module Squared
748
763
  op.append(escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
749
764
  end
750
765
  end
751
- print_run(op, banner, **kwargs)
752
- run(sync: sync, banner: banner, exception: exception?(**kwargs), from: :python)
766
+ print_run(op, banner, **kwargs) unless op.stdout
767
+ run(sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from: :python)
753
768
  end
754
769
 
755
770
  def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -786,7 +801,7 @@ module Squared
786
801
  ret = kwargs[:requirement] || begin
787
802
  file = op.detect { |val| op.exist?(val) }
788
803
  op.remove(file) if file
789
- basepath(file || DEP_PYTHON[4])
804
+ basepath(file || DEP_PYTHON[6])
790
805
  end
791
806
  op.add_quote(ret)
792
807
  .clear
@@ -832,7 +847,7 @@ module Squared
832
847
  end
833
848
  print_run(op, banner, **kwargs)
834
849
  run(sync: sync, banner: banner, exception: exception?(**kwargs), from: symjoin('pip', flag))
835
- .yield_self { |val| ret || val }
850
+ .then { |val| ret || val }
836
851
  end
837
852
 
838
853
  def serve(root, opts = [], bind: 'localhost', port: nil, **)
@@ -1039,7 +1054,15 @@ module Squared
1039
1054
  end
1040
1055
  end
1041
1056
  ret.last[1] += val
1042
- elsif line.strip =~ /^(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*))$/
1057
+ elsif line.strip =~ /^(\S+)\s*=\s*
1058
+ (
1059
+ [+-]?(?:[\d._]+(?:[eE].+)?|0x[\dA-Fa-f]+|0[ob]\d+|nan|inf)
1060
+ |true|false
1061
+ |\d{4}-\d{2}-\d{2}.*
1062
+ |\d{2}:\d{2}.*
1063
+ |("""|'''|["'\[{])(.*)
1064
+ )$/x
1065
+ name = $1
1043
1066
  if (val = $4)
1044
1067
  case (ch = $3)
1045
1068
  when '{', '['
@@ -1059,11 +1082,21 @@ module Squared
1059
1082
  true
1060
1083
  when 'false'
1061
1084
  false
1085
+ when /^\d{4}-/
1086
+ Time.parse(ch)
1087
+ when /^\d{2}:/
1088
+ Time.strptime(ch, '%T')
1089
+ when /nan$/
1090
+ Float::NAN
1091
+ when /inf$/
1092
+ Float::INFINITY * (ch[0] == '-' ? -1 : 1)
1093
+ when /^[+-]?0[xob]/
1094
+ eval ch
1062
1095
  else
1063
1096
  ch.include?('.') ? ch.to_f : ch.to_i
1064
1097
  end
1065
1098
  end
1066
- ret << [$1, val]
1099
+ ret << [name, val]
1067
1100
  end
1068
1101
  if !ch && (val = ret.last[1]).is_a?(String) && (val.match?(/\A\{.+\}\z/m) || val.match?(/\A\[.+\]\z/m))
1069
1102
  ret.last[1] = JSON.parse(val) rescue nil
@@ -1082,7 +1115,7 @@ module Squared
1082
1115
  end
1083
1116
 
1084
1117
  def pyprojectfile
1085
- @pyprojectfile = basepath!(DEP_PYTHON[2]) || false if @pyprojectfile.nil?
1118
+ @pyprojectfile = basepath!(DEP_PYTHON[4]) || false if @pyprojectfile.nil?
1086
1119
  @pyprojectfile || nil
1087
1120
  end
1088
1121
 
@@ -1138,7 +1171,7 @@ module Squared
1138
1171
  if windows?
1139
1172
  shell_quote(venvbin.join(powershell? ? 'Activate.ps1' : 'activate.bat'), option: false)
1140
1173
  else
1141
- { 'VIRTUAL_ENV' => venv.to_s, 'PATH' => "#{venvbin}:#{ENV['PATH']}" }
1174
+ { 'VIRTUAL_ENV' => venv.to_s, 'PATH' => task_join(venvbin, ENV['PATH']) }
1142
1175
  end
1143
1176
  end
1144
1177
 
@@ -1220,6 +1253,8 @@ module Squared
1220
1253
  if poetry?
1221
1254
  dir += (windows? ? 'Scripts/python.exe' : 'bin/python')
1222
1255
  cmd = poetry_session 'env use'
1256
+ elsif pdm?
1257
+ cmd = pdm_session 'use -f'
1223
1258
  else
1224
1259
  puts "Success: #{dir}"
1225
1260
  return
@@ -1263,13 +1298,17 @@ module Squared
1263
1298
  end
1264
1299
 
1265
1300
  def setuptools?
1266
- dependtype == 2 || dependtype == 4
1301
+ dependtype == 4 || dependtype == 6
1267
1302
  end
1268
1303
 
1269
1304
  def poetry?
1270
1305
  dependtype == 1
1271
1306
  end
1272
1307
 
1308
+ def pdm?
1309
+ dependtype == 2
1310
+ end
1311
+
1273
1312
  def twine?
1274
1313
  venv_package?('twine')
1275
1314
  end
@@ -1279,7 +1318,7 @@ module Squared
1279
1318
  end
1280
1319
 
1281
1320
  def requirements?
1282
- dependtype == 5
1321
+ dependtype == 7
1283
1322
  end
1284
1323
  end
1285
1324
 
@@ -238,10 +238,10 @@ module Squared
238
238
  File.foreach(rakefile) do |line|
239
239
  next unless line.match?(%r{\brequire\s+(["'])bundler/gem_tasks\1})
240
240
 
241
- cmd = bundle_output('exec rake').to_s
242
- @output[0] = "#{cmd} build"
243
- @copy = "#{cmd} install"
244
- @clean = "#{cmd} clean" if @clean.nil?
241
+ cmd = "#{bundle_output('exec rake')} %s"
242
+ @output[0] = cmd % 'build'
243
+ @copy = cmd % 'install'
244
+ @clean = cmd % 'clean' if @clean.nil?
245
245
  break
246
246
  end
247
247
  rescue => e
@@ -331,7 +331,7 @@ module Squared
331
331
  opts = args.to_a
332
332
  cmd = opts.delete('::')
333
333
  if (n = opts.index('c'))
334
- args = opts.slice!(n.succ..-1)
334
+ args = opts.slice!(n.succ..)
335
335
  else
336
336
  file = opts.shift
337
337
  args = []
@@ -461,11 +461,13 @@ module Squared
461
461
  when :build, :push, :exec, :update
462
462
  format_desc(action, flag, 'opts*', after: case flag
463
463
  when :exec then 'command,args*'
464
- when :push then 'file/:'
464
+ when :push then 'file/:,d/dry-run?'
465
465
  when :update then 'name*'
466
466
  end)
467
467
  task flag do |_, args|
468
- gem(flag, opts: args.to_a, banner: true)
468
+ opts = args.to_a
469
+ filter = { dryrun: true } if flag == :push && has_value!(opts, 'd', 'dry-run')
470
+ gem(flag, opts: opts, banner: true, filter: filter)
469
471
  end
470
472
  when :install, :uninstall, :pristine
471
473
  format_desc(action, flag, 'opts*', after: flag == :pristine ? 'name*|name?@version' : 'name*')
@@ -572,13 +574,18 @@ module Squared
572
574
  else
573
575
  %w[## ;]
574
576
  end
575
- msg = if Prompt.reline.respond_to?(:readmultiline)
576
- 'ruby>'
577
- else
578
- multiline = Array(multiline)
579
- 'Enter script'
580
- end
581
- command = ENV['RUBY_E'] || readline(msg, force: true, multiline: multiline)
577
+ unless (command = ENV['RUBY_E'])
578
+ command = if Prompt.reline.respond_to?(:readmultiline)
579
+ require 'ripper'
580
+ readline('ruby>', force: true, multiline: multiline) do |code|
581
+ next if code.strip.empty? || !Ripper.sexp(code)
582
+
583
+ Array(multiline).any? { |s| code.split.last.match?(/(?<!#{s[-1]})#{s}$/) }
584
+ end
585
+ else
586
+ readline('Enter script', force: true, multiline: Array(multiline))
587
+ end
588
+ end
582
589
  ruby(flag, opts: args.to_a, command: command)
583
590
  end
584
591
  when :version
@@ -701,7 +708,7 @@ module Squared
701
708
  .lines
702
709
  .map { |line| line.sub(/#.*$/, '').strip }
703
710
  .reject(&:empty?)
704
- .yield_self do |lines|
711
+ .then do |lines|
705
712
  target = lines.find { |line| line.include?(tool) }
706
713
  target ? [target] : lines
707
714
  end
@@ -788,7 +795,7 @@ module Squared
788
795
  when '1', 'true' then nil
789
796
  else
790
797
  if val.start_with?('~')
791
- val = File.join(Dir.home, val == '~' ? '.bundle' : val[1..-1])
798
+ val = File.join(Dir.home, val == '~' ? '.bundle' : val[1..])
792
799
  if prod?
793
800
  config_set('binstubs', shell_quote(val), global: true)
794
801
  val = nil
@@ -978,8 +985,9 @@ module Squared
978
985
  if found > 0
979
986
  unless Array(items).empty?
980
987
  gems = if se
981
- choice('Select a package', items.map(&:first),
982
- multiple: true, force: false, index: true, border: true).map { |n| items[n.pred].last }
988
+ choice('Select a package', items.map(&:first), multiple: true, force: false, index: true,
989
+ border: true, **parse_select)
990
+ .map { |n| items[n.pred].last }
983
991
  else
984
992
  items.map(&:last)
985
993
  end
@@ -1013,13 +1021,17 @@ module Squared
1013
1021
  end
1014
1022
 
1015
1023
  def ruby(*args, sync: true, banner: verbose?, with: nil, pass: PASS_RUBY[:ruby], **kwargs)
1016
- if args.first.is_a?(Symbol)
1017
- flag = args.shift
1018
- from = symjoin 'ruby', flag
1019
- end
1020
- opts = session_opts(with, args: args, kwargs: kwargs, pass: pass)
1021
- op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, strict: strict?,
1022
- multiple: [/^-e/], args: true, stdin: true)
1024
+ from = if args.first.is_a?(Symbol)
1025
+ flag = args.shift
1026
+ symjoin 'ruby', flag
1027
+ else
1028
+ :ruby
1029
+ end
1030
+ op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass),
1031
+ OPT_RUBY[:ruby],
1032
+ ruby_session,
1033
+ project: self, strict: strict?, auto: %w[help version],
1034
+ multiple: [/^-e/], args: true, stdin: true)
1023
1035
  if kwargs[:command]
1024
1036
  op << quote_option('e', kwargs[:command])
1025
1037
  elsif kwargs[:file]
@@ -1040,8 +1052,8 @@ module Squared
1040
1052
  op.append(delim: true, escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
1041
1053
  end
1042
1054
  end
1043
- print_run(op, banner, **kwargs) unless flag
1044
- run(sync: sync, banner: banner, exception: exception?(**kwargs), from: from || :ruby)
1055
+ print_run(op, banner, **kwargs) unless flag || op.stdout
1056
+ run(sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from: from)
1045
1057
  end
1046
1058
 
1047
1059
  def gem(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -1213,8 +1225,9 @@ module Squared
1213
1225
  puts 'No updates were found'
1214
1226
  else
1215
1227
  if items
1216
- update = choice('Select a package', items.map(&:first),
1217
- multiple: true, force: false, index: true, border: true).map { |n| items[n.pred].last }
1228
+ update = choice('Select a package', items.map(&:first), multiple: true, force: false, index: true,
1229
+ border: true, **parse_select)
1230
+ .map { |n| items[n.pred].last }
1218
1231
  end
1219
1232
  unless Array(update).empty?
1220
1233
  opts = ['f']
@@ -1298,7 +1311,12 @@ module Squared
1298
1311
 
1299
1312
  op.add_path(file)
1300
1313
  end
1301
- return run(from: from, interactive: ['Push', 'N', target || gemname]) unless with || !banner
1314
+ if dryrun? || kwargs[:filter]&.fetch(:dryrun, nil)
1315
+ print_item "> #{op}"
1316
+ exit
1317
+ elsif !with && banner
1318
+ return run(from: from, interactive: ['Push', 'N', target || gemname])
1319
+ end
1302
1320
  when :exec
1303
1321
  min = if op.arg?('g', 'gem')
1304
1322
  1
@@ -1367,9 +1385,9 @@ module Squared
1367
1385
  name = op.remove_at(n)
1368
1386
  n = name.index('@')
1369
1387
  pre, ver = if n == 0
1370
- [gemname, name[1..-1]]
1388
+ [gemname, name[1..]]
1371
1389
  else
1372
- [name[0, n], name[n.succ..-1]]
1390
+ [name[0, n], name[n.succ..]]
1373
1391
  end
1374
1392
  op.adjoin(pre, quote_option('version', ver))
1375
1393
  .clear
@@ -1828,10 +1846,7 @@ module Squared
1828
1846
  set.call(ver, val)
1829
1847
  end
1830
1848
  end
1831
- if semgte?('2.6')
1832
- target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
1833
- parse.call(target.resolve_feature_path(gemname)&.last)
1834
- end
1849
+ parse.call($LOAD_PATH.resolve_feature_path(gemname)&.last)
1835
1850
  unless gemdir || pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
1836
1851
  raise Errno::ENOENT, 'gems home'
1837
1852
  end
@@ -2059,7 +2074,7 @@ module Squared
2059
2074
  end
2060
2075
 
2061
2076
  def gemlib
2062
- @gemlib ||= Set.new(['lib']).yield_self do |lib|
2077
+ @gemlib ||= Set.new(['lib']).then do |lib|
2063
2078
  if (spec = gemspec)
2064
2079
  lib.merge(spec.require_paths || [])
2065
2080
  end
@@ -153,7 +153,7 @@ module Squared
153
153
  return true if super
154
154
  return extras.include?(obj) unless (n = extras.index(@partition))
155
155
 
156
- extras[0..n].include?(obj)
156
+ extras[..n].include?(obj)
157
157
  end
158
158
 
159
159
  def multiple?(val)
@@ -19,7 +19,6 @@ module Squared
19
19
  class << self
20
20
  include Common::Format
21
21
  include Shell
22
- include Prompt
23
22
 
24
23
  def append(target, *args, delim: false, escape: false, quote: true, strip: nil, double: false, filter: nil,
25
24
  pass: nil, **kwargs)
@@ -82,7 +81,7 @@ module Squared
82
81
  kwargs[:hint] ||= 'unrecognized'
83
82
  append(target, opts, delim: true) if kwargs.delete(:append)
84
83
  warn log_warn(opts.join(', '), pass: true, **kwargs)
85
- exit 1 unless !strict && (pass || confirm("Run? [#{sub_style(target, styles)}]", 'N'))
84
+ exit 1 unless !strict && (pass || Common::Prompt.confirm("Run? [#{sub_style(target, styles)}]", 'N'))
86
85
  end
87
86
 
88
87
  def delete_key(target, *args, value: false, reverse: false, count: -1)
@@ -104,7 +103,7 @@ module Squared
104
103
  next if s.empty? || pass == i
105
104
 
106
105
  if s == '--'
107
- ret << s << args[i.succ..-1].join(' ')
106
+ ret << s << args[i.succ..].join(' ')
108
107
  break
109
108
  end
110
109
  next ret << s unless s.start_with?('-')
@@ -139,7 +138,7 @@ module Squared
139
138
  j = val =~ OPT_VALUE ? $1 : val
140
139
  (out[j] ||= []) << i unless pass.include?(j)
141
140
  end
142
- .map { |item| item[1].size > 1 ? item[1][0..-2] : [] }
141
+ .map { |item| item[1].size > 1 ? item[1][..-2] : [] }
143
142
  .reject(&:empty?)
144
143
  return if data.empty?
145
144
 
@@ -152,12 +151,12 @@ module Squared
152
151
  val = val.strip
153
152
  return [val, nil, ''] unless (i = val.index('='))
154
153
 
155
- last = val[i.succ..-1].strip
154
+ last = val[i.succ..].strip
156
155
  if last =~ /\A(["'])(.*)\1\z/m
157
156
  last = $2
158
157
  quote = $1
159
158
  end
160
- [val[0..i.pred], last, quote || '']
159
+ [val[...i], last, quote || '']
161
160
  end
162
161
 
163
162
  def parse_arg!(name, val)
@@ -174,7 +173,7 @@ module Squared
174
173
  r << matchopts(s, value) unless s.empty?
175
174
  a = target.to_a
176
175
  if (n = a.index('--'))
177
- a = a[0..n]
176
+ a = a[..n]
178
177
  end
179
178
  r.any? { |pat| a.any?(pat) }
180
179
  end
@@ -193,6 +192,8 @@ module Squared
193
192
  false
194
193
  end
195
194
 
195
+ alias filter select
196
+
196
197
  private
197
198
 
198
199
  def matchopt(val, value = false)
@@ -225,7 +226,7 @@ module Squared
225
226
  :merge, :compact, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
226
227
  def_delegators :@extras, :empty?, :member?, :each, :each_with_index, :each_with_object, :partition, :dup,
227
228
  :first, :shift, :unshift, :pop, :push, :concat, :index, :join, :detect, :map, :map!, :select,
228
- :select!, :reject, :slice, :slice!, :size
229
+ :select!, :filter, :filter!, :reject, :slice, :slice!, :size
229
230
 
230
231
  def_delegator :@extras, :delete, :remove
231
232
  def_delegator :@extras, :delete_at, :remove_at
@@ -272,7 +273,7 @@ module Squared
272
273
  x, y = val.split('|', 2)
273
274
  if y
274
275
  if (n = val.index('='))
275
- x += val[n..-1]
276
+ x += val[n..]
276
277
  end
277
278
  [x, y]
278
279
  else
@@ -321,7 +322,7 @@ module Squared
321
322
  bare.concat(mod)
322
323
  when '/'
323
324
  begin
324
- val = val[n.succ..-1]
325
+ val = val[n.succ..]
325
326
  pat = eval(val)
326
327
  raise SyntaxError unless pat.is_a?(Regexp)
327
328
 
@@ -330,7 +331,7 @@ module Squared
330
331
  warn "#{self.class}: invalid pattern (#{val})"
331
332
  end
332
333
  when '{'
333
- group = val[(n + 2)..-1].chomp!('}')&.split(',')
334
+ group = val[(n + 2)..].chomp!('}')&.split(',')
334
335
  if group
335
336
  mod.each { |key| ar[key] = group }
336
337
  else
@@ -405,7 +406,7 @@ module Squared
405
406
  break
406
407
  end
407
408
  end
408
- elsif opt.start_with?(/no[-_]/) && no.include?(s = opt[3..-1])
409
+ elsif opt.start_with?(/no[-_]/) && no.include?(s = opt[3..])
409
410
  add "--no-#{s}"
410
411
  else
411
412
  has = lambda do |list, key|
@@ -463,7 +464,7 @@ module Squared
463
464
  push opt
464
465
  end
465
466
  opt = key unless opt == last
466
- elsif has.call(m, key = opt[0]) && opt[1..-1] =~ QUOTE_VALUE
467
+ elsif has.call(m, key = opt[0]) && opt[1..] =~ QUOTE_VALUE
467
468
  add basic_option(key, $2, double: $1 == '"' || has.call(qq, key), **kwargs, merge: true)
468
469
  opt = key
469
470
  else
@@ -621,7 +622,7 @@ module Squared
621
622
  else
622
623
  args.each { |val| remove val }
623
624
  end
624
- args = temp[0, index] + args + temp[index..-1]
625
+ args = temp[0, index] + args + temp[index..]
625
626
  target.clear
626
627
  end
627
628
  merge args
@@ -215,8 +215,8 @@ module Squared
215
215
  opts << '--force-checkout'
216
216
  when 'rebase', 'detach'
217
217
  opts << "--#{val}"
218
- when /^(fetch-)?submodules$/
219
- opts << '--fetch-submodules' if repo_submodules?(true, **envargs)
218
+ when /^(recurse-)?submodules$/
219
+ opts << '--recurse-submodules' if repo_submodules?(true, **envargs)
220
220
  when /^(fail-)?fast$/
221
221
  opts << '--fail-fast'
222
222
  when /^no-(manifest-)?update$/
@@ -228,7 +228,7 @@ module Squared
228
228
  if (jobs = ENV['REPO_JOBS']) || opts.none?(/^--?j(obs)?$/)
229
229
  opts << "-j#{jobs || Rake::CpuCounter.count}"
230
230
  end
231
- opts << '--fetch-submodules' if repo_submodules?(**envargs)
231
+ opts << '--recurse-submodules' if repo_submodules?(**envargs)
232
232
  begin
233
233
  repo_run('sync', opts, exception: opts.include?('--fail-fast'), options: stage != 'init')
234
234
  rescue Errno::ENOENT => e
@@ -262,7 +262,7 @@ module Squared
262
262
  return false unless root.directory?
263
263
 
264
264
  path = sub_style root, theme[:inline]
265
- @repo_override = case env('REPO_Y')
265
+ @repo_override = case __arg__('YES', 'REPO') || env('REPO_Y')
266
266
  when '0', 'false'
267
267
  false
268
268
  when '1', 'true'
@@ -345,7 +345,7 @@ module Squared
345
345
  def repo_opts(*args)
346
346
  return args unless (n = ARGV.index('--'))
347
347
 
348
- ARGV[n.succ..-1].concat(args)
348
+ ARGV[n.succ..].concat(args)
349
349
  end
350
350
 
351
351
  def repo_submodules?(val = false, **kwargs)
@@ -9,6 +9,7 @@ module Squared
9
9
  extend Forwardable
10
10
 
11
11
  attr_reader :sync, :multiple, :parallel
12
+ attr_writer :ref_min
12
13
 
13
14
  def_delegators :@data, :[], :each, :each_key, :keys, :key?, :include?, :fetch, :update, :merge!, :any?, :none?,
14
15
  :delete, :delete_if, :find, :find_all, :to_a, :to_s, :inspect
@@ -19,6 +20,7 @@ module Squared
19
20
  @sync = []
20
21
  @multiple = []
21
22
  @parallel = []
23
+ @ref_min = 2
22
24
  @chain = {}
23
25
  @exclude = exclude.freeze
24
26
  @task = Struct::SeriesData.new(workspace.config_get(:rename))
@@ -56,7 +58,7 @@ module Squared
56
58
  @session = {
57
59
  group: Support.hashlist,
58
60
  parent: Support.hashlist,
59
- id: []
61
+ id: Set.new
60
62
  }.freeze
61
63
  end
62
64
 
@@ -85,7 +87,7 @@ module Squared
85
87
 
86
88
  def build(parallel: [], pattern: [], **)
87
89
  subcheck = ->(val) { (ns = task_namespace(val)) && parallel.include?(ns) }
88
- update @session[:parent] if @session[:id].uniq.size > 1
90
+ update @session[:parent] if @session[:id].size >= @ref_min
89
91
  update @session[:group]
90
92
  each do |key, items|
91
93
  next if exclude?(key, empty: true) || @workspace.task_exclude?(t = name_get(key))
data/squared.gemspec CHANGED
@@ -11,21 +11,23 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "Rake task generator for managing multi-language workspaces."
12
12
  spec.description = "Rake task generator for managing multi-language workspaces."
13
13
  spec.homepage = "https://github.com/anpham6/squared-ruby"
14
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15
15
  spec.licenses = ["BSD-3-Clause"]
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
19
19
  spec.metadata["documentation_uri"] = "https://squared.readthedocs.io"
20
20
 
21
- spec.files = Dir["lib/**/*"] +
22
- %w[CHANGELOG.md LICENSE README.md squared.gemspec]
23
21
  spec.bindir = "exe"
24
- spec.executables = []
22
+ spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
23
+
24
+ spec.files = Dir["exe/*"] + Dir["lib/**/*"] +
25
+ %w[CHANGELOG.md LICENSE README.md squared.gemspec]
25
26
  spec.require_paths = ["lib"]
26
27
 
27
28
  spec.add_dependency "rake"
29
+ spec.add_dependency "optparse"
28
30
  spec.add_dependency "logger"
29
31
  spec.add_dependency "rexml"
30
- spec.add_dependency "readline"
32
+ spec.add_dependency "reline"
31
33
  end