squared 0.5.19 → 0.5.21

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90e816457aa629a2416781e2480aa4025f0b5395eb41dc45157ecbb0d9a57262
4
- data.tar.gz: a03eca5dba74e2b6c3c6d6946291f788e5f3a75c84afa89a8e5139c325d3397a
3
+ metadata.gz: 422d0fe6f69fab606e4b0a218c2f4faae43fe6bb24a2e66f7e37ef2d0685019a
4
+ data.tar.gz: 53761c954112ee12a3f22756a2d140b2a86db9c6a0f6113ea05a3aa32f95f52a
5
5
  SHA512:
6
- metadata.gz: 3ec9a3d2105f6355485a71820b4631554dfe9a47a6b4fbfb36d690b09693cd54abad75877aa7b17fe235dadcf2f03c0508b5ea33dd0e3a67c69faa73ad6c19b4
7
- data.tar.gz: 8ed22f2ba7bb7195082d616ab085ead6e1795fa23a06f9bc48035206e1dedec4f146b2934711c2d88ac52e77b8c000838a517bdc8ddb616a3b0d5c1a9c608bd8
6
+ metadata.gz: 46c2e2f4a935003a2a773e157760b928d23445e57a1d2c4663eae322ac02b3f3b96091a1e122457c91621b7693199cb1f15f1ebea0f5349f8f536b1ac4cc3d06
7
+ data.tar.gz: 79e1beaddef54cad59db12a5ca864babe97933636f129f9797338d710bc0d928f38c1beb5882028a87670ea6aec217646ffafd6227ca7bd6b106ed77557f8f69
data/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.21] - 2025-12-31
4
+
5
+ ### Fixed
6
+
7
+ - See `0.4.35`.
8
+
9
+ ## [0.4.35] - 2025-12-31
10
+
11
+ ### Changed
12
+
13
+ - Ruby task copy uses GEM_HOME as fallback for autodetect.
14
+
15
+ ### Fixed
16
+
17
+ - Git commands [rebase|clone] did not forward sync flag.
18
+ - Pip command install carelessly used an undefined method.
19
+ - Common prompt method readline with multiline did not permit empty lines.
20
+ - Application method with using pass did not ignore exceptions.
21
+
22
+ ## [0.5.20] - 2025-12-26
23
+
24
+ ### Fixed
25
+
26
+ - Bundle config get method did not always discard newline.
27
+
28
+ ## [0.4.34] - 2025-12-26
29
+
30
+ ### Added
31
+
32
+ - Project public base method scope for nested tasks was created.
33
+ - Ruby task copy can autodetect "env" using [GEM_HOME|GEM_ROOT].
34
+
35
+ ### Changed
36
+
37
+ - Python virtual environment did not install poetry during initialization.
38
+
39
+ ### Fixed
40
+
41
+ - Workspace global banner never referenced the correct hash key.
42
+ - Python task depend without editable did not append context directory.
43
+ - Docker task build did not parse DOCKER_OPTIONS as command options.
44
+ - Project base method build did not call Method routines.
45
+ - Bundler autodetect did not check for valid gems directory.
46
+ - Ruby copy to version detection did not check for valid gemspec.
47
+
3
48
  ## [0.5.19] - 2025-12-07
4
49
 
5
50
  ### Fixed
@@ -1306,6 +1351,8 @@
1306
1351
 
1307
1352
  - Changelog was created.
1308
1353
 
1354
+ [0.5.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.21
1355
+ [0.5.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.20
1309
1356
  [0.5.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.19
1310
1357
  [0.5.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.18
1311
1358
  [0.5.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.17
@@ -1326,6 +1373,8 @@
1326
1373
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1327
1374
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1328
1375
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1376
+ [0.4.35]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.35
1377
+ [0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
1329
1378
  [0.4.33]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.33
1330
1379
  [0.4.32]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.32
1331
1380
  [0.4.31]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.31
data/README.md CHANGED
@@ -68,7 +68,7 @@ Workspace::Application
68
68
  .add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
69
69
  .add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
70
70
  .add("pi-r2", "pir2", copy: { from: :npm, also: %i[squared express], files: ["LICENSE", ["README.md.ruby", "README.md"]] }) # Uses dist files from NPM package spec
71
- .add("squared", init: 'pnpm', script: ["build:stage1", "build:stage2"], group: "app") do # Use pnpm/yarn/berry for depend + Copy target (main)
71
+ .add("squared", init: "pnpm", script: ["build:stage1", "build:stage2"], group: "app") do # Use pnpm/yarn/berry for depend + Copy target (main)
72
72
  # Repo (global)
73
73
  as(:run, "build:dev", "dev") # npm run build:dev -> npm run dev
74
74
  as(:run, { "build:dev": "dev", "build:prod": "prod" })
@@ -521,7 +521,7 @@ Commands which use commit hashes are parsed using a ":" prefix as to not be conf
521
521
 
522
522
  ```sh
523
523
  rake squared:log:view[:af012345] # git log af012345
524
- rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- 'lib' 'H12345'
524
+ rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- "lib" "H12345"
525
525
  ```
526
526
 
527
527
  ## Environment
@@ -676,7 +676,7 @@ DOCKER_ALL=1 # list every image/container
676
676
  DOCKER_Y=1 # confirm all
677
677
 
678
678
  BUILD_SQUARED_OPTS="NODE_TAG=24 RUBY_VERSION=3.4.0" DOCKER_SQUARED_OPTS="--no-cache --label=v1" rake squared:build
679
- docker build --no-cache --label=v1 --build-arg='NODE_TAG=24' --build-arg='RUBY_VERSION=3.4.0' .
679
+ docker build --no-cache --label=v1 --build-arg="NODE_TAG=24" --build-arg="RUBY_VERSION=3.4.0" .
680
680
  ```
681
681
 
682
682
  | Command | Flag | ENV |
@@ -65,8 +65,9 @@ module Squared
65
65
  while (ch = Readline.readline(msg))
66
66
  unless (ch = ch.strip).empty?
67
67
  if multiple
68
- a = ch.split(/\s*,\s*/)
68
+ a = ch.split(',')
69
69
  b = a.map do |s|
70
+ s.strip!
70
71
  if s =~ /^(\d+)-(\d+)$/
71
72
  next unless valid.call($1) && valid.call($2)
72
73
 
@@ -112,7 +113,11 @@ module Squared
112
113
  elsif block_given?
113
114
  Readline.readmultiline(msg, history, &blk)
114
115
  else
115
- Readline.readmultiline(msg, history) { |line| multiline.any? { |val| line.split.last.end_with?(val.to_s) } }
116
+ Readline.readmultiline(msg, history) do |line|
117
+ next if line.strip.empty?
118
+
119
+ multiline.any? { |val| line.split.last.end_with?(val.to_s) }
120
+ end
116
121
  end
117
122
  end
118
123
  case force
@@ -112,6 +112,7 @@ module Squared
112
112
  end
113
113
 
114
114
  def shell_bin(name, env: true)
115
+ require_relative 'base'
115
116
  key = name.to_s.upcase
116
117
  key = File.basename(key, '.*') if Rake::Win32.windows?
117
118
  shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.19'
4
+ VERSION = '0.5.21'
5
5
  end
@@ -179,7 +179,7 @@ module Squared
179
179
  end
180
180
 
181
181
  def with(*val, pass: false, group: nil, **kwargs, &blk)
182
- return self if pass == true || (pass && Array(pass).map(&:to_s).any? { |s| respond_to?(s) && __send__(s) })
182
+ return self if pass == true || (pass && as_a(pass, :to_s).any? { |s| respond_to?(s) && __send__(s) rescue nil })
183
183
 
184
184
  @group = nil
185
185
  @ref = nil
@@ -274,9 +274,9 @@ module Squared
274
274
 
275
275
  def pass(name, group: @group, ref: @ref, &blk)
276
276
  data = if group
277
- @pass[:group][group]
277
+ @pass[:group][group.to_s]
278
278
  elsif ref
279
- @pass[:ref][ref]
279
+ @pass[:ref][ref.to_sym]
280
280
  else
281
281
  @pass[:global]
282
282
  end
@@ -580,7 +580,7 @@ module Squared
580
580
  return ret if group && (ret = @banner[:group][group.to_sym])
581
581
 
582
582
  ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
583
- @banner[:ref][:'']
583
+ @banner[:ref][:_]
584
584
  end
585
585
 
586
586
  def enabled?
@@ -503,8 +503,14 @@ module Squared
503
503
  cmd = []
504
504
  var = {}
505
505
  args.each do |val|
506
- next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
507
-
506
+ case val.first
507
+ when Proc
508
+ instance_exec(*val[1..-1], &val.first)
509
+ next
510
+ when Method
511
+ val.first.call(*val[1..-1])
512
+ next
513
+ end
508
514
  a, b, c, d, e = val
509
515
  case b
510
516
  when Hash
@@ -828,6 +834,7 @@ module Squared
828
834
  end
829
835
  cmd << name << version
830
836
  when :exec
837
+ cmd << name unless opts.first.start_with?(/#{name}\b/)
831
838
  cmd.merge(opts)
832
839
  when :current
833
840
  cmd << '--no-header' unless legacy
@@ -927,6 +934,12 @@ module Squared
927
934
  end
928
935
  end
929
936
 
937
+ def scope(*args, **kwargs, &blk)
938
+ namespace name do
939
+ task(*args, **kwargs, &blk)
940
+ end
941
+ end
942
+
930
943
  def variable_set(key, *args, **kwargs, &blk)
931
944
  if block_given?
932
945
  if blocks.include?(key)
@@ -968,7 +981,8 @@ module Squared
968
981
  when :env
969
982
  run_set(output[0], *args, **kwargs)
970
983
  when :dependfile
971
- @dependfile = basepath(*args)
984
+ @dependindex = nil
985
+ @dependfile = val.nil? ? nil : basepath(*args)
972
986
  else
973
987
  instance_variable_set(:"@#{key}", val)
974
988
  end
@@ -1122,8 +1136,7 @@ module Squared
1122
1136
  begin
1123
1137
  cmd.flatten.each { |val| run(val, env, sync: sync, banner: banner, **kwargs) }
1124
1138
  rescue StandardError => e
1125
- ret = on :error, from, e
1126
- raise unless ret == true
1139
+ on_error(e, from, exception: kwargs.fetch(:exception, exception))
1127
1140
  end
1128
1141
  on :last, from
1129
1142
  end
@@ -262,21 +262,20 @@ module Squared
262
262
  def compose(opts, flags = nil, script: false, args: nil, from: :run, **)
263
263
  return opts if script == false
264
264
 
265
- ret = docker_session
266
265
  if from == :run
267
266
  if bake?(n = filetype)
268
- ret << 'buildx bake'
267
+ ret = docker_session 'buildx bake'
269
268
  append_file n
270
269
  from = :bake
271
270
  elsif compose?(n)
272
- ret << 'compose build'
271
+ ret = docker_session 'compose build'
273
272
  append_file n
274
273
  from = :compose
275
274
  else
276
- ret << 'build'
275
+ ret = docker_session 'build'
277
276
  end
278
277
  else
279
- ret << from
278
+ ret = docker_session from
280
279
  end
281
280
  case opts
282
281
  when String
@@ -694,8 +693,8 @@ module Squared
694
693
  end
695
694
  end
696
695
 
697
- def list_image(flag, cmd, hint: nil, from: nil, no: true)
698
- pwd_set do
696
+ def list_image(flag, cmd, hint: nil, no: true, from: nil)
697
+ pwd_set(from: from) do
699
698
  found = false
700
699
  index = 0
701
700
  all = option('all', prefix: 'docker')
@@ -1050,7 +1050,7 @@ module Squared
1050
1050
 
1051
1051
  cmd << "--#{command}"
1052
1052
  end
1053
- source
1053
+ source(sync: sync)
1054
1054
  end
1055
1055
 
1056
1056
  def autostash(*, sync: invoked_sync?('autostash'), **)
@@ -1094,7 +1094,7 @@ module Squared
1094
1094
  append_hash opts
1095
1095
  cmd << '--quiet' unless verbose
1096
1096
  append_value(data[0], path, delim: true)
1097
- source(banner: sync && !quiet?, multiple: !sync || quiet?)
1097
+ source(sync: sync, banner: sync && !quiet?, multiple: !sync || quiet?)
1098
1098
  end
1099
1099
 
1100
1100
  def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
@@ -1840,7 +1840,7 @@ module Squared
1840
1840
  return args ? [IO.popen(cmd), banner || '', from] : IO.popen(cmd)
1841
1841
  elsif stdin? ? sync : stdout
1842
1842
  print_item banner unless multiple
1843
- ret = `#{cmd}`
1843
+ ret = `#{cmd}`.chomp
1844
1844
  if !ret.empty?
1845
1845
  puts ret
1846
1846
  elsif success?(!banner.nil?)
@@ -27,7 +27,8 @@ module Squared
27
27
  use-running-store-server use-store-server child-concurrency=i hoist-pattern=q lockfile-dir=p
28
28
  modules-dir=p network-concurrency=i package-import-method=b public-hoist-pattern=q
29
29
  reporter=b].freeze,
30
- install_base: %w[global-dir ignore-scripts offline prefer-offline store-dir=p virtual-store-dir=p].freeze,
30
+ install_base: %w[dangerously-allow-all-builds global-dir ignore-scripts offline prefer-offline store-dir=p
31
+ virtual-store-dir=p].freeze,
31
32
  install_no: %w[frozen-lockfile verify-store-integrity].freeze,
32
33
  install_as: %w[D|dev no-optional P|prod].freeze,
33
34
  update: %w[g|global i|interactive L|latest depth=i].freeze,
@@ -456,6 +457,7 @@ module Squared
456
457
  split_escape(val).each { |opt| cmd << shell_option('public-hoist-pattern', opt) }
457
458
  end
458
459
  cmd << '--ignore-workspace' if env('NODE_WORKSPACES', equals: '0')
460
+ cmd << '--dangerously-allow-all-builds' if option('approve-builds')
459
461
  append_nocolor
460
462
  else
461
463
  cmd = session 'npm', 'install'
@@ -684,7 +686,7 @@ module Squared
684
686
  log.info cmd.to_s
685
687
  end
686
688
  if sync
687
- run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
689
+ run(sync: sync, from: from, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
688
690
  else
689
691
  require 'open3'
690
692
  on :first, from
@@ -806,7 +808,7 @@ module Squared
806
808
  raise_error('version not found', hint: dependfile)
807
809
  end
808
810
  rescue StandardError => e
809
- on_error e, :bump
811
+ on_error(e, :bump, dryrun: dryrun?)
810
812
  end
811
813
  end
812
814
 
@@ -30,15 +30,15 @@ module Squared
30
30
  OPT_POETRY = {
31
31
  common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose P|project=p].freeze,
32
32
  build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
33
- publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=b r|repository=q
34
- u|username=b].freeze
33
+ publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=q r|repository=q
34
+ u|username=qq].freeze
35
35
  }.freeze
36
36
  OPT_PDM = {
37
37
  common: %w[I|ignore-python no-cache n|non-interactive].freeze,
38
38
  build: %w[C=bm no-clean no-isolation no-sdist no-wheel quiet verbose config-setting=q d|dest=p p|project=p
39
39
  k|skip=b].freeze,
40
40
  publish: %w[no-build no-very-ssl quiet S|sign skip-existing verbose ca-certs=p c|comment=q d|dest=p
41
- i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=b].freeze
41
+ i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
42
42
  }.freeze
43
43
  OPT_HATCH = {
44
44
  common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
@@ -50,7 +50,7 @@ module Squared
50
50
  OPT_TWINE = {
51
51
  publish: %w[attestations disable-progress-bar non-interactive s|sign skip-existing verbose cert=p
52
52
  client-cert=p c|comment=q config-file=p i|identity=b p|password=q r|repository=b repository-url=q
53
- sign-with=b u|username=q].freeze
53
+ sign-with=b u|username=qq].freeze
54
54
  }.freeze
55
55
  private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE
56
56
 
@@ -352,6 +352,7 @@ module Squared
352
352
  cmd << '--no-root' if option('no-root')
353
353
  else
354
354
  cmd = pip_session 'install'
355
+ cmd << '--upgrade-strategy=eager' if env('PYTHON_UPDATE')
355
356
  if flag
356
357
  case flag
357
358
  when :user
@@ -506,7 +507,6 @@ module Squared
506
507
  if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
507
508
  op.add_path(outdir)
508
509
  end
509
- op << basic_option('p', project) unless ENV['HATCH_PROJECT'] || op.arg?('p', 'project')
510
510
  else
511
511
  unless op.empty?
512
512
  args = case flag
@@ -595,17 +595,21 @@ module Squared
595
595
  end
596
596
  case key
597
597
  when :dependfile
598
- req = basepath(*val)
599
- if (index = DEP_PYTHON.index(req.basename.to_s))
600
- @dependindex = index
601
- @dependfile = req
598
+ if val.first.nil?
599
+ super
602
600
  else
603
- log.warn "variable_set: @#{key}=#{req} (not supported)"
601
+ req = basepath(*val)
602
+ if (index = DEP_PYTHON.index(req.basename.to_s))
603
+ @dependindex = index
604
+ @dependfile = req
605
+ else
606
+ log.warn "variable_set: @#{key}=#{req} (not supported)"
607
+ end
604
608
  end
605
609
  when :editable
606
610
  editable_set val.first
607
611
  when :venv
608
- instance_variable_set(:"@#{key}", val.empty? ? nil : basepath(*val))
612
+ @venv = val.empty? || val.first.nil? ? nil : basepath(*val)
609
613
  else
610
614
  super
611
615
  end
@@ -626,10 +630,11 @@ module Squared
626
630
  end
627
631
 
628
632
  def python_session(*cmd, opts: nil)
629
- return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
633
+ pre = preopts(quiet: false)
634
+ return session('python', *pre, *cmd, path: venv.nil?) unless opts
630
635
 
631
636
  op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
632
- ret = session('python', *op.to_a, *cmd, path: venv.nil?)
637
+ ret = session('python', *pre, *op.to_a, *cmd, path: venv.nil?)
633
638
  [ret, op.extras]
634
639
  end
635
640
 
@@ -650,8 +655,8 @@ module Squared
650
655
  def create_session(*cmd, name:, common:, opts: nil)
651
656
  return session(name, *preopts, *cmd, path: venv.nil?) unless opts
652
657
 
653
- op = OptionPartition.new(opts, common, project: self, single: singleopt)
654
- ret = session(name, *op.to_a, *cmd, path: venv.nil?)
658
+ op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
659
+ ret = session(name, *preopts, *op.to_a, *cmd, path: venv.nil?)
655
660
  [ret, op.extras]
656
661
  end
657
662
 
@@ -706,14 +711,16 @@ module Squared
706
711
  OptionPartition.delete_key(target, 'e', 'editable')
707
712
  case val
708
713
  when '0', 'false'
709
- return
714
+ return unless installable?
710
715
  else
711
716
  val = basepath val
712
717
  end
713
- elsif session_arg?('e', 'editable', target: target) || !(val = editable)
718
+ elsif session_arg?('e', 'editable', target: target) || !installable?
714
719
  return
720
+ else
721
+ val = editable
715
722
  end
716
- target << quote_option('e', basepath(val))
723
+ target << (val ? quote_option('e', basepath(val)) : '.')
717
724
  end
718
725
 
719
726
  def append_global(target: @session)
@@ -889,9 +896,14 @@ module Squared
889
896
  .clear(pass: false)
890
897
  .arg?(/\A-v+\z/)
891
898
  run(op, env, exception: true, banner: banner)
899
+ install(:upgrade, ['poetry']) if poetry?
892
900
  puts(dir.directory? ? "Success: #{dir}" : 'Failed') if banner && !status
893
901
  end
894
902
 
903
+ def installable?
904
+ setuptools? || !!pyprojectfile
905
+ end
906
+
895
907
  def setuptools?
896
908
  dependtype == 2 || dependtype == 4
897
909
  end
@@ -893,7 +893,16 @@ module Squared
893
893
  def copy?
894
894
  return true if @copy.is_a?(Hash) ? copy[:into] : super
895
895
  return gemdir? if gemdir
896
+ return false unless @autodetect
897
+
898
+ set = lambda do |val, path|
899
+ base = Pathname.new(path.strip)
900
+ return false unless base.join(gempath(val, 'specifications')).exist?
896
901
 
902
+ log.warn "using version #{val} (given #{version})" if version && version != val
903
+ self.version = val
904
+ self.gemdir = base + gempath
905
+ end
897
906
  if version
898
907
  begin
899
908
  case @autodetect
@@ -904,38 +913,28 @@ module Squared
904
913
  self.gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
905
914
  end
906
915
  when 'asdf'
907
- val = pwd_set { `asdf where ruby` }
916
+ val = pwd_set { `asdf where ruby`.chomp }
908
917
  self.gemdir = File.join(val, 'lib/ruby/gems', "#{$1}.0") if val =~ /(\d\.\d)\.[^.]+$/
909
918
  when /bundler?/
910
- self.gemdir = pwd_set { `bundle env` }[/^\s+Gem Home\s+(.+)$/, 1]
919
+ path = pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1]
920
+ self.gemdir = path.split(File::PATH_SEPARATOR).find { |val| Dir.exist?(val) }
921
+ else
922
+ self.gemdir = ENV['GEM_HOME'] || ENV['GEM_ROOT']
911
923
  end
924
+ return true if gemdir?
912
925
  rescue StandardError => e
913
926
  log.debug e
914
927
  end
915
- return true if gemdir?
916
- end
917
- return false unless @autodetect
918
-
919
- set = lambda do |val, path|
920
- if (ver = version) && ver != val
921
- log.warn "using version #{val} (given #{ver})"
922
- end
923
- self.version = val
924
- self.gemdir = Pathname.new(path.strip) + gempath
925
- end
926
- if version
927
- opt = gempwd
928
- pwd_set(pass: !opt.nil?) do
929
- out = `#{gem_output(opt, 'list --local -d', gemname)}`
930
- if out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
928
+ pwd_set(pass: !gempwd.nil?) do
929
+ out = `#{gem_output(gempwd, 'list --local -d', gemname)}`
930
+ if out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
931
931
  split_escape($1)
932
932
  .unshift(version)
933
933
  .uniq
934
934
  .each do |val|
935
- next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
935
+ next unless out =~ /(?:\(#{Regexp.escape(val)}[^)]*\)|Installed at):\s+(.+)$/
936
936
 
937
- set.call(val, $1)
938
- return gemdir? if gemdir
937
+ return gemdir? if set.call(val, $1)
939
938
  end
940
939
  end
941
940
  end
@@ -1029,19 +1028,19 @@ module Squared
1029
1028
  end
1030
1029
 
1031
1030
  def config_get(key)
1032
- ret = if pwd_set { `#{bundle_output('config get --parseable', key)}` } =~ /\A([^=]+)=(.*)\z/ && $1 == key
1033
- $2.chomp
1034
- end
1035
- case ret
1031
+ out = pwd_set { `#{bundle_output('config get --parseable', key)}`.chomp }
1032
+ return unless out =~ /\A([^=]+)=(.*)\z/ && $1 == key
1033
+
1034
+ case (out = $2)
1036
1035
  when 'true'
1037
1036
  true
1038
1037
  when '', '[]'
1039
1038
  nil
1040
1039
  else
1041
- if ret =~ /\A\[:(.+)\]\z/
1042
- $1.split(', :').map! { |val| ((val.delete_prefix!('"') && val.delete_suffix!('"')) || val).to_sym }
1040
+ if out =~ /\A\[:(.+)\]\z/
1041
+ $1.split(', :').map { |val| ((val.delete_prefix!('"') && val.delete_suffix!('"')) || val).to_sym }
1043
1042
  else
1044
- ret || false
1043
+ out || false
1045
1044
  end
1046
1045
  end
1047
1046
  end
@@ -1109,8 +1108,10 @@ module Squared
1109
1108
  end
1110
1109
  end
1111
1110
 
1112
- def gempath(val = version)
1113
- File.join('gems', "#{gemname}-#{val}")
1111
+ def gempath(val = version, dir = 'gems')
1112
+ ret = File.join(dir, "#{gemname}-#{val}")
1113
+ ret += '.gemspec' if dir == 'specifications'
1114
+ ret
1114
1115
  end
1115
1116
 
1116
1117
  def gemdir?
@@ -135,9 +135,9 @@ module Squared
135
135
 
136
136
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
137
137
  :merge, :compact, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
138
- def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
139
- :pop, :push, :concat, :index, :join, :map, :map!, :detect, :select, :select!, :reject, :size,
140
- :delete_at
138
+ def_delegators :@extras, :empty?, :member?, :each, :each_with_index, :each_with_object, :partition, :dup,
139
+ :first, :shift, :unshift, :pop, :push, :concat, :index, :join, :map, :map!, :detect, :select,
140
+ :select!, :reject, :size
141
141
 
142
142
  def_delegator :@extras, :delete, :remove
143
143
  def_delegator :@extras, :delete_at, :remove_at
@@ -229,9 +229,8 @@ module Squared
229
229
 
230
230
  path = sub_style(root, styles: theme[:inline])
231
231
  @repo_override = Common::Prompt.confirm(
232
- "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation?",
233
- 'N',
234
- timeout: env('REPO_TIMEOUT', 15, ignore: '0')
232
+ "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation?", 'N',
233
+ timeout: env('REPO_TIMEOUT').to_i.yield_self { |n| n > 0 ? n : 15 }
235
234
  )
236
235
  end
237
236
 
@@ -31,7 +31,10 @@ module Squared
31
31
  end
32
32
  elsif (data = TASK_BATCH[obj])
33
33
  args.each { |ref| data.delete(ref) }
34
- TASK_KEYS.delete(obj) if data.empty?
34
+ if data.empty?
35
+ TASK_KEYS.delete(obj)
36
+ TASK_BATCH.delete(obj)
37
+ end
35
38
  end
36
39
  end
37
40
 
@@ -40,6 +43,7 @@ module Squared
40
43
  obj.each { |key, val| TASK_ALIAS[key][ref] = val }
41
44
  elsif TASK_ALIAS.key?(obj)
42
45
  TASK_ALIAS[obj].delete(ref)
46
+ TASK_ALIAS.delete(obj) if TASK_ALIAS[obj].empty?
43
47
  end
44
48
  end
45
49
 
@@ -191,7 +195,7 @@ module Squared
191
195
  TASK_EXTEND[key].each do |kind|
192
196
  next unless obj.is_a?(kind)
193
197
 
194
- if kind.instance_methods.include?(meth)
198
+ if kind.method_defined?(meth)
195
199
  out = obj.__send__(meth)
196
200
  return true if out == 1
197
201
  return out if obj.ref?(kind.ref)
@@ -232,7 +236,7 @@ module Squared
232
236
  end
233
237
 
234
238
  def exclude?(key, empty = false)
235
- @exclude.include?(key) || (empty && @data[key].empty?)
239
+ @exclude.include?(key) || (empty && (!@data.key?(key) || @data[key].empty?))
236
240
  end
237
241
 
238
242
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.19
4
+ version: 0.5.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  requirements: []
127
- rubygems_version: 3.6.9
127
+ rubygems_version: 4.0.3
128
128
  specification_version: 4
129
129
  summary: Rake task generator for managing multi-language workspaces.
130
130
  test_files: []