squared 0.6.16 → 0.6.18

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: a26491045e0e9a54898e1d36dd86702354e6ae5c13fd26f81cb8a3f40a495782
4
- data.tar.gz: 945d788953e1a6fc6fbd8630d68653fd19b1e4f70fb2ffce4645661ffe4ed00e
3
+ metadata.gz: 610a359081c94c9a38364e97e392a3e8f380eeb5d4b676df490640e00f32c89b
4
+ data.tar.gz: 5cede396fcf2a352dddb44a2df4cb2befa87e87359c8093f3b909fe05cab58a4
5
5
  SHA512:
6
- metadata.gz: 8cd5453e7e5a42d466eaf17b56775ac19b2d7e1c2e2a04d2d4daf68bc4ca0700cbed58037c70f0bd101e9e55f0667f2cee30e014714548cf6d05dbb1390bc9bb
7
- data.tar.gz: 68bc4817d3f0ea3d99197e23dad1e21f94ad70dbc0c1afb96cbc4fab5e6bc9a7fcf85a8e6c80d90616367ea5cbe7db92cebdf95207c6a299d5ed2d68cf781edd
6
+ metadata.gz: 47264b07af707f8053591cdce3d9dce6a9fdf8cd6fa051d41745e604cb89cd5c1de571da1dcb7ae816236989aafbb1d742b83cea9c937cb2e64dd4f92f362212
7
+ data.tar.gz: d2bbf7f1895fa7d4b1fb4017ad371adff3921b26fe6fb14d21d10306f1b8ca701b01ae5d1cf0dc0ceb454d1625a30f47e128165aae65c55e48c9ea9d10f799e7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.18] - 2026-09-04
4
+
5
+ ### Added
6
+
7
+ - Docker command bake action buildx with first arg "-" inherits base args.
8
+
9
+ ### Fixed
10
+
11
+ - Git action grep did not recognize format and max-count.
12
+ - Node command nvm did not quote executable path.
13
+
14
+ ## [0.5.26] - 2026-09-04
15
+
16
+ ### Fixed
17
+
18
+ - Node command nvm did not quote executable path.
19
+
20
+ ## [0.4.41] - 2026-09-04
21
+
22
+ ### Added
23
+
24
+ - Common base argument SUCCESS for command confirmation was created.
25
+
26
+ ### Changed
27
+
28
+ - Program options prefer using quotes instead of escape.
29
+ - Docker container run arguments with a leading dash are concatenated.
30
+
31
+ ### Fixed
32
+
33
+ - Common prompt method choice did not grep list items.
34
+ - OptionPartition static method strip did not parse flags with dashes.
35
+ - Project base method choice_index did not support multiple selections.
36
+
37
+ ## [0.6.17] - 2026-08-06
38
+
39
+ ### Added
40
+
41
+ - NPM command install can bypass engines with ENV and engine-strict=false.
42
+
43
+ ### Fixed
44
+
45
+ - Ruby command gem action push interactive file selector did nothing.
46
+ - Git choice prompt did not permit optional empty values.
47
+
48
+ ## [0.4.40] - 2026-08-06
49
+
50
+ ### Changed
51
+
52
+ - Series method exclude? was made compatible with v0.8 signature.
53
+
3
54
  ## [0.6.16] - 2026-07-04
4
55
 
5
56
  ### Added
@@ -1740,6 +1791,8 @@
1740
1791
 
1741
1792
  - Changelog was created.
1742
1793
 
1794
+ [0.6.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.18
1795
+ [0.6.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.17
1743
1796
  [0.6.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.16
1744
1797
  [0.6.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.15
1745
1798
  [0.6.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.14
@@ -1757,6 +1810,7 @@
1757
1810
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1758
1811
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1759
1812
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1813
+ [0.5.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.26
1760
1814
  [0.5.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.25
1761
1815
  [0.5.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.24
1762
1816
  [0.5.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.23
@@ -1783,6 +1837,8 @@
1783
1837
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1784
1838
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1785
1839
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1840
+ [0.4.41]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.41
1841
+ [0.4.40]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.40
1786
1842
  [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
1787
1843
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
1788
1844
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
@@ -14,6 +14,7 @@ module Squared
14
14
  CHOICE: 25,
15
15
  QUOTE: "'",
16
16
  SPACE: ' => ',
17
+ SUCCESS: 'Success',
17
18
  GRAPH: %w[| - | \\ -].freeze,
18
19
  BORDER: %w[| - - - - - | | - -].freeze,
19
20
  VIEW: 'view',
@@ -91,6 +92,13 @@ module Squared
91
92
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
92
93
  end
93
94
 
95
+ def __arg__(key, name = nil, &blk)
96
+ ret = ARG[key.to_sym]
97
+ return ret unless name && ret.is_a?(::Hash)
98
+
99
+ ret[name = name.downcase] || (block_given? ? ret.fetch(name.to_sym, &blk) : ret[name.to_sym])
100
+ end
101
+
94
102
  def __freeze__
95
103
  PATH.freeze
96
104
  ARG.freeze
@@ -56,11 +56,12 @@ module Squared
56
56
  def choice(msg, list = nil, min: 1, max: 1, multiple: false, index: false, grep: nil, border: nil, auto: true,
57
57
  force: true, attempts: 3, timeout: 0)
58
58
  require 'timeout'
59
+ multiple = Array(multiple) if multiple.is_a?(::Numeric)
59
60
  if list
60
61
  grep &&= Array(grep).map { |val| Regexp.new(val) }
61
62
  items = []
62
63
  list.each do |val|
63
- next if grep&.none? { |pat| pat.match?(line) }
64
+ next if grep&.none? { |pat| pat.match?(val) }
64
65
 
65
66
  items << val.to_s.chomp
66
67
  puts '%2d. %s' % [items.size, val]
@@ -77,11 +78,11 @@ module Squared
77
78
  puts print_footer(border: border)
78
79
  end
79
80
  msg = "#{msg + (force ? ':' : '?')} [#{min}-#{max}#{if (n = multiple)
80
- "|,#{n.is_a?(::Numeric) ? "{#{n}}" : '*'}"
81
+ "|,#{n.is_a?(::Array) ? "{#{n.join(',')}}" : '*'}"
81
82
  end}] "
82
83
  end
83
84
  end
84
- between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
85
+ between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max <= min ? Float::INFINITY : max) }
85
86
  Timeout.timeout(timeout) do
86
87
  while (ch = Readline.readline(msg))
87
88
  unless (ch = ch.strip).empty?
@@ -106,8 +107,8 @@ module Squared
106
107
  k.flatten!
107
108
  k.uniq!
108
109
  k.sort!
109
- unless multiple.is_a?(::Numeric) && multiple != k.size
110
- return index || !items ? k : k.map! { |i| items[i.pred] }
110
+ unless multiple.is_a?(::Array) && !multiple.include?(k.size)
111
+ return index || !items ? k : k.map { |i| items[i.pred] }
111
112
  end
112
113
  end
113
114
  elsif between.call(ch)
@@ -136,7 +136,7 @@ module Squared
136
136
  end
137
137
 
138
138
  def env_key(*val)
139
- val.join('_').gsub(/\W+/, '_').upcase
139
+ val.join('_').sub(/\A\d+\W*/, '__').gsub(/\W+/, '_').upcase
140
140
  end
141
141
 
142
142
  def env_value(key, default = '', suffix: nil, strict: false)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.16'
4
+ VERSION = '0.6.18'
5
5
  end
@@ -1409,7 +1409,7 @@ module Squared
1409
1409
  def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
1410
1410
  name = "#{key}_#{@envname}"
1411
1411
  ret = if suffix
1412
- ENV.fetch("#{name}_#{suffix}", '')
1412
+ ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1413
1413
  elsif strict
1414
1414
  ENV[name].to_s
1415
1415
  else
@@ -1532,7 +1532,7 @@ module Squared
1532
1532
  end
1533
1533
 
1534
1534
  def print_success
1535
- puts 'Success'
1535
+ puts ARG[:SUCCESS]
1536
1536
  end
1537
1537
 
1538
1538
  def print_error(*args, loglevel: Logger::WARN, **kwargs)
@@ -1711,7 +1711,7 @@ module Squared
1711
1711
  end
1712
1712
 
1713
1713
  def append_hash(data, target: @session || [], build: false)
1714
- if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1714
+ if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1715
1715
  if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
1716
1716
  data = data.merge(extra)
1717
1717
  else
@@ -1918,8 +1918,8 @@ module Squared
1918
1918
  args
1919
1919
  end
1920
1920
 
1921
- def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
1922
- return true if prefix ? option('y', prefix: prefix) : target && option('y', target: target)
1921
+ def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
1922
+ return true if option('y', prefix: prefix)
1923
1923
 
1924
1924
  confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
1925
1925
  end
@@ -1969,7 +1969,10 @@ module Squared
1969
1969
  if accept
1970
1970
  hint = Array(ret).map { |val| sub_style(val.to_s, theme[:inline]) }.join(', ')
1971
1971
  accept = Array(accept).map { |val| Array(val) }
1972
- ret = Array(ret) if accept.any? { |val| val[1] == true }
1972
+ if accept.any? { |val| val[1] == true }
1973
+ ret = [ret]
1974
+ multiple = -1
1975
+ end
1973
1976
  loop do
1974
1977
  item = accept.first
1975
1978
  c = confirm("#{item[0]}#{" [#{hint}]" if hint}", item[2] ? 'Y' : 'N')
@@ -1985,7 +1988,7 @@ module Squared
1985
1988
  exit 1 unless accept.empty?
1986
1989
  end
1987
1990
  if values
1988
- ret = Array(ret)
1991
+ ret = [ret] unless accept && multiple == -1
1989
1992
  Array(values).each do |val|
1990
1993
  if val.is_a?(Array)
1991
1994
  val, force = val
@@ -2516,6 +2519,10 @@ module Squared
2516
2519
  ARG[:BANNER] && !env('BANNER', equals: '0')
2517
2520
  end
2518
2521
 
2522
+ def dryrun?(*, target: @session, prefix: target&.first)
2523
+ Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2524
+ end
2525
+
2519
2526
  def pwd?
2520
2527
  path == Pathname.pwd
2521
2528
  end
@@ -21,14 +21,14 @@ module Squared
21
21
  }.freeze,
22
22
  compose: {
23
23
  common: %w[all-resources ansi=b compatibility dry-run env-file=p f|file=p parallel=n profile=b progress=b
24
- project-directory=p p|project-name=e].freeze,
24
+ project-directory=p p|project-name=b].freeze,
25
25
  build: %w[check no-cache print pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
26
26
  provenance=q sbom=q ssh=qq].freeze,
27
27
  create: %w[build force-recreate no-build no-recreate quiet-pull remove-orphans y|yes pull=b scale=i].freeze,
28
- exec: %w[d|detach privileged e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
28
+ exec: %w[d|detach privileged e|env=qq index=i T|no-tty=!? user=b w|workdir=q].freeze,
29
29
  run: %w[build d|detach no-deps q|quiet quiet-build quiet-pull remove-orphans rm P|service-ports use-aliases
30
30
  cap-add=b cap-drop=b entrypoint=q e|env=qq env-from-file=p i|interactive=b? l|label=q name=b
31
- T|no-TTY=b? p|publish=q pull=b u|user=e v|volume=q w|workdir=q].freeze,
31
+ T|no-tty=!? p|publish=q pull=b u|user=b v|volume=qq w|workdir=q].freeze,
32
32
  up: %w[abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
33
33
  d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
34
34
  quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
@@ -37,9 +37,9 @@ module Squared
37
37
  }.freeze,
38
38
  container: {
39
39
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
40
- rm t|tty use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i blkio-weight-device=i
41
- cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q device-cgroup-rule=q
42
- device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
40
+ rm t|tty=!? use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i
41
+ blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q
42
+ device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
43
43
  dns=q dns-option=q dns-search=q domainname=b entrypoint=q e|env=qq env-file=p expose=q gpus=q
44
44
  group-add=b health-cmd=q health-interval=b health-retries=i health-start-interval=q
45
45
  health-start-period=q health-timeout=q hostname=q io-maxbandwidth=b io-maxiops=b ip=b ip6=q ipc=b
@@ -47,13 +47,14 @@ module Squared
47
47
  m|memory=b memory-reservation=b memory-swap=n memory-swappiness=n mount=qq name=b network=b
48
48
  network-alias=b oom-score-adj=b pid=b pids-limit=n platform=q p|publish=q pull=b restart=b
49
49
  runtime=b security-opt=q shm-size=b stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q
50
- ulimit=q u|user=b userns=b uts=b v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
50
+ ulimit=q u|user=b userns=b uts=b v|volume=qq volume-driver=b volumes-from=b w|workdir=q].freeze,
51
51
  run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
52
52
  update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
53
53
  cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=n pids-limit=n
54
54
  restart=q].freeze,
55
- exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p u|user=e
55
+ exec: %w[d|detach i|interactive privileged t|tty=!? detach-keys=q e|env=qq env-file=p u|user=b
56
56
  w|workdir=q].freeze,
57
+ rm: %w[f|force l|link v|volumes].freeze,
57
58
  commit: %w[no-pause a|author=q c|change=q m|message=q pause=b?].freeze,
58
59
  inspect: %w[s|size f|format=q type=b].freeze,
59
60
  start: %w[a|attach i|interactive detach-keys=q].freeze,
@@ -393,6 +394,10 @@ module Squared
393
394
  append_tag(tag || option('tag', ignore: false) || self.tag)
394
395
  append_context context
395
396
  when :bake
397
+ if op.first == '-'
398
+ op.shift
399
+ op << @output[4] if @output[4]
400
+ end
396
401
  unless op.empty?
397
402
  if !context && op.size > 1 && basepath(op.last).directory?
398
403
  pat = /\btarget\s+"#{Regexp.escape(op.last)}"/
@@ -703,8 +708,22 @@ module Squared
703
708
  when :exec
704
709
  raise_error ArgumentError, 'nothing to execute', hint: flag if list.empty?
705
710
  end
706
- target << val << list.shift
707
- target << list.join(' && ') unless list.empty?
711
+ target << val
712
+ case list.first
713
+ when '--'
714
+ target.merge(list.drop(1))
715
+ when /\A(--|&&)(\s|\z)/
716
+ target.merge(list)
717
+ else
718
+ target << list.shift
719
+ unless list.empty?
720
+ if list.first.start_with?('-')
721
+ target.merge(list)
722
+ else
723
+ target << list.join(' && ')
724
+ end
725
+ end
726
+ end
708
727
  end
709
728
 
710
729
  def append_file(type, target: @session, index: 2)
@@ -923,7 +942,7 @@ module Squared
923
942
  end
924
943
  cmd.merge(Array(out).map! { |val| val.split(/\s+/, 2).first })
925
944
  cmd << args
926
- success?(run(cmd), ctx.start_with?(/network|tag|save/))
945
+ success?(run(cmd, { 'NO_COLOR' => 'true' }), ctx.start_with?(/network|tag|save/))
927
946
  end
928
947
 
929
948
  def filetype(val = dockerfile)
@@ -141,7 +141,6 @@ module Squared
141
141
  end
142
142
  File.write(@revfile, JSON.pretty_generate(@revdoc))
143
143
  rescue StandardError => e
144
- log&.debug e
145
144
  warn log_warn(e, pass: true) if warning
146
145
  ensure
147
146
  @revlock = false
@@ -170,9 +169,10 @@ module Squared
170
169
  fetch: {
171
170
  base: %w[multiple porcelain progress P|prune-tags refetch stdin u|update-head-ok
172
171
  recurse-submodules-default=b?].freeze,
173
- pull: %w[4 6 n t a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet set-upstream
174
- unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q recurse-submodules=v
175
- refmap=q o|server-option=q shallow-exclude=b shallow-since=v upload-pack=q].freeze
172
+ pull: %w[n t 4|ipv4 6|ipv6 a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
173
+ set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
174
+ recurse-submodules=v refmap=q o|server-option=q shallow-exclude=b shallow-since=v
175
+ upload-pack=q].freeze
176
176
  }.freeze,
177
177
  git: {
178
178
  add: %w[N|intent-to-add].freeze,
@@ -211,7 +211,7 @@ module Squared
211
211
  ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames numstat
212
212
  patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary a|text
213
213
  abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
214
- diff-algorithm=b diff-filter=e? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
214
+ diff-algorithm=b diff-filter=q? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
215
215
  find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? line-prefix=q output=p
216
216
  output-indicator-context=q output-indicator-new=q output-indicator-old=q relative=p rotate-to=p
217
217
  skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i submodule=b?
@@ -269,7 +269,7 @@ module Squared
269
269
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
270
270
  fetch: {
271
271
  base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
272
- pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
272
+ pull: %w[all recurse-submodules show-forced-updates tags].freeze
273
273
  },
274
274
  grep: %w[color exclude-standard recursive textconv].freeze,
275
275
  log: {
@@ -587,10 +587,10 @@ module Squared
587
587
  when 'i', 'E', 'F', 'P'
588
588
  opts << last
589
589
  else
590
- if last =~ /^(f(-ormat)?)=(.+)$/
590
+ if last =~ /^f(?:-ormat)?=(.+)$/
591
591
  opts.shift
592
592
  opts << "format=#{$1}"
593
- elsif last =~ /^(max(-count)?)=(\d+)$/
593
+ elsif last =~ /^max(?:-count)?=(\d+)$/
594
594
  opts << "max-count=#{$1}"
595
595
  else
596
596
  grep << last
@@ -1776,7 +1776,7 @@ module Squared
1776
1776
  op.add_quote(remote) if remote
1777
1777
  out, banner, from = source(io: true)
1778
1778
  print_item banner
1779
- ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
1779
+ ret = write_lines(out, grep: op.extras)
1780
1780
  list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1781
1781
  end
1782
1782
 
@@ -2021,7 +2021,7 @@ module Squared
2021
2021
  ret = choice_index('Choose a commit', git_spawn(cmd, stdout: false), column: /^(\S+)/, force: force, **kwargs)
2022
2022
  case ret
2023
2023
  when Array
2024
- ret.map!(&:stripstyle)
2024
+ ret.map { |val| val&.stripstyle }
2025
2025
  when String
2026
2026
  ret.stripstyle
2027
2027
  else
@@ -2197,10 +2197,6 @@ module Squared
2197
2197
  stdout: stdout, banner: banner, **kwargs)
2198
2198
  end
2199
2199
 
2200
- def dryrun?(*, target: @session, prefix: target&.first)
2201
- Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2202
- end
2203
-
2204
2200
  def quiet?(*, target: @session, **)
2205
2201
  return silent? unless target
2206
2202
 
@@ -7,8 +7,8 @@ module Squared
7
7
  OPT_NPM = {
8
8
  common: %w[dry-run=!? force=!? loglevel=b include-workspace-root=!? workspaces=!? w|workspace=v].freeze,
9
9
  install: %w[package-lock-only=!? prefer-dedupe=!? E|save-exact=!? before=q cpu=b libc=b os=b].freeze,
10
- install_a: %w[audit=! bin-links=! foreground-scripts=!? fund=! ignore-scripts=!? install-links=!?
11
- package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
10
+ install_a: %w[audit=! bin-links=! engine-strict=!? foreground-scripts=!? fund=! ignore-scripts=!?
11
+ install-links=!? package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
12
12
  install_b: %w[no-save B|save-bundle D|save-dev O|save-optional save-peer P|save-prod g|global=!?
13
13
  S|save=!?].freeze,
14
14
  run: %w[foreground-scripts=!? if-present=!? ignore-scripts=!? script-shell=p].freeze,
@@ -267,7 +267,7 @@ module Squared
267
267
  version = param_guard(action, 'version', args: args, key: :version)
268
268
  args = args.extras
269
269
  args << readline('Enter command', force: true) if args.empty?
270
- args.unshift(File.join(ENV['NVM_DIR'], 'nvm-exec'))
270
+ args.unshift(shell_quote(File.join(ENV['NVM_DIR'], 'nvm-exec')))
271
271
  run(args.join(' '), { 'NODE_VERSION' => version }, banner: false, from: :nvm)
272
272
  end
273
273
  when 'pack'
@@ -586,8 +586,7 @@ module Squared
586
586
  cmd << '--ignore-scripts' if option('ignore-scripts')
587
587
  cmd << '--dangerously-allow-all-builds' if option('approve-builds')
588
588
  else
589
- cmd = session 'npm'
590
- cmd << (ci = option('ci') ? 'ci' : 'install')
589
+ cmd = session('npm', (ci = option('ci', prefix: 'npm')) ? 'ci' : 'install')
591
590
  option('approve-scripts') do |val|
592
591
  cmd = npm_output 'approve-scripts'
593
592
  cmd << case val
@@ -601,6 +600,14 @@ module Squared
601
600
  print_run cmd, silent?
602
601
  run(cmd, banner: false)
603
602
  end
603
+ option('engine-strict', ignore: false) do |val|
604
+ cmd << case val
605
+ when '0', 'false'
606
+ '--engine-strict=false'
607
+ else
608
+ '--engine-strict'
609
+ end
610
+ end
604
611
  cmd << '--workspaces=false' if ws
605
612
  cmd << '--force' if option('force')
606
613
  append_nocolor
@@ -1359,8 +1366,8 @@ module Squared
1359
1366
  end
1360
1367
 
1361
1368
  def remove_modules(prefix = dependbin)
1362
- modules = basepath 'node_modules'
1363
- return false unless modules.directory? && confirm_basic('Remove?', modules, prefix: prefix)
1369
+ modules = basepath!('node_modules', type: 'd')
1370
+ return false unless modules && confirm_basic('Remove?', modules, prefix: prefix)
1364
1371
 
1365
1372
  modules.rmtree
1366
1373
  rescue Timeout::Error => e
@@ -31,8 +31,8 @@ module Squared
31
31
  root-user-action=b t|target=p upgrade-strategy=b].freeze,
32
32
  install_a: %w[ignore-requires-python no-index pre prefer-binary all-releases=b extra-index-url=q
33
33
  f|find-links=q i|index-url=q no-binary=q only-binary=q only-final=b uploaded-prior-to=q].freeze,
34
- install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps
35
- require-hashes use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p
34
+ install_b: %w[check-build-dependencies no-build-isolation no-clean no-deps require-hashes use-pep517
35
+ build-constraint=p c|constraint=p group=q progress-bar=b r|requirement=p
36
36
  requirements-from-script=p src=p].freeze,
37
37
  install_c: %w[C|config-settings=q e|editable=v].freeze,
38
38
  hash: %w[a|algorithm].freeze,
@@ -185,7 +185,7 @@ module Squared
185
185
  log.warn "run script #{n} of #{list.size}".subhint('out of range')
186
186
  end
187
187
  else
188
- case i
188
+ case (i > 1 && poetry? ? 0 : i)
189
189
  when 0
190
190
  found |= 1
191
191
  run(session_output('poetry', 'run', val), from: :run)
@@ -651,7 +651,7 @@ module Squared
651
651
  op.clear(pass: false)
652
652
  else
653
653
  if op.empty?
654
- op << "#{dist.call}/*"
654
+ op.add_path(dist.call, '*')
655
655
  else
656
656
  op.add_path
657
657
  end
@@ -936,6 +936,7 @@ module Squared
936
936
  buffer = []
937
937
  filter = kwargs.fetch(:filter, {})
938
938
  semver = filter[:semver]
939
+ dryrun = filter[:dryrun] || dryrun?(prefix: 'gem')
939
940
  update = if sync && filter[:select]
940
941
  semver ||= 'major'
941
942
  items = []
@@ -1089,7 +1090,7 @@ module Squared
1089
1090
  'user-install'
1090
1091
  end
1091
1092
  end
1092
- if filter[:dryrun]
1093
+ if dryrun
1093
1094
  print_run gem_output('update -f', *update.quote!), false
1094
1095
  else
1095
1096
  gem(:update, *update, opts: opts)
@@ -1131,8 +1132,8 @@ module Squared
1131
1132
  .clear(pass: false)
1132
1133
  end
1133
1134
  when :push
1134
- if op.empty? || (n = op.index(':'))
1135
- file = basepath(if !n && (spec = gemspec)
1135
+ if op.empty? || ia
1136
+ file = basepath(if !ia && (spec = gemspec)
1136
1137
  "#{spec.name}-#{spec.version}.gem"
1137
1138
  else
1138
1139
  choice_index 'Select a file', Dir.glob('*.gem', base: path)
@@ -88,8 +88,25 @@ module Squared
88
88
 
89
89
  def strip(val)
90
90
  val = shell_split val if val.is_a?(String)
91
- Array(val).map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }
92
- .reject(&:empty?)
91
+ ret = []
92
+ pass = -1
93
+ (args = Array(val)).each_with_index do |s, i|
94
+ next if s.empty? || pass == i
95
+
96
+ if s == '--'
97
+ ret << s << args[i.succ..-1].join(' ')
98
+ break
99
+ end
100
+ next ret << s unless s.start_with?('-')
101
+
102
+ if !s.include?('=') && (j = args[i.succ]) && !j.start_with?('-')
103
+ ret << "#{s.sub(/^-{1,2}/, '')}=#{j}"
104
+ pass = i.succ
105
+ else
106
+ ret << s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2')
107
+ end
108
+ end
109
+ ret
93
110
  end
94
111
 
95
112
  def select(list, bare: true, no: true, single: false, double: false)
@@ -141,7 +158,11 @@ module Squared
141
158
  end
142
159
 
143
160
  def pattern?(val)
144
- val.match?(/\A\^|\$\z/) || val.match?(/[.)][*+?]|\(\?:|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
161
+ Regexp.new(val)
162
+ val.start_with?('\A', '^') || val.end_with?('\z', '$') ||
163
+ val.match?(/[.)][*+?]|\(\?[:=!><]|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
164
+ rescue RegexpError
165
+ false
145
166
  end
146
167
 
147
168
  private
@@ -282,7 +303,7 @@ module Squared
282
303
  end
283
304
  numtype = [
284
305
  [i, /\A\d+\z/],
285
- [f, /\A\d*(?:\.\d+)?\z/],
306
+ [f, /\A(\d+(\.\d*)?|\d*\.\d+)\z/],
286
307
  [si, /\A-?\d+\z/]
287
308
  ].freeze
288
309
  numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && v.match?(pat) } }
@@ -317,8 +338,8 @@ module Squared
317
338
  elsif q.include?(key)
318
339
  add quote_option(key, val, double: qq.include?(key), merge: merge, sep: sep)
319
340
  elsif p.include?(key)
320
- if val.match?(/\A(["']).+\1\z/)
321
- add shell_option(key, val, escape: false, merge: merge, sep: sep)
341
+ if val =~ /\A(["']).+\1\z/
342
+ add shell_option(key, val, double: $1 == '"', escape: false, merge: merge, sep: sep)
322
343
  elsif path
323
344
  add quote_option(key, path + val, merge: merge, sep: sep)
324
345
  else
@@ -246,8 +246,9 @@ module Squared
246
246
  already_invoked? parallel, val
247
247
  end
248
248
 
249
- def exclude?(key, empty = false)
250
- @exclude.include?(key) || (empty && (!key?(key) || self[key].empty?))
249
+ def exclude?(key, fallback = false, empty: nil)
250
+ fallback = empty unless empty.nil?
251
+ @exclude.include?(key) || (fallback && (!key?(key) || self[key].empty?))
251
252
  end
252
253
 
253
254
  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.6.16
4
+ version: 0.6.18
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: 4.0.10
127
+ rubygems_version: 4.0.19
128
128
  specification_version: 4
129
129
  summary: Rake task generator for managing multi-language workspaces.
130
130
  test_files: []