squared 0.7.8 → 0.7.10

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: 4c4eb1673e7842e505bf21625b8452292591fa243e04d7481f44b889f0e4c22b
4
- data.tar.gz: a44d3b23a26deba7d5cec9559a82d1d53545f9c6e78d55108f90f3221013d4df
3
+ metadata.gz: bf477ce6ea561419bddfea1572f95762934d01c5d5e94bd3cd65e027a96bdcc8
4
+ data.tar.gz: ffbdcaea4e1a2dc293b75fe99c8e121baa444c8784175aa6117134921fb59e46
5
5
  SHA512:
6
- metadata.gz: b2413955e422ad4b3d7d7a90d155848bd6a359bb42f212cbb67f20ed1eac8a8a7bd895e90decf99bfdfcc05ddf90d0363a9e48111bf4843de97b23930e81e7a3
7
- data.tar.gz: b85dfd373270eb1cc285156902cc06f1a14591270dc94e8a0f4cbc1951f8cd39b0475ef92cd0f0629f84fb55a149eb4cf17a549105eb5813072127eb67a6affa
6
+ metadata.gz: e86f20679d0f906ed3ae080963014c88f2b747dd5570d3e8bf0037f7f0d4670ce257dc6720b13d94fc8f044f16e89a535f09634f7cee8bc5d7061a2f8d2b7485
7
+ data.tar.gz: 41c08e924735c9626889f6075a3eb3b5a00bf8f9e9b487ccf29f9de161a3b93702ee1658ea9a73d323bceea31671ea08ab74f58ad83151a5e5bd2929351c6c60
data/CHANGELOG.md CHANGED
@@ -1,5 +1,61 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.10] - 2026-08-06
4
+
5
+ ### Fixed
6
+
7
+ - See `0.6.17`.
8
+
9
+ ## [0.6.17]
10
+
11
+ ### Added
12
+
13
+ - NPM command install can bypass engines with ENV and engine-strict=false.
14
+
15
+ ### Fixed
16
+
17
+ - Ruby command gem action push interactive file selector did nothing.
18
+ - Git choice prompt did not permit optional empty values.
19
+
20
+ ## [0.4.40]
21
+
22
+ ### Changed
23
+
24
+ - Series method exclude? was made compatible with v0.8 signature.
25
+
26
+ ## [0.7.9] - 2026-07-04
27
+
28
+ ### Added
29
+
30
+ - Docker command image action inspect was implemented.
31
+
32
+ ### Changed
33
+
34
+ - Project global ENV for BANNER and STRICT can accept boolean values.
35
+
36
+ ## [0.6.16]
37
+
38
+ ### Added
39
+
40
+ - Git command pull action all supports filter pattern negation.
41
+
42
+ ## [0.5.25]
43
+
44
+ ### Fixed
45
+
46
+ - See `0.4.39`.
47
+
48
+ ## [0.4.39]
49
+
50
+ ### Changed
51
+
52
+ - Common global argument OUT with a file separator overrides PIPE.
53
+
54
+ ### Fixed
55
+
56
+ - Git output list results did not hide footer when banner was disabled.
57
+ - Project banners which were empty were being printed.
58
+
3
59
  ## [0.7.8] - 2026-06-17
4
60
 
5
61
  ### Fixed
@@ -1891,6 +1947,8 @@
1891
1947
 
1892
1948
  - Changelog was created.
1893
1949
 
1950
+ [0.7.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.10
1951
+ [0.7.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.9
1894
1952
  [0.7.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.8
1895
1953
  [0.7.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.7
1896
1954
  [0.7.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.6
@@ -1900,6 +1958,8 @@
1900
1958
  [0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
1901
1959
  [0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
1902
1960
  [0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
1961
+ [0.6.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.17
1962
+ [0.6.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.16
1903
1963
  [0.6.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.15
1904
1964
  [0.6.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.14
1905
1965
  [0.6.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.13
@@ -1916,6 +1976,7 @@
1916
1976
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1917
1977
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1918
1978
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1979
+ [0.5.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.25
1919
1980
  [0.5.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.24
1920
1981
  [0.5.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.23
1921
1982
  [0.5.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.22
@@ -1941,6 +2002,8 @@
1941
2002
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1942
2003
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1943
2004
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
2005
+ [0.4.40]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.40
2006
+ [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
1944
2007
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
1945
2008
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
1946
2009
  [0.4.36]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.36
data/README.md CHANGED
@@ -886,7 +886,7 @@ Features can be enabled through ENV when calling global tasks such as through *C
886
886
  | outdated | - | U|UPDATE=major|minor|patch DIFF DRY_RUN |
887
887
  | publish | - | OTP=s TAG=s ACCESS=0,1,s DRY_RUN Y |
888
888
  | depend package | * | PACAKGE_LOCK|LOCKFILE=0 NO_LOCKFILE=1 Y |
889
- | npm | depend | APPROVE_SCRIPTS=s |
889
+ | npm | depend | APPROVE_SCRIPTS=0,1,s ALLOW_SCRIPTS=0,1,s |
890
890
  | npm | package | SAVE IGNORE_SCRIPTS STRICT_PEER_DEPS |
891
891
  | pnpm | depend | PUBLIC_HOIST_PATTERN=s APPROVE_BUILDS |
892
892
  | pnpm | depend:add | ALLOW_BUILD=s |
@@ -92,6 +92,13 @@ module Squared
92
92
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
93
93
  end
94
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
+
95
102
  def __freeze__
96
103
  PATH.freeze
97
104
  ARG.freeze
@@ -80,7 +80,7 @@ module Squared
80
80
  end}] "
81
81
  end
82
82
  end
83
- between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
83
+ between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max <= min ? Float::INFINITY : max) }
84
84
  Timeout.timeout(timeout) do
85
85
  while (ch = Readline.readline(msg))
86
86
  ch.strip!
@@ -162,11 +162,19 @@ module Squared
162
162
  end
163
163
 
164
164
  def env_pipe(key, default = 1, root: nil, **kwargs)
165
+ out = 1
165
166
  case key
166
167
  when ::String
167
168
  case (ret = env_value(key, **kwargs))
168
169
  when '0', '1', '2'
169
170
  return ret.to_i
171
+ else
172
+ out = default if default.is_a?(::Numeric)
173
+ if ret.include?(File::SEPARATOR)
174
+ default = ret
175
+ elsif key.include?(File::SEPARATOR)
176
+ default = key
177
+ end
170
178
  end
171
179
  when ::Numeric
172
180
  return key if key.between?(0, 2)
@@ -177,7 +185,7 @@ module Squared
177
185
  (root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
178
186
  rescue => e
179
187
  warn e
180
- 1
188
+ out
181
189
  end
182
190
  end
183
191
 
@@ -332,8 +332,7 @@ module Squared
332
332
  'yaml'
333
333
  when 'js'
334
334
  'json'
335
- when ''
336
- nil
335
+ when '' then nil
337
336
  else
338
337
  ret
339
338
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.7.8'
4
+ VERSION = '0.7.10'
5
5
  end
@@ -115,7 +115,13 @@ module Squared
115
115
  @stage = Support.hashlist
116
116
  self.home = home
117
117
  self.exception = env_bool exception
118
- self.pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: home)
118
+ self.pipe = if $DEBUG
119
+ 2
120
+ elsif (out = ARG[:OUT]) && out.include?(File::SEPARATOR)
121
+ env_pipe(out, pipe, root: home)
122
+ else
123
+ env_pipe(pipe, (out && env(out)) || 1, root: home)
124
+ end
119
125
  self.verbose = if $VERBOSE.nil?
120
126
  false
121
127
  elsif verbose.nil?
@@ -1545,7 +1545,7 @@ module Squared
1545
1545
  def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
1546
1546
  name = "#{key}_#{envname_get}"
1547
1547
  ret = if suffix
1548
- ENV.fetch("#{name}_#{suffix}", '')
1548
+ ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1549
1549
  elsif strict
1550
1550
  ENV[name].to_s
1551
1551
  else
@@ -1692,7 +1692,13 @@ module Squared
1692
1692
  ret += 1
1693
1693
  break out if first
1694
1694
  end
1695
- print_item banner, lines if banner && (ret > 0 || (!pass && !first))
1695
+ if banner && (ret > 0 || (!pass && !first))
1696
+ if banner.empty?
1697
+ print_item(*lines)
1698
+ else
1699
+ print_item(banner, *lines)
1700
+ end
1701
+ end
1696
1702
  ret
1697
1703
  end
1698
1704
 
@@ -1718,7 +1724,7 @@ module Squared
1718
1724
  end
1719
1725
 
1720
1726
  def print_run(cmd, banner = true, verbose: nil, **)
1721
- return if banner || !stdout? || verbose == false || env('BANNER', equals: '0')
1727
+ return if banner || !stdout? || verbose == false || env('BANNER', equals: %w[0 false])
1722
1728
 
1723
1729
  puts "\n> #{cmd}"
1724
1730
  printsucc
@@ -1727,7 +1733,7 @@ module Squared
1727
1733
  def print_item(*val, series: false)
1728
1734
  puts unless printfirst?
1729
1735
  printsucc unless series
1730
- puts val unless val.empty? || (val.size == 1 && !val.first)
1736
+ puts val unless val.empty? || (val.size == 1 && (!val.first || val.first.empty?))
1731
1737
  end
1732
1738
 
1733
1739
  def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle)
@@ -1891,7 +1897,7 @@ module Squared
1891
1897
  end
1892
1898
 
1893
1899
  def append_hash(data, target: @session || [], build: false)
1894
- if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1900
+ if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1895
1901
  if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
1896
1902
  data = data.merge(extra)
1897
1903
  else
@@ -2080,8 +2086,8 @@ module Squared
2080
2086
  args
2081
2087
  end
2082
2088
 
2083
- def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
2084
- return true if prefix ? option('y', prefix: prefix) : target && option('y', target: target)
2089
+ def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
2090
+ return true if option('y', prefix: prefix)
2085
2091
 
2086
2092
  confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
2087
2093
  end
@@ -2686,7 +2692,16 @@ module Squared
2686
2692
  end
2687
2693
 
2688
2694
  def banner?
2689
- ARG[:BANNER] && env('BANNER', notequals: '0')
2695
+ case (val = env('BANNER', ignore: false))
2696
+ when '0', 'false'
2697
+ false
2698
+ else
2699
+ !val.nil? || ARG[:BANNER]
2700
+ end
2701
+ end
2702
+
2703
+ def dryrun?(*, target: @session, prefix: target&.first)
2704
+ Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2690
2705
  end
2691
2706
 
2692
2707
  def pwd?
@@ -2719,7 +2734,12 @@ module Squared
2719
2734
  end
2720
2735
 
2721
2736
  def strict?
2722
- (ARG[:STRICT] || exception?(Logger::FATAL)) && env('STRICT', notequals: '0')
2737
+ case (val = env('STRICT', ignore: false))
2738
+ when '0', 'false'
2739
+ false
2740
+ else
2741
+ !val.nil? || ARG[:STRICT] || exception?(Logger::FATAL)
2742
+ end
2723
2743
  end
2724
2744
 
2725
2745
  def serve?
@@ -56,7 +56,7 @@ module Squared
56
56
  exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p u|user=e
57
57
  w|workdir=q].freeze,
58
58
  commit: %w[no-pause a|author=q c|change=q m|message=q pause=b?].freeze,
59
- inspect: %w[s|size f|format=q type=b].freeze,
59
+ inspect: %w[s|size f|format=q].freeze,
60
60
  start: %w[a|attach i|interactive detach-keys=q].freeze,
61
61
  stop: %w[s|signal=b t|timeout=i].freeze,
62
62
  restart: %w[s|signal=b t|timeout=i].freeze,
@@ -64,6 +64,7 @@ module Squared
64
64
  stats: %w[a|all no-stream no-trunc format|q].freeze
65
65
  }.freeze,
66
66
  image: {
67
+ inspect: %w[f|format platform=q].freeze,
67
68
  ls: %w[a|all digests no-trunc q|quiet tree f|filter=q format=q].freeze,
68
69
  pull: %w[a|all-tags platform=q q|quiet].freeze,
69
70
  push: %w[a|all-tags platform=q q|quiet].freeze,
@@ -113,7 +114,7 @@ module Squared
113
114
  'build' => %i[tag context].freeze,
114
115
  'compose' => %i[build create publish run exec up down service].freeze,
115
116
  'bake' => %i[build compose check].freeze,
116
- 'image' => %i[ls rm pull push tag save].freeze,
117
+ 'image' => %i[ls rm pull push tag save inspect].freeze,
117
118
  'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
118
119
  rm].freeze,
119
120
  'network' => %i[connect disconnect create].freeze,
@@ -276,7 +277,7 @@ module Squared
276
277
  end
277
278
  end
278
279
  else
279
- format_desc action, flag, "opts*,id/name#{flag == :update ? '+' : '*'}"
280
+ format_desc action, flag, "opts*,id/name#{flag == :update || flag == :inspect ? '+' : '*'}"
280
281
  task flag do |_, args|
281
282
  container flag, args.to_a
282
283
  end
@@ -287,7 +288,7 @@ module Squared
287
288
  next unless @registry
288
289
 
289
290
  format_desc action, flag, 'tag?,registry/username?,opts*'
290
- task flag, [:tag] do |_, args|
291
+ task flag do |_, args|
291
292
  image flag, args.to_a
292
293
  end
293
294
  when :pull
@@ -296,6 +297,11 @@ module Squared
296
297
  id = param_guard(action, flag, args: args, key: :tag)
297
298
  image(flag, args.extras, id: id)
298
299
  end
300
+ when :inspect
301
+ format_desc action, flag, 'opts*,id+'
302
+ task flag do |_, args|
303
+ image flag, args.to_a
304
+ end
299
305
  else
300
306
  format_desc(action, flag, case flag
301
307
  when :rm, :save then 'id,opts*'
@@ -646,6 +652,9 @@ module Squared
646
652
  sync = false
647
653
  exception ||= true
648
654
  banner = false
655
+ when :inspect
656
+ raise_error ArgumentError, 'missing image', hint: flag if op.empty?
657
+ op.append(escape: true, strip: /^:/)
649
658
  end
650
659
  success?(run(sync: sync, exception: exception, banner: banner, from: from), flag == :tag || flag == :save)
651
660
  end
@@ -141,7 +141,6 @@ module Squared
141
141
  end
142
142
  File.write(@revfile, JSON.pretty_generate(@revdoc))
143
143
  rescue => e
144
- log&.debug e
145
144
  warn log_warn(e, pass: true) if warning
146
145
  ensure
147
146
  @revlock = false
@@ -1048,13 +1047,13 @@ module Squared
1048
1047
  op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, strict: strict?,
1049
1048
  no: OPT_GIT[:no][:pull])
1050
1049
  opts -= op.extras
1051
- reg = matchmap op
1050
+ reg, neg = matchmap(op, negate: true)
1052
1051
  session_done op.target
1053
1052
  heads = []
1054
1053
  cur = nil
1055
1054
  foreachref('heads', format: '%(if)%(HEAD)%(then)* %(end)%(refname:short)').each do |line|
1056
1055
  cur ||= line.delete_prefix!('* ')
1057
- heads << line if matchany?(reg, line)
1056
+ heads << line if matchany?(reg, line) && !matchany?(neg, line, empty: false)
1058
1057
  end
1059
1058
  raise_error 'head not found', hint: 'for-each-ref' unless cur
1060
1059
  opts << 'ff-only' if opts.empty? && option('ff-only', notequals: '0')
@@ -1234,7 +1233,7 @@ module Squared
1234
1233
  op.clear
1235
1234
  out, banner, from = source(io: true)
1236
1235
  print_item banner
1237
- list_result(write_lines(out), 'objects', from: from)
1236
+ list_result(write_lines(out), 'objects', banner: banner, from: from)
1238
1237
  return
1239
1238
  end
1240
1239
  else
@@ -1286,7 +1285,7 @@ module Squared
1286
1285
  end
1287
1286
  out, banner, from = source(io: true)
1288
1287
  ret = write_lines(out, banner: banner, sub: sub)
1289
- list_result(ret, 'files', action: 'modified', from: from)
1288
+ list_result(ret, 'files', action: 'modified', banner: banner, from: from)
1290
1289
  end
1291
1290
 
1292
1291
  def revbuild(flag = nil, opts = [], **kwargs)
@@ -1454,7 +1453,7 @@ module Squared
1454
1453
  out, banner, from = source(io: true)
1455
1454
  print_item banner
1456
1455
  ret = write_lines(out, grep: op.extras)
1457
- list_result(ret, 'tags', grep: op.extras, from: from)
1456
+ list_result(ret, 'tags', grep: op.extras, banner: banner, from: from)
1458
1457
  return
1459
1458
  end
1460
1459
  if (ret = source) && (remote ||= option('remote'))
@@ -1465,9 +1464,9 @@ module Squared
1465
1464
 
1466
1465
  def log!(flag, opts = [], range: [], index: [], grep: [])
1467
1466
  cmd, opts = git_session('log', opts: opts)
1468
- op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self, strict: strict?,
1469
- no: collect_hash(OPT_GIT[:no][:log]),
1470
- first: matchpathspec)
1467
+ op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
1468
+ project: self, strict: strict?, no: collect_hash(OPT_GIT[:no][:log]),
1469
+ first: matchpathspec)
1471
1470
  case flag
1472
1471
  when :between, :contain
1473
1472
  op.add_quote(range.join(flag == :between ? '..' : '...'))
@@ -1722,7 +1721,7 @@ module Squared
1722
1721
  opt_style(color(:green), /^(\*\s+)(\S+)(.*)$/, 2),
1723
1722
  opt_style(color(:red), %r{^(\s*)(remotes/\S+)(.*)$}, 2)
1724
1723
  ])
1725
- list_result(ret, 'branches', from: from)
1724
+ list_result(ret, 'branches', banner: banner, from: from)
1726
1725
  return
1727
1726
  else
1728
1727
  if (head = git_spawn('rev-parse --abbrev-ref HEAD').chomp).empty?
@@ -1731,7 +1730,7 @@ module Squared
1731
1730
  git_spawn 'fetch --all --prune --quiet' if option('sync')
1732
1731
  cmd << '-vv --no-abbrev --list'
1733
1732
  out, banner, from = source(io: true)
1734
- first = workspace.size > 1
1733
+ first = from_base?('branch')
1735
1734
  grep = first ? [/^\*\s+#{Regexp.escape(head)}\s/] : []
1736
1735
  ret = write_lines(out, grep: grep, banner: banner, first: first) do |line, index|
1737
1736
  next line if stdin?
@@ -1804,9 +1803,7 @@ module Squared
1804
1803
 
1805
1804
  def restore(flag, opts = [], commit: nil, files: nil)
1806
1805
  cmd, opts = git_session('restore', shell_option(flag, commit, escape: false, force: false), opts: opts)
1807
- op = OptionPartition.new(opts,
1808
- OPT_GIT[:restore] + OPT_GIT[:log][:diff_context],
1809
- cmd,
1806
+ op = OptionPartition.new(opts, OPT_GIT[:restore] + OPT_GIT[:log][:diff_context], cmd,
1810
1807
  project: self, strict: strict?, no: OPT_GIT[:no][:restore], first: matchpathspec)
1811
1808
  append_pathspec(op.extras + (files || []), pass: false)
1812
1809
  source(sync: false, stderr: true)
@@ -1835,8 +1832,7 @@ module Squared
1835
1832
  end
1836
1833
  list = OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context]
1837
1834
  op = OptionPartition.new(opts, list, cmd,
1838
- project: self,
1839
- strict: strict?,
1835
+ project: self, strict: strict?,
1840
1836
  no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
1841
1837
  op.append(delim: true)
1842
1838
  source(exception: false, banner: flag != :oneline)
@@ -1861,8 +1857,8 @@ module Squared
1861
1857
  cmd << '--sq-quote'
1862
1858
  args = true
1863
1859
  end
1864
- OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd,
1865
- project: self, strict: strict?, no: OPT_GIT[:no][:rev_parse], args: args)
1860
+ OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd, project: self, strict: strict?, args: args,
1861
+ no: OPT_GIT[:no][:rev_parse])
1866
1862
  .append(escape: args)
1867
1863
  end
1868
1864
  source(banner: verbose?)
@@ -1890,7 +1886,7 @@ module Squared
1890
1886
  out, banner, from = source(io: true)
1891
1887
  print_item banner
1892
1888
  ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
1893
- list_result(ret, flag.to_s, grep: op.extras, from: from)
1889
+ list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1894
1890
  end
1895
1891
 
1896
1892
  def ls_files(flag, opts = [])
@@ -1900,7 +1896,7 @@ module Squared
1900
1896
  out, banner, from = source(io: true)
1901
1897
  print_item banner
1902
1898
  ret = write_lines(out, grep: op.extras)
1903
- list_result(ret, 'files', grep: op.extras, from: from)
1899
+ list_result(ret, 'files', grep: op.extras, banner: banner, from: from)
1904
1900
  end
1905
1901
 
1906
1902
  def git(flag, opts = [])
@@ -2069,10 +2065,10 @@ module Squared
2069
2065
  end
2070
2066
  end
2071
2067
 
2072
- def list_result(size, type, action: 'found', grep: [], from: nil)
2068
+ def list_result(size, type, action: 'found', grep: [], banner: nil, from: nil)
2073
2069
  if size == 0
2074
2070
  puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
2075
- elsif stdout?
2071
+ elsif stdout? && (banner.nil? || (banner.is_a?(String) && !banner.empty?))
2076
2072
  styles = theme.fetch(:banner, []).reject { |val| val.to_s.end_with?('!') }
2077
2073
  styles << :bold if styles.size <= 1
2078
2074
  puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
@@ -2104,7 +2100,7 @@ module Squared
2104
2100
  ret = choice_index('Choose a commit', git_spawn(cmd, stdout: false), column: /^(\S+)/, force: force, **kwargs)
2105
2101
  case ret
2106
2102
  when Array
2107
- ret.map(&:stripstyle)
2103
+ ret.map { |val| val&.stripstyle }
2108
2104
  when String
2109
2105
  ret.stripstyle
2110
2106
  else
@@ -2141,8 +2137,8 @@ module Squared
2141
2137
  append_submodules(target: target, from: from)
2142
2138
  return if !remote && opts.empty?
2143
2139
 
2144
- op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, strict: strict?,
2145
- no: no)
2140
+ op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target,
2141
+ project: self, strict: strict?, no: no)
2146
2142
  refspec = op.each_with_object([]) do |opt, out|
2147
2143
  if opt =~ op.values
2148
2144
  case $1
@@ -2282,10 +2278,6 @@ module Squared
2282
2278
  stdout: stdout, banner: banner, **kwargs)
2283
2279
  end
2284
2280
 
2285
- def dryrun?(*, target: @session, prefix: target&.first)
2286
- Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2287
- end
2288
-
2289
2281
  def quiet?(*, target: @session, **)
2290
2282
  return silent? unless target
2291
2283
 
@@ -8,8 +8,8 @@ module Squared
8
8
  common: %w[dry-run=!? force=!? loglevel=b include-workspace-root=!? workspaces=!? w|workspace=v].freeze,
9
9
  common_scripts: %w[dangerously-allow-all-scripts=!? strict-allow-scripts=!? allow-scripts=q].freeze,
10
10
  install: %w[package-lock-only=!? prefer-dedupe=!? E|save-exact=!? before=q cpu=b libc=b os=b].freeze,
11
- install_a: %w[audit=! bin-links=! foreground-scripts=!? fund=! ignore-scripts=!? install-links=!?
12
- package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
11
+ install_a: %w[audit=! bin-links=! engine-strict=!? foreground-scripts=!? fund=! ignore-scripts=!?
12
+ install-links=!? package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
13
13
  install_b: %w[no-save B|save-bundle D|save-dev O|save-optional save-peer P|save-prod g|global=!?
14
14
  S|save=!?].freeze,
15
15
  install_c: %w[allow-directory=b? allow-file=b? allow-git=b? allow-remote=b?].freeze,
@@ -315,7 +315,7 @@ module Squared
315
315
  when 'package'
316
316
  format_desc(action, flag, 'opts*', before: case flag
317
317
  when :dedupe, :rebuild then nil
318
- when :reinstall then 'force?'
318
+ when :reinstall then 'f/orce?'
319
319
  else 'name*'
320
320
  end)
321
321
  task flag do |_, args|
@@ -627,8 +627,7 @@ module Squared
627
627
  cmd << '--ignore-scripts' if option('ignore-scripts')
628
628
  cmd << '--dangerously-allow-all-builds' if option('approve-builds')
629
629
  else
630
- cmd = session 'npm'
631
- cmd << (ci = option('ci') ? 'ci' : 'install')
630
+ cmd = session('npm', (ci = option('ci', prefix: 'npm')) ? 'ci' : 'install')
632
631
  option('approve-scripts') do |val|
633
632
  cmd = npm_output 'approve-scripts'
634
633
  cmd << case val
@@ -642,6 +641,26 @@ module Squared
642
641
  print_run cmd, silent?
643
642
  run(cmd, banner: false)
644
643
  end
644
+ option('allow-scripts', ignore: false) do |val|
645
+ cmd << case val
646
+ when '0'
647
+ '--ignore-scripts'
648
+ when 'false'
649
+ '--strict-allow-scripts'
650
+ when '1', 'true'
651
+ '--dangerously-allow-all-scripts'
652
+ else
653
+ quote_option 'allow-scripts', val
654
+ end
655
+ end
656
+ option('engine-strict', ignore: false) do |val|
657
+ cmd << case val
658
+ when '0', 'false'
659
+ '--engine-strict=false'
660
+ else
661
+ '--engine-strict'
662
+ end
663
+ end
645
664
  cmd << '--workspaces=false' if ws
646
665
  cmd << '--force' if option('force')
647
666
  append_nocolor
@@ -1032,6 +1051,7 @@ module Squared
1032
1051
 
1033
1052
  def package(flag, opts = [], packages: [], from: nil)
1034
1053
  workspace.rev_clear(name)
1054
+ force = true if flag == :reinstall && has_value!(opts, 'f')
1035
1055
  yarn = dependtype(:yarn)
1036
1056
  if yarn > 0 && !(yarn == 1 && ((flag == :update && !packages.empty?) || %i[approve deny
1037
1057
  rebuild].include?(flag)))
@@ -1045,8 +1065,8 @@ module Squared
1045
1065
  end
1046
1066
  when :reinstall
1047
1067
  if yarn == 1
1048
- remove_modules 'yarn' if opts.include?('force')
1049
- elsif opts.delete('force')
1068
+ remove_modules 'yarn' if opts.include?('force') || force
1069
+ elsif opts.delete('force') || force
1050
1070
  opts << 'check-cache'
1051
1071
  end
1052
1072
  opts << 'no-lockfile' if lockfile(true)
@@ -1115,7 +1135,7 @@ module Squared
1115
1135
  spec = 1
1116
1136
  flag = :install
1117
1137
  when :reinstall
1118
- remove_modules 'npm' if opts.delete('force')
1138
+ remove_modules 'npm' if opts.delete('force') || force
1119
1139
  opts.unshift('package-lock=false') if lockfile(true)
1120
1140
  flag = :install
1121
1141
  end
@@ -1450,8 +1470,7 @@ module Squared
1450
1470
  next if yarntype(exist: true) == 0
1451
1471
  when /^pnpm/
1452
1472
  next if pnpmtype(exist: true) == 0
1453
- when /^npm/
1454
- nil
1473
+ when /^npm/ then nil
1455
1474
  else
1456
1475
  next
1457
1476
  end
@@ -1505,8 +1524,8 @@ module Squared
1505
1524
  end
1506
1525
 
1507
1526
  def remove_modules(prefix = dependbin)
1508
- modules = basepath 'node_modules'
1509
- return false unless modules.directory? && confirm_basic('Remove?', modules, prefix: prefix)
1527
+ modules = basepath!('node_modules', type: 'd')
1528
+ return false unless modules && confirm_basic('Remove?', modules, prefix: prefix)
1510
1529
 
1511
1530
  modules.rmtree
1512
1531
  rescue Timeout::Error => e
@@ -36,9 +36,9 @@ module Squared
36
36
  root-user-action=b t|target=p upgrade-strategy=b].freeze,
37
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
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,
39
+ install_b: %w[check-build-dependencies no-build-isolation no-clean no-deps require-hashes use-pep517
40
+ build-constraint=p c|constraint=p group=q progress-bar=b r|requirement=p
41
+ requirements-from-script=p src=p].freeze,
42
42
  install_c: %w[C|config-settings=q e|editable=v].freeze,
43
43
  install_d: %w[ignore-requires-python uploaded-prior-to=q].freeze,
44
44
  hash: %w[a|algorithm].freeze,
@@ -181,8 +181,8 @@ module Squared
181
181
  format_desc action, nil, "script+|#{indexchar}index+|#,pattern*"
182
182
  task action, [:command] do |_, args|
183
183
  found = 0
184
- %w[tool.poetry.scripts tool.pdm.scripts project.scripts].each_with_index do |table, i|
185
- next if (list = read_pyproject(table)).empty?
184
+ %w[tool.poetry tool.pdm project].each_with_index do |table, i|
185
+ next if (list = read_pyproject("#{table}.scripts")).empty?
186
186
 
187
187
  if args.command == '#'
188
188
  format_list(list, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: pyprojectfile)
@@ -208,7 +208,7 @@ module Squared
208
208
  log.warn "run script #{n} of #{list.size}".subhint('out of range')
209
209
  end
210
210
  else
211
- case i
211
+ case (i > 1 && poetry? ? 0 : i)
212
212
  when 0
213
213
  found |= 1
214
214
  run(session_output('poetry', 'run', val), from: :run)
@@ -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/uninstall,opts*"
300
+ format_desc action, flag, "file?=#{DEP_PYTHON[4]},u/ninstall?,opts*"
301
301
  task flag do |_, args|
302
302
  opts = args.to_a
303
303
  if has_value!(opts, 'u', 'uninstall')
@@ -312,7 +312,7 @@ module Squared
312
312
  end
313
313
  file = pip(flag, opts: opts, banner: requirement.nil?, requirement: requirement)
314
314
  puts File.read(file) unless silent?
315
- if requirement && confirm_basic('Uninstall?', file)
315
+ if requirement && confirm_basic('Uninstall?', file, prefix: 'pip')
316
316
  pip(:uninstall, opts: ['y', "r=#{shell_quote(file)}"])
317
317
  end
318
318
  end
@@ -482,7 +482,7 @@ module Squared
482
482
  :patch
483
483
  end
484
484
  end
485
- '--not-required' if option('not-required', notequals: '0') && !env('PYTHON_DEFAULT')
485
+ '--not-required' if option('not-required', notequals: '0')
486
486
  end
487
487
  cmd << '--local' if option('l', 'local')
488
488
  append_global
@@ -607,17 +607,17 @@ module Squared
607
607
  project: self, strict: strict?, single: singleopt(flag))
608
608
  else
609
609
  op = append_pip(flag, opts, pipopts(:install), target: pip_session('install'))
610
- end
611
- case flag
612
- when :editable
613
- op << quote_option('e', op.pop || editable || '.')
614
- op.clear
615
- when :user, :upgrade
616
- op.concat(packages)
617
- raise_error ArgumentError, 'no packages listed', hint: flag if op.empty?
618
- op << "--#{flag}"
619
- op.append
620
- python_session('-m pip', *op.to_a.drop(1)) if workspace.windows?
610
+ case flag
611
+ when :editable
612
+ op << quote_option('e', op.pop || editable || '.')
613
+ op.clear
614
+ when :user, :upgrade
615
+ op.concat(packages)
616
+ raise_error ArgumentError, 'no packages listed', hint: flag if op.empty?
617
+ op << "--#{flag}"
618
+ op.append
619
+ python_session('-m pip', *op.to_a.drop(1)) if workspace.windows?
620
+ end
621
621
  end
622
622
  run(banner: banner, from: :install)
623
623
  end
@@ -798,8 +798,7 @@ module Squared
798
798
  raise_error 'no subcommand', hint: flag if op.empty?
799
799
  op << (action = op.shift)
800
800
  case action
801
- when 'dir', 'info', 'purge'
802
- nil
801
+ when 'dir', 'info', 'purge' then nil
803
802
  when 'list', 'remove'
804
803
  op.add_first(quote: true)
805
804
  else
@@ -811,8 +810,7 @@ module Squared
811
810
  raise_error 'no subcommand', hint: flag if op.empty?
812
811
  op << (action = op.shift)
813
812
  case action
814
- when 'list', 'edit', 'debug'
815
- nil
813
+ when 'list', 'edit', 'debug' then nil
816
814
  when 'get', 'unset', 'set'
817
815
  op.add_first
818
816
  op.add_first(quote: true, expect: true) if action == 'set'
@@ -1091,8 +1089,7 @@ module Squared
1091
1089
  /\A(?:v+|q+|b+|V+|O+)\z/
1092
1090
  when :pdm, :poetry
1093
1091
  /\Av+\z/
1094
- when :twine, :meson
1095
- nil
1092
+ when :twine, :meson then nil
1096
1093
  else
1097
1094
  /\A(?:v+|q+)\z/
1098
1095
  end
@@ -506,16 +506,22 @@ module Squared
506
506
  format_desc action, flag, 'f/orce?,l/ocal?,opts*'
507
507
  task flag do |_, args|
508
508
  opts = args.to_a
509
- opts << 'local' if has_value!(opts, 'l')
509
+ opts << 'local' if has_value!(opts, 'l', 'local')
510
510
  opts << 'redownload' if has_value!(opts, 'f', 'force')
511
511
  if (lock = basepath!('Gemfile.lock'))
512
- config = basepath '.bundle', 'config'
513
- if config.exist? && config.read.match?(/\bBUNDLE_FROZEN:\s+"true"/)
514
- if opts.include?('redownload')
515
- run(bundle_output('config unset frozen'), banner: false)
516
- else
517
- print_error('Gemfile.lock is frozen', subject: name, hint: flag)
512
+ case (val = ENV['BUNDLE_FROZEN'])
513
+ when '0', 'false' then nil
514
+ else
515
+ if val
516
+ print_error("BUNDLE_FROZEN: #{val}", loglevel: Logger::INFO, subject: name, hint: flag)
518
517
  lock = nil
518
+ elsif basepath!('.bundle', 'config')&.read&.match?(/\bBUNDLE_FROZEN:\s+"true"/)
519
+ if opts.include?('redownload')
520
+ run(bundle_output('config unset frozen'), banner: false)
521
+ else
522
+ print_error('Gemfile.lock is frozen', subject: name, hint: flag)
523
+ lock = nil
524
+ end
519
525
  end
520
526
  end
521
527
  lock&.delete
@@ -775,8 +781,7 @@ module Squared
775
781
  next if val == '0' || val == 'false'
776
782
 
777
783
  run(bundle_output('binstubs --all', case val
778
- when '1', 'true'
779
- nil
784
+ when '1', 'true' then nil
780
785
  else
781
786
  if val.start_with?('~')
782
787
  val = File.join(Dir.home, val == '~' ? '.bundle' : val[1..-1])
@@ -1067,6 +1072,7 @@ module Squared
1067
1072
  buffer = []
1068
1073
  filter = kwargs.fetch(:filter, {})
1069
1074
  semver = filter[:semver]
1075
+ dryrun = filter[:dryrun] || dryrun?(prefix: 'gem')
1070
1076
  update = if sync && filter[:select]
1071
1077
  semver ||= 'major'
1072
1078
  items = []
@@ -1219,7 +1225,7 @@ module Squared
1219
1225
  'user-install'
1220
1226
  end
1221
1227
  end
1222
- if filter[:dryrun]
1228
+ if dryrun
1223
1229
  print_run gem_output('update -f', *update.quote!(escape: true)), false
1224
1230
  else
1225
1231
  gem(:update, *update, opts: opts)
@@ -1261,8 +1267,8 @@ module Squared
1261
1267
  .clear(pass: false)
1262
1268
  end
1263
1269
  when :push
1264
- if op.empty? || (n = op.index(':'))
1265
- file = basepath(if !n && (spec = gemspec)
1270
+ if op.empty? || ia
1271
+ file = basepath(if !ia && (spec = gemspec)
1266
1272
  "#{spec.name}-#{spec.version}.gem"
1267
1273
  else
1268
1274
  choice_index 'Select a file', Dir.glob('*.gem', base: path)
@@ -1826,8 +1832,8 @@ module Squared
1826
1832
  private
1827
1833
 
1828
1834
  def run_repl(*args, opts:, banner:, from:, delim: true, **kwargs)
1829
- op = OptionPartition.new(opts, OPT_RUBY[from], session(*bundle_args(from)), project: self, strict: strict?,
1830
- first: [/\.rb$/])
1835
+ op = OptionPartition.new(opts, OPT_RUBY[from], session(*bundle_args(from)),
1836
+ project: self, strict: strict?, first: [/\.rb$/])
1831
1837
  r = []
1832
1838
  r << 'bundler/setup' if !op.arg?('r') && bundle_load
1833
1839
  r.concat(Array(kwargs[:name])) if kwargs[:name]
@@ -1915,8 +1921,7 @@ module Squared
1915
1921
  val = case (val = $2)
1916
1922
  when 'true'
1917
1923
  true
1918
- when '', '[]'
1919
- nil
1924
+ when '', '[]' then nil
1920
1925
  else
1921
1926
  if val =~ /\A\[:(.+)\]\z/
1922
1927
  $1.split(', :').map { |s| (s[/\A"(.+)"\z/, 1] || s).to_sym }
@@ -26,13 +26,29 @@ module Squared
26
26
  end
27
27
  end
28
28
 
29
- def matchmap(list, prefix = nil)
30
- list.map do |val|
31
- next val if val.is_a?(Regexp)
32
-
33
- val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
34
- Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
29
+ def matchmap(list, prefix = nil, negate: false)
30
+ ret = negate ? [[], []] : []
31
+ list.each do |val|
32
+ unless val.is_a?(Regexp)
33
+ val = val.dup
34
+ n = 1 if negate && val.delete_prefix!('!')
35
+ if prefix
36
+ a = nil
37
+ val.sub!(/\A(\^|\\A)/) do |s|
38
+ a = s
39
+ nil
40
+ end
41
+ val = ".*#{val}" unless a
42
+ end
43
+ end
44
+ pat = Regexp.new("#{a}#{prefix}#{val == '*' ? '.+' : val}")
45
+ if negate
46
+ ret[n || 0] << pat
47
+ else
48
+ ret << pat
49
+ end
35
50
  end
51
+ ret
36
52
  end
37
53
 
38
54
  def matchany?(list, *args, empty: true)
@@ -157,8 +157,6 @@ module Squared
157
157
  [proj, proj.build? && (script || run), doc && proj.doc?, lint && proj.lint?, test && proj.test?]
158
158
  end
159
159
  .select do |proj, run, doc, lint, test|
160
- next unless proj
161
-
162
160
  proj.doc(sync: true) if doc
163
161
  proj.build(sync: true) if run
164
162
  next if n.anybits?(4)
@@ -186,8 +184,7 @@ module Squared
186
184
  end
187
185
  env('REPO_GROUPS', **envargs) do |val|
188
186
  g = case val
189
- when '0', 'false'
190
- nil
187
+ when '0', 'false' then nil
191
188
  else
192
189
  val
193
190
  end
@@ -209,8 +209,9 @@ module Squared
209
209
  already_invoked? parallel, val
210
210
  end
211
211
 
212
- def exclude?(key, empty = false)
213
- @exclude.include?(key) || (empty && (!key?(key) || self[key].empty?))
212
+ def exclude?(key, fallback = false, empty: nil)
213
+ fallback = empty unless empty.nil?
214
+ @exclude.include?(key) || (fallback && (!key?(key) || self[key].empty?))
214
215
  end
215
216
 
216
217
  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.7.8
4
+ version: 0.7.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 4.0.12
128
+ rubygems_version: 4.0.15
129
129
  specification_version: 4
130
130
  summary: Rake task generator for managing multi-language workspaces.
131
131
  test_files: []