squared 0.6.8 → 0.6.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: f3fd4d34940e2ce81d6aff4d5bb9ccd827c8c11f755808778c0f266fc53fbf00
4
- data.tar.gz: 4a030838743ef95041fe4cd53a6a4491f9d5a5f89cca6dc1283c04429644cdc1
3
+ metadata.gz: 51fbe5bab2648700b1859c3cf76d5960e1e6d02084281444e5113a02365ecfc6
4
+ data.tar.gz: f3179ae97b2035233ac01856bd9f775462afb87183da51c3be34eb6357813f61
5
5
  SHA512:
6
- metadata.gz: d4e1ddf573b20ea122f1b03d0c7d14ac23542d09aac252ae5eda2185a13a1e42fc32302b82896a6ca07ec6dfcf58dfed81dc3e009f2f7b8c2b8f4ba10fddfe5c
7
- data.tar.gz: 97bda796bfed20453137241f0f6cd98362d877fccc4674e1a1a0e615f1059ea8067d28a9f1d31e4a96b60c7fbb4011bb58ee05877e47ae3be0c41aea855bc872
6
+ metadata.gz: 368045e7cd2f56b56e95e5d5809346d69e87c41fb3a3b8f33af001844d0d18f63fc5f72abca10d166c7b6af51443dd52ddd2fd9ee72aff1fe67f38e9d7a02526
7
+ data.tar.gz: e750addd94fab922f914ffd75b771c2b5710b64f4375229dc52d7b1129637a5eccd857a7fe39ba51254793f4e3de78c041d73c644accee0a083164abf3132fa4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.10] - 2025-02-23
4
+
5
+ ### Added
6
+
7
+ - Docker command image action [ls|rm|tag|save] can be filtered.
8
+ - Pip command options were updated to 26.1.
9
+
10
+ ### Changed
11
+
12
+ - Ruby property autodetect was converted into an accessor.
13
+ - Python property editable was converted into an accessor.
14
+
15
+ ### Fixed
16
+
17
+ - Git task show was completely non-functional due to excessive formatting.
18
+ - Gem command install did not respond to interactive prompt.
19
+ - Docker task clean does not run in parallel without ENV override.
20
+
21
+ ## [0.6.9] - 2025-01-07
22
+
23
+ ### Added
24
+
25
+ - Bundler command config can be executed without [set|get] actions.
26
+
27
+ ### Changed
28
+
29
+ - Application method with using hide and pass compatibility was implemented.
30
+
31
+ ## [0.5.21] - 2025-12-31
32
+
33
+ ### Fixed
34
+
35
+ - See `0.4.35`.
36
+
37
+ ## [0.4.35] - 2025-12-31
38
+
39
+ ### Changed
40
+
41
+ - Ruby task copy uses GEM_HOME as fallback for autodetect.
42
+
43
+ ### Fixed
44
+
45
+ - Git commands [rebase|clone] did not forward sync flag.
46
+ - Pip command install carelessly used an undefined method.
47
+ - Common prompt method readline with multiline did not permit empty lines.
48
+ - Application method with using pass did not ignore exceptions.
49
+ - Git method source did not check command object for supported method.
50
+
3
51
  ## [0.6.8] - 2025-12-26
4
52
 
5
53
  ### Added
@@ -1565,6 +1613,8 @@
1565
1613
 
1566
1614
  - Changelog was created.
1567
1615
 
1616
+ [0.6.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.10
1617
+ [0.6.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.9
1568
1618
  [0.6.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.8
1569
1619
  [0.6.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.7
1570
1620
  [0.6.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.6
@@ -1574,6 +1624,7 @@
1574
1624
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1575
1625
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1576
1626
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1627
+ [0.5.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.21
1577
1628
  [0.5.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.20
1578
1629
  [0.5.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.19
1579
1630
  [0.5.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.18
@@ -1595,6 +1646,7 @@
1595
1646
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1596
1647
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1597
1648
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1649
+ [0.4.35]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.35
1598
1650
  [0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
1599
1651
  [0.4.33]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.33
1600
1652
  [0.4.32]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.32
data/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  | 2025-01-07 | 0.2.0 | | 3.4.0 |
12
12
  | 2025-02-07 | 0.3.0 | | 3.4.1 |
13
13
  | 2025-03-06 | 0.4.0 | | 3.4.2 |
14
- | 2025-06-16 | 0.5.0 | 2.5.0 | 3.4.3 |
14
+ | 2025-06-16 | 0.5.0 | 2.5.0 | 3.4.4 |
15
15
  | ---------- | ----- | ----- | ----- |
16
16
  | 2025-08-23 | 0.5.5 | | 3.4.5 |
17
17
  | 2025-10-31 | 0.6.0 | | 3.4.7 |
@@ -733,12 +733,13 @@ docker build --no-cache --label=v1 --build-arg="NODE_TAG=24" --build-arg="RUBY_V
733
733
  | compose | build | TARGET=s |
734
734
  | compose | run | VERSION=s |
735
735
  | container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
736
- | container | -run -create -exec | ALL=1 |
736
+ | container | -run -create -exec | ALL=1 FILTER=s |
737
737
  | | -update -commit | |
738
738
  | image | rm | Y=1 |
739
739
  | image | push | TAG=s REGISTRY=s |
740
740
  | image | -push | ALL=1 |
741
- | network | * | ALL=1 |
741
+ | image | -push -pull | FILTER=s |
742
+ | network | * | ALL=1 FILTER=s |
742
743
 
743
744
  ### asdf
744
745
 
@@ -806,7 +807,7 @@ REPO_MANIFEST # e.g. latest,nightly,prod
806
807
  REPO_GROUPS # e.g. base,prod,docs
807
808
  REPO_STAGE # 0,1,2,3,4
808
809
  REPO_SUBMODULLES # 0,1
809
- REPO_Y # 0,1
810
+ REPO_Y # 0,1 (bypass interactive prompt)
810
811
  REPO_TIMEOUT # confirm dialog (seconds)
811
812
  ```
812
813
 
@@ -835,7 +836,7 @@ Features can be enabled through ENV when calling global tasks such as through *C
835
836
  | :------------- | :------------- | :------------------------------------------------------- |
836
837
  | depend | - | FORCE CI IGNORE_SCRIPTS |
837
838
  | outdated | - | U|UPDATE=major|minor|patch DIFF DRY_RUN |
838
- | publish | - | OTP=s TAG=s ACCESS=0,1,s DRY_RUN |
839
+ | publish | - | OTP=s TAG=s ACCESS=0,1,s DRY_RUN Y |
839
840
  | depend package | * | PACAKGE_LOCK|LOCKFILE=0 NO_LOCKFILE=1 Y |
840
841
  | npm pnpm | depend package | CPU=s OS=s LIBC=s |
841
842
  | npm | package | SAVE IGNORE_SCRIPTS STRICT_PEER_DEPS |
@@ -261,6 +261,8 @@ module Squared
261
261
  lines = val.to_s.lines(chomp: true)
262
262
  lines[0] = "#{val.class}: #{lines.first}" if (err = val.is_a?(::StandardError))
263
263
  end
264
+ return if lines.empty?
265
+
264
266
  n = (cols.is_a?(::Array) ? cols.map(&:size).max : cols) || max.call(lines)
265
267
  if $stdout.tty?
266
268
  require 'io/console'
@@ -138,7 +138,11 @@ module Squared
138
138
  elsif block_given?
139
139
  Readline.readmultiline(msg, history, &blk)
140
140
  else
141
- Readline.readmultiline(msg, history) { |line| multiline.any? { |val| line.split.last.end_with?(val.to_s) } }
141
+ Readline.readmultiline(msg, history) do |line|
142
+ next if line.strip.empty?
143
+
144
+ multiline.any? { |val| line.split.last.end_with?(val.to_s) }
145
+ end
142
146
  end
143
147
  end
144
148
  case force
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.8'
4
+ VERSION = '0.6.10'
5
5
  end
@@ -201,8 +201,25 @@ module Squared
201
201
  self
202
202
  end
203
203
 
204
- def with(*val, pass: false, group: nil, **kwargs, &blk)
205
- return self if pass == true || (pass && as_a(pass, :to_s).any? { |s| respond_to?(s) && __send__(s) })
204
+ def with(*val, hide: nil, group: nil, **kwargs, &blk)
205
+ if hide.nil? && kwargs.key?(:pass)
206
+ pass = kwargs[:pass]
207
+ case pass
208
+ when true, false
209
+ hide = pass
210
+ kwargs.delete(:pass)
211
+ else
212
+ hide, pass = Array(pass).partition { |s| respond_to?(s) || s.to_s.end_with?('?') }
213
+ if pass.empty?
214
+ kwargs.delete(:pass)
215
+ elsif hide.empty?
216
+ hide = nil
217
+ else
218
+ kwargs[:pass] = pass
219
+ end
220
+ end
221
+ end
222
+ return self if hide == true || (hide && Array(hide).any? { |s| respond_to?(s) && __send__(s) rescue nil })
206
223
 
207
224
  @group = nil
208
225
  @ref = nil
@@ -508,7 +508,7 @@ module Squared
508
508
  end
509
509
 
510
510
  def build(*args, sync: invoked_sync?('build'), from: :run, **)
511
- banner = verbose
511
+ banner = !silent?
512
512
  if args.empty?
513
513
  return unless from == :run
514
514
 
@@ -716,7 +716,7 @@ module Squared
716
716
  end
717
717
 
718
718
  def unpack(target, file = nil, uri: nil, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {},
719
- verbose: self.verbose, from: :unpack)
719
+ verbose: !silent?, from: :unpack)
720
720
  if !target.exist?
721
721
  target.mkpath
722
722
  elsif !target.directory?
@@ -1226,8 +1226,7 @@ module Squared
1226
1226
  run(val, var, sync: sync, banner: banner, **kwargs)
1227
1227
  end
1228
1228
  rescue StandardError => e
1229
- ret = on :error, from, e
1230
- raise unless ret == true
1229
+ on_error(e, from, exception: kwargs.fetch(:exception, exception))
1231
1230
  end
1232
1231
  on :last, from
1233
1232
  end
@@ -1277,6 +1276,8 @@ module Squared
1277
1276
  else
1278
1277
  items = data[target.name] - done
1279
1278
  end
1279
+ return done if items.empty?
1280
+
1280
1281
  if out
1281
1282
  a, b, c, d, e = ARG[:GRAPH]
1282
1283
  f = tag.call(target)
@@ -1370,8 +1371,8 @@ module Squared
1370
1371
  if (obj = workspace.find(name: val))
1371
1372
  obj.enabled? ? [obj] : []
1372
1373
  else
1373
- workspace.find(group: val, ref: val.to_sym)
1374
- end.sort.each do |proj|
1374
+ workspace.find(group: val, ref: val.to_sym).sort
1375
+ end.each do |proj|
1375
1376
  next if pass.include?(name = proj.name)
1376
1377
 
1377
1378
  if proj.graph? && !data.key?(name) && !root.include?(name)
@@ -1541,7 +1542,7 @@ module Squared
1541
1542
  end
1542
1543
 
1543
1544
  def print_run(cmd, banner = true, verbose: nil, **)
1544
- return if banner || !stdout? || verbose == false
1545
+ return if banner || !stdout? || verbose == false || env('BANNER', equals: '0')
1545
1546
 
1546
1547
  puts "\n> #{cmd}"
1547
1548
  printsucc
@@ -1725,7 +1726,9 @@ module Squared
1725
1726
  next if val.nil?
1726
1727
  end
1727
1728
  case val
1728
- when Array
1729
+ when Hash
1730
+ append_hash(val, target: target, build: build)
1731
+ when Enumerable
1729
1732
  append_repeat(key, val, target: target)
1730
1733
  when Numeric
1731
1734
  target << basic_option(key, val)
@@ -1809,10 +1812,10 @@ module Squared
1809
1812
  next unless data.key?(key)
1810
1813
 
1811
1814
  out[key] = case (val = data[key])
1812
- when Array
1813
- base.fetch(key, []) + val
1814
1815
  when Hash
1815
1816
  base.fetch(key, {}).update(val)
1817
+ when Enumerable
1818
+ Array(base.fetch(key, [])) + val.to_a
1816
1819
  else
1817
1820
  val
1818
1821
  end
@@ -1915,8 +1918,10 @@ module Squared
1915
1918
  args
1916
1919
  end
1917
1920
 
1918
- def confirm_basic(msg, target, default = 'Y', style: :inline, **kwargs)
1919
- confirm("#{msg} [#{sub_style(target.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
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)
1923
+
1924
+ confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
1920
1925
  end
1921
1926
 
1922
1927
  def confirm_outdated(pkg, ver, type, cur = nil, lock: false, col0: 0, col1: 0, col2: nil, col3: 0, col4: 0,
@@ -2269,7 +2274,9 @@ module Squared
2269
2274
  end
2270
2275
  self.global = global
2271
2276
  case cmd
2272
- when Array
2277
+ when Hash
2278
+ @output = parse.call(data)
2279
+ when Enumerable
2273
2280
  @output = if cmd.all? { |data| data.is_a?(Hash) }
2274
2281
  noopt = false
2275
2282
  noenv = false
@@ -2278,8 +2285,6 @@ module Squared
2278
2285
  cmd.dup
2279
2286
  end
2280
2287
  return
2281
- when Hash
2282
- @output = parse.call(data)
2283
2288
  else
2284
2289
  @output[0] = cmd
2285
2290
  end
@@ -282,14 +282,18 @@ module Squared
282
282
  end
283
283
  else
284
284
  format_desc(action, flag, case flag
285
- when :rm, :save then 'id*,opts*'
286
- when :tag then 'version?'
285
+ when :rm, :save then 'id,opts*'
286
+ when :tag then 'version'
287
287
  else 'opts*,args*'
288
- end)
288
+ end, before: 'pattern?')
289
289
  task flag do |_, args|
290
290
  args = args.to_a
291
+ n = args.size
292
+ if (n > 1 || (flag == :ls && n > 0)) && OptionPartition.pattern?(args.first)
293
+ filter = args.shift
294
+ end
291
295
  if !args.empty? || flag == :ls
292
- image flag, args
296
+ image(flag, args, filter: filter)
293
297
  else
294
298
  choice_command flag
295
299
  end
@@ -315,8 +319,8 @@ module Squared
315
319
  def clean(*, sync: invoked_sync?('clean'), **)
316
320
  if runnable?(@clean)
317
321
  super
318
- else
319
- image(:rm, sync: sync)
322
+ elsif sync || option('y', prefix: 'docker')
323
+ image :rm
320
324
  end
321
325
  end
322
326
 
@@ -533,7 +537,7 @@ module Squared
533
537
  run(from: from)
534
538
  end
535
539
 
536
- def image(flag, opts = [], sync: true, id: nil, registry: nil)
540
+ def image(flag, opts = [], sync: true, id: nil, registry: nil, filter: nil)
537
541
  cmd, opts = docker_session('image', flag, opts: opts)
538
542
  op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
539
543
  exception = self.exception
@@ -551,7 +555,7 @@ module Squared
551
555
  opts.delete(val)
552
556
  break
553
557
  end
554
- list_image(:run, from: from) do |val|
558
+ list_image(:run, filter: filter, from: from) do |val|
555
559
  container(:run, if name
556
560
  opts.dup << "name=#{index == 0 ? name : "#{name}-#{index}"}"
557
561
  else
@@ -565,9 +569,7 @@ module Squared
565
569
  when :rm
566
570
  unless id
567
571
  if op.empty?
568
- list_image(:rm, from: from) do |val|
569
- image(:rm, opts, sync: sync, id: val)
570
- end
572
+ list_image(:rm, filter: filter, from: from) { |val| image(:rm, opts, sync: sync, id: val) }
571
573
  else
572
574
  op.each { |val| run(cmd.temp(val), sync: sync, from: from) }
573
575
  end
@@ -579,13 +581,16 @@ module Squared
579
581
  banner = false
580
582
  end
581
583
  when :tag, :save
582
- list_image(flag, from: from) do |val|
584
+ found = false
585
+ list_image(flag, filter: filter, from: from) do |val|
583
586
  op << val
587
+ found = true
584
588
  if flag == :tag
585
589
  op << tagname("#{project}:#{op.first}")
586
590
  break
587
591
  end
588
592
  end
593
+ raise_error ArgumentError, 'target not specified', hint: flag unless found
589
594
  when :push
590
595
  id ||= option('tag', ignore: false) || tagmain
591
596
  registry ||= op.shift || option('registry') || @registry
@@ -774,12 +779,20 @@ module Squared
774
779
  [cmd, status, no]
775
780
  end
776
781
 
777
- def list_image(flag, cmd = docker_output('image ls -a'), hint: nil, from: nil, no: true)
778
- pwd_set do
782
+ def list_image(flag, cmd = docker_output('image ls -a'), filter: nil, hint: nil, no: true, from: nil)
783
+ pwd_set(from: from) do
779
784
  index = 1
780
785
  all = option('all', prefix: 'docker')
781
786
  y = from == :'image:rm' && option('y', prefix: 'docker')
782
- pat = /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})\b/
787
+ filter = env('DOCKER_FILTER', filter).to_s
788
+ pat = if OptionPartition.pattern?(filter)
789
+ Regexp.new(filter)
790
+ elsif filter.match?(/[:_-]$/)
791
+ /\b#{Regexp.escape(filter)}/
792
+ else
793
+ filter = filter.empty? ? '(?:[:_-]|$)' : "[:_-]#{filter}"
794
+ /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})#{filter}/
795
+ end
783
796
  IO.popen(cmd.temp('--format=json')).each do |line|
784
797
  data = JSON.parse(line)
785
798
  id = data['ID']
@@ -1075,7 +1075,7 @@ module Squared
1075
1075
 
1076
1076
  cmd << "--#{command}"
1077
1077
  end
1078
- source
1078
+ source(sync: sync)
1079
1079
  end
1080
1080
 
1081
1081
  def autostash(*, sync: invoked_sync?('autostash'), **)
@@ -1128,7 +1128,7 @@ module Squared
1128
1128
  append_hash opts
1129
1129
  cmd << '--quiet' if option('quiet') || !verbose
1130
1130
  append_value(data[0], path, delim: true)
1131
- source(banner: sync && !quiet?, multiple: !sync || quiet?)
1131
+ source(sync: sync, banner: sync && !quiet?, multiple: !sync || quiet?)
1132
1132
  end
1133
1133
 
1134
1134
  def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
@@ -1747,8 +1747,9 @@ module Squared
1747
1747
  opts << format if format
1748
1748
  end
1749
1749
  list = OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context]
1750
- op = OptionPartition.new(opts, list, cmd, project: self, pass: [:base],
1751
- no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log]))
1750
+ op = OptionPartition.new(opts, list, cmd,
1751
+ project: self,
1752
+ no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
1752
1753
  op.append(delim: true)
1753
1754
  source(exception: false, banner: flag != :oneline)
1754
1755
  end
@@ -1892,16 +1893,19 @@ module Squared
1892
1893
  banner = nil unless banner? && !multiple
1893
1894
  args = true
1894
1895
  end
1895
- if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) })
1896
- from = :"git:#{from}"
1897
- elsif from == false
1896
+ if from == false
1898
1897
  from = nil
1898
+ elsif !from && cmd.respond_to?(:drop)
1899
+ from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) }
1900
+ from &&= :"git:#{from}"
1899
1901
  end
1900
1902
  banner &&= cmd.temp { |val| val.start_with?(/--(?:work-tree|git-dir)/) } if cmd.respond_to?(:temp)
1901
1903
  end
1902
1904
  cmd = session_done cmd
1903
1905
  log&.info cmd
1904
- banner = format_banner(banner.is_a?(String) ? banner : cmd, hint: hint, strip: true) if banner
1906
+ banner = if banner
1907
+ format_banner(banner.is_a?(String) ? banner : cmd, hint: hint, strip: true)
1908
+ end
1905
1909
  on :first, from
1906
1910
  begin
1907
1911
  if io
@@ -1914,7 +1918,7 @@ module Squared
1914
1918
  raise(ret.empty? ? $?.to_s : ret) unless $?.success?
1915
1919
 
1916
1920
  if ret.empty?
1917
- success?(nil, !banner.nil?)
1921
+ success?(true, !banner.nil?)
1918
1922
  else
1919
1923
  puts ret
1920
1924
  end
@@ -1928,7 +1932,7 @@ module Squared
1928
1932
  n = write_lines(out, banner: banner, pass: true, **kwargs)
1929
1933
  if n == 0
1930
1934
  n = write_lines(err, banner: banner)
1931
- success?(nil, n == 0 && !banner.nil?)
1935
+ success?(n == 0, n == 0 && !banner.nil?)
1932
1936
  else
1933
1937
  write_lines(err, loglevel: Logger::DEBUG)
1934
1938
  end
@@ -5,7 +5,7 @@ module Squared
5
5
  module Project
6
6
  class Node < Git
7
7
  OPT_NPM = {
8
- common: %w[dry-run=!? loglevel=b include-workspace-root=!? workspaces=!? w|workspace=v].freeze,
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
10
  install_a: %w[audit=! bin-links=! foreground-scripts=!? fund=! ignore-scripts=!? install-links=!?
11
11
  package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
@@ -877,7 +877,7 @@ module Squared
877
877
  log.info cmd.to_s
878
878
  end
879
879
  if sync
880
- run(from: from, sync: sync, interactive: !dryrun && ['Publish', 'N', npmname])
880
+ run(sync: sync, from: from, interactive: !dryrun && ['Publish', 'N', npmname])
881
881
  else
882
882
  require 'open3'
883
883
  on :first, from
@@ -1055,7 +1055,7 @@ module Squared
1055
1055
  raise_error 'version not found', hint: dependfile
1056
1056
  end
1057
1057
  rescue StandardError => e
1058
- on_error e, :bump
1058
+ on_error(e, :bump, dryrun: dryrun?)
1059
1059
  end
1060
1060
 
1061
1061
  def pack(opts = [])
@@ -1329,7 +1329,7 @@ module Squared
1329
1329
 
1330
1330
  def remove_modules(prefix = dependbin)
1331
1331
  modules = basepath 'node_modules'
1332
- return false unless modules.directory? && (option('y', prefix: prefix) || confirm_basic('Remove?', modules))
1332
+ return false unless modules.directory? && confirm_basic('Remove?', modules, prefix: prefix)
1333
1333
 
1334
1334
  modules.rmtree
1335
1335
  rescue Timeout::Error => e
@@ -29,14 +29,16 @@ module Squared
29
29
  install: %w[break-system-packages compile dry-run force-reinstall I|ignore-installed no-compile
30
30
  no-warn-conflicts no-warn-script-location U|upgrade user prefix=p report=p root=p
31
31
  root-user-action=b t|target=p upgrade-strategy=b].freeze,
32
- install_a: %w[ignore-requires-python no-index pre extra-index-url=q f|find-links=q i|index-url=q no-binary=q
33
- only-binary=q].freeze,
34
- install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps prefer-binary
35
- require-hashes use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p src=p].freeze,
32
+ install_a: %w[ignore-requires-python no-index pre prefer-binary all-releases=b extra-index-url=q
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
36
+ requirements-from-script=p src=p].freeze,
36
37
  install_c: %w[C|config-settings=q e|editable=v].freeze,
37
38
  hash: %w[a|algorithm].freeze,
38
- list: %w[e|editable exclude-editable include-editable l|local no-index not-required o|outdated pre u|uptodate
39
- user exclude=b extra-index-url=q format=b f|find-links=q i|index-url=q path=p].freeze,
39
+ list: %w[e|editable exclude-editable include-editable l|local no-index not-required o|outdated pre
40
+ prefer-binary u|uptodate user all-releases=b exclude=b extra-index-url=q format=b f|find-links=q
41
+ i|index-url=q no-binary=q only-binary=q only-final=b path=p].freeze,
40
42
  lock: %w[o|output=p].freeze,
41
43
  show: %w[f|files].freeze,
42
44
  uninstall: %w[break-system-packages y|yes r|requirement=p root-user-action=b].freeze,
@@ -73,7 +75,7 @@ module Squared
73
75
  debug: %w[platform].freeze,
74
76
  install: %w[C config-settings c constraint extra-index-url no-binary only-binary platform
75
77
  r requirement].freeze,
76
- list: %w[exclude extra-index-url].freeze
78
+ list: %w[exclude extra-index-url no-binary only-binary].freeze
77
79
  }.freeze
78
80
  }.freeze
79
81
  private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE,
@@ -99,7 +101,8 @@ module Squared
99
101
  end
100
102
  end
101
103
 
102
- attr_reader :venv, :editable
104
+ attr_reader :venv
105
+ attr_accessor :editable
103
106
 
104
107
  def initialize(*, editable: '.', asdf: 'python', **kwargs)
105
108
  super
@@ -249,7 +252,7 @@ module Squared
249
252
  if args.empty?
250
253
  args = readline('Enter command', force: true).split(' ', 2)
251
254
  elsif args.size == 1 && !option('interactive', equals: '0', prefix: ref)
252
- args << readline('Enter arguments', force: false)
255
+ args << readline('Enter arguments', force: false) unless args.first.include?(' ')
253
256
  end
254
257
  venv_init
255
258
  run args.join(' ')
@@ -404,7 +407,7 @@ module Squared
404
407
  cmd << "-r #{DEP_PYTHON[4]}" if exist?(DEP_PYTHON[4]) && !session_arg?('r', 'requirement')
405
408
  append_editable
406
409
  end
407
- run(from: :depend, sync: sync)
410
+ run(sync: sync, from: :depend)
408
411
  end
409
412
  end
410
413
 
@@ -48,7 +48,7 @@ module Squared
48
48
  cache: %w[frozen no-all no-install no-prune quiet cache-path=p gemfile=p].freeze,
49
49
  check: %w[dry-run gemfile=p path=p].freeze,
50
50
  clean: %w[dry-run force].freeze,
51
- config: %w[global local].freeze,
51
+ config: %w[global local skip-parseable].freeze,
52
52
  doctor: %w[quiet ssl gemfile=p].freeze,
53
53
  doctor_ssl: %w[host=q tls-version=b verify-mode=b].freeze,
54
54
  exec: %w[gemfile=p].freeze,
@@ -69,6 +69,7 @@ module Squared
69
69
  show: %w[outdated paths].freeze,
70
70
  update: %w[all conservative local major minor patch pre ruby strict bundler=b? g|group=q source=q].freeze,
71
71
  no: {
72
+ config: %w[parseable].freeze,
72
73
  gem: %w[changelog ci coc exe linter mit test].freeze
73
74
  }.freeze
74
75
  }.freeze
@@ -186,6 +187,7 @@ module Squared
186
187
  })
187
188
 
188
189
  attr_reader :gemdir
190
+ attr_accessor :autodetect
189
191
 
190
192
  def initialize(*, autodetect: false, gemspec: nil, steep: 'Steepfile', rubocop: '.rubocop.yml', asdf: 'ruby',
191
193
  **kwargs)
@@ -198,7 +200,7 @@ module Squared
198
200
  initialize_env(**kwargs)
199
201
  end
200
202
  dependfile_set GEMFILE
201
- @autodetect = autodetect
203
+ self.autodetect = autodetect
202
204
  @gemfile = if gemspec == false
203
205
  false
204
206
  elsif gemspec
@@ -206,7 +208,7 @@ module Squared
206
208
  end
207
209
  @steepfile = basepath! steep if steep
208
210
  @rubocopfile = Pathname.new(rubocop).realpath rescue basepath!(Dir.home, '.rubocop.yml') if rubocop
209
- return unless rakefile && @output[0].nil? && @copy.nil? && !version && !@autodetect
211
+ return unless rakefile && @output[0].nil? && @copy.nil? && !version && !self.autodetect
210
212
 
211
213
  begin
212
214
  File.foreach(rakefile) do |line|
@@ -442,10 +444,10 @@ module Squared
442
444
  when :exec then 'command,args*|:'
443
445
  end)
444
446
  task flag do |_, args|
445
- bundle(flag, opts: args.to_a, banner: true)
447
+ bundle(flag, opts: args.to_a, banner: flag == :exec ? verbose? : true)
446
448
  end
447
449
  when :config
448
- format_desc action, flag, 'list|set|get|unset?,args*'
450
+ format_desc action, flag, 'list|set|get|unset?,opts*,args*'
449
451
  task flag do |_, args|
450
452
  bundle(flag, *args.to_a, banner: true)
451
453
  end
@@ -551,7 +553,7 @@ module Squared
551
553
  end
552
554
  end
553
555
  option('jobs') { |n| cmd << "-j#{n}" if n.to_i > 0 }
554
- run_rb(from: :depend, sync: sync)
556
+ run_rb(sync: sync, from: :depend)
555
557
  end
556
558
  end
557
559
 
@@ -765,41 +767,42 @@ module Squared
765
767
  order = { 'rbenv' => -1, 'rvm' => -1, 'asdf' => -1, 'chruby' => -1 }
766
768
  ENV.fetch('PATH', '').split(':').each_with_index do |val, index|
767
769
  order.each_key do |key|
768
- if val.match?(%r{[/.]#{key}/})
769
- order[key] = index
770
- break
771
- end
770
+ next unless val.match?(%r{[/.]#{key}/})
771
+
772
+ order[key] = index
773
+ break
772
774
  end
773
775
  end
774
- paths = [
775
- "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
776
- '$HOME/.rvm/bin/rvm',
777
- @asdf ? "#{ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf')}/installs/#{@asdf.first}" : nil,
778
- '/usr/bin/rbenv',
779
- '/usr/local/rvm/bin/rvm',
780
- '/usr/share/rvm/bin/rvm',
781
- '/usr/local/share/chruby/chruby.sh'
782
- ].compact
783
- paths.sort do |a, b|
784
- c = -1
785
- d = -1
786
- order.each do |key, val|
787
- pat = %r{/\.?#{key}}
788
- c = val if a.match?(pat)
789
- d = val if b.match?(pat)
790
- end
791
- if c == d
792
- 0
793
- elsif c == -1
794
- 1
795
- elsif d == -1
796
- -1
797
- else
798
- c < d ? -1 : 1
776
+ if @asdf
777
+ [File.join(ENV.fetch('ASDF_DATA_DIR', '$HOME/.asdf'), "installs/#{@asdf.first}")]
778
+ else
779
+ [
780
+ "#{ENV.fetch('RBENV_ROOT', '$HOME/.rbenv')}/bin/rbenv",
781
+ '$HOME/.rvm/bin/rvm',
782
+ '/usr/bin/rbenv',
783
+ '/usr/local/rvm/bin/rvm',
784
+ '/usr/share/rvm/bin/rvm',
785
+ '/usr/local/share/chruby/chruby.sh'
786
+ ].sort do |a, b|
787
+ c = -1
788
+ d = -1
789
+ order.each do |key, val|
790
+ pat = %r{/\.?#{key}}
791
+ c = val if a.match?(pat)
792
+ d = val if b.match?(pat)
793
+ end
794
+ if c == d
795
+ 0
796
+ elsif c == -1
797
+ 1
798
+ elsif d == -1
799
+ -1
800
+ else
801
+ c < d ? -1 : 1
802
+ end
799
803
  end
800
- end
801
- .push('')
802
- .each do |val|
804
+ .push('')
805
+ end.each do |val|
803
806
  next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
804
807
 
805
808
  trim = ->(s) { s[/^\D+\d+\.\d+(?:\.\S+)?/, 0].sub(/^([a-z]+)-/i, '\1 ') }
@@ -1104,6 +1107,7 @@ module Squared
1104
1107
  when :dependency, :environment, :list, :search, :specification, :which
1105
1108
  op.concat(args)
1106
1109
  end
1110
+ ia = op.remove(':')
1107
1111
  op.each do |opt|
1108
1112
  if gems && !opt.start_with?('-') && !opt.match?(GEMNAME)
1109
1113
  op.errors << opt
@@ -1167,7 +1171,7 @@ module Squared
1167
1171
  end
1168
1172
  when :install, :uninstall, :pristine
1169
1173
  if flag == :install
1170
- post = if op.remove(':')
1174
+ post = if ia
1171
1175
  op.concat(args)
1172
1176
  readline('Enter command [args]', force: true)
1173
1177
  elsif op.empty?
@@ -1185,14 +1189,14 @@ module Squared
1185
1189
  else
1186
1190
  op.clear
1187
1191
  end
1188
- elsif (n = op.index { |val| val.match?(/(\A|[a-z])@\d/) })
1192
+ elsif (n = op.index { |val| val.match?(/(\A|[\w.-])@\d/) })
1189
1193
  name = op.remove_at(n)
1190
1194
  pre, ver = if (n = name.index('@')) == 0
1191
1195
  [gemname, name[1..-1]]
1192
1196
  else
1193
1197
  [name[0, n], name[n.succ..-1]]
1194
1198
  end
1195
- op.adjoin(pre, basic_option('version', ver))
1199
+ op.adjoin(pre, quote_option('version', ver))
1196
1200
  .clear
1197
1201
  end
1198
1202
  if flag == :install
@@ -1258,15 +1262,27 @@ module Squared
1258
1262
  when :cache, :check, :clean, :init, :install, :lock, :pack, :package, :platform
1259
1263
  pre = true
1260
1264
  opts.concat(args)
1265
+ when :config
1266
+ if args.empty?
1267
+ pre = true
1268
+ else
1269
+ case (pre = args.shift)
1270
+ when 'list', 'get', 'set', 'unset'
1271
+ cmd << pre
1272
+ else
1273
+ args.unshift(pre)
1274
+ end
1275
+ opts.concat(args)
1276
+ end
1261
1277
  when :doctor
1262
1278
  case (pre = (val = args.shift) || opts.shift)
1263
1279
  when 'diagnose', 'ssl'
1264
1280
  cmd << pre
1265
1281
  else
1266
1282
  if val
1267
- args << val
1283
+ args.unshift(val)
1268
1284
  elsif pre
1269
- opts << pre
1285
+ opts.unshift(pre)
1270
1286
  end
1271
1287
  pre = true
1272
1288
  end
@@ -1286,54 +1302,57 @@ module Squared
1286
1302
  else
1287
1303
  flag
1288
1304
  end),
1289
- cmd, project: self, no: OPT_BUNDLE[:no][flag], args: flag == :exec)
1305
+ cmd,
1306
+ project: self, no: OPT_BUNDLE[:no][flag], args: flag == :exec || flag == :config)
1290
1307
  op.concat(args) unless pre
1291
1308
  output = false
1292
1309
  invalid = ->(a) { raise_error ArgumentError, "unrecognized args: #{a.join(', ')}", hint: flag }
1293
1310
  case flag
1294
1311
  when :config
1295
- if op.empty?
1296
- op << (val = readline('Enter arguments', force: false))
1297
- output = val.match?(/(?:un)?set/)
1298
- else
1312
+ if pre == 'list'
1313
+ op.clear
1314
+ elsif !op.empty?
1299
1315
  a = op.dup
1300
- b, c, d = op.slice!(0, 3)
1301
- e = op.arg?('global', 'local')
1302
- op << b
1303
- getname = -> { op << (c || readline('Enter name', force: true)) }
1304
- case b
1305
- when 'list'
1306
- nil
1316
+ b, c = op.slice!(0, 2)
1317
+ d = op.arg?('global', 'local')
1318
+ getname = -> { op << (b || readline('Enter name', force: true)) }
1319
+ case pre
1307
1320
  when 'get'
1308
1321
  getname.call
1309
1322
  when 'set'
1310
- if e
1311
- op << c
1312
- c = d
1313
- d = op.shift
1323
+ if d
1324
+ op << b
1325
+ b = c
1326
+ c = op.shift
1314
1327
  end
1315
1328
  getname.call
1316
- op << (d || readline('Enter value', force: true))
1329
+ op << (c || readline('Enter value', force: true))
1317
1330
  output = true
1318
1331
  when 'unset'
1319
- if e
1320
- op << c
1321
- c = d
1332
+ if d
1333
+ op << b
1334
+ b = c
1322
1335
  end
1323
1336
  getname.call
1324
1337
  output = true
1325
1338
  else
1326
- if b
1327
- op << b
1328
- if c
1329
- op.add_quote(c)
1330
- output = true
1331
- end
1339
+ if c && !op.arg?('parseable', 'no-parseable')
1340
+ op.adjoin('set') << b
1341
+ op.add_quote(c)
1342
+ output = true
1343
+ exit 1 unless confirm_basic('Confirm?', op, 'Y')
1344
+ elsif b
1345
+ op.adjoin('get') << b
1346
+ op.unshift(c) if c
1332
1347
  else
1333
1348
  invalid.call(a)
1334
1349
  end
1335
1350
  end
1336
1351
  op.clear
1352
+ else
1353
+ val = readline('Enter arguments', force: false)
1354
+ op << (val.empty? ? 'list' : val)
1355
+ output = val.match?(/^(un)?set/)
1337
1356
  end
1338
1357
  when :plugin
1339
1358
  case plu
@@ -1485,10 +1504,20 @@ module Squared
1485
1504
  def copy?
1486
1505
  return true if @copy.is_a?(Hash) ? copy[:into] : super
1487
1506
  return gemdir? if gemdir
1507
+ return false unless autodetect
1488
1508
 
1509
+ set = lambda do |val, path|
1510
+ base = Pathname.new(path.strip)
1511
+ dir = base + gempath
1512
+ return false unless dir.writable? && base.join(gempath(val, 'specifications')).exist?
1513
+
1514
+ log.warn "using version #{val}".subhint("given #{version}") if version && version != val
1515
+ self.version = val
1516
+ self.gemdir = dir
1517
+ end
1489
1518
  if version
1490
1519
  begin
1491
- case @autodetect
1520
+ case autodetect
1492
1521
  when 'rvm'
1493
1522
  pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
1494
1523
  when 'rbenv'
@@ -1496,36 +1525,23 @@ module Squared
1496
1525
  File.join($1, 'lib/ruby/gems', "#{$2}.0")
1497
1526
  end
1498
1527
  when 'asdf'
1499
- pwd_set { `asdf where ruby` }.yield_self do |val|
1528
+ pwd_set { `asdf where ruby`.chomp }.yield_self do |val|
1500
1529
  val =~ /(\d\.\d)\.[^.]+$/ && File.join(val, 'lib/ruby/gems', "#{$1}.0")
1501
1530
  end
1502
- when 'env'
1503
- ENV['GEM_HOME'] || ENV['GEM_ROOT']
1504
1531
  when /bundler?/
1505
1532
  pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1].split(File::PATH_SEPARATOR).find do |val|
1506
- Dir.exist?(val)
1533
+ Dir.exist?(File.join(val, 'gems'))
1507
1534
  end
1508
- end.tap { |val| self.gemdir = val if val }
1535
+ else
1536
+ ENV['GEM_HOME'] || ENV['GEM_ROOT']
1537
+ end.tap do |val|
1538
+ return true if val && set.call(version, val)
1539
+ end
1509
1540
  rescue StandardError => e
1510
1541
  log.debug e
1511
1542
  end
1512
- return true if gemdir?
1513
- end
1514
- return false unless @autodetect
1515
-
1516
- set = lambda do |val, path|
1517
- base = Pathname.new(path.strip)
1518
- dir = base + gempath
1519
- return false unless dir.writable? && base.join(gempath(val, 'specification')).exist?
1520
-
1521
- log.warn "using version #{val}".subhint("given #{version}") if version && version != val
1522
- self.version = val
1523
- self.gemdir = dir
1524
- end
1525
- if version
1526
- opt = gempwd
1527
- pwd_set(pass: !opt.nil?) do
1528
- out = `#{gem_output(opt, 'list --local -d', gemname)}`
1543
+ pwd_set(pass: !gempwd.nil?) do
1544
+ out = `#{gem_output(gempwd, 'list --local -d', gemname)}`
1529
1545
  next unless out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
1530
1546
 
1531
1547
  split_escape($1)
@@ -1559,7 +1575,7 @@ module Squared
1559
1575
  log.error e
1560
1576
  self.version = nil
1561
1577
  @gemdir = nil
1562
- @autodetect = false
1578
+ self.autodetect = false
1563
1579
  else
1564
1580
  gemdir?
1565
1581
  end
@@ -587,10 +587,12 @@ module Squared
587
587
  elsif exclude.first.is_a?(Symbol)
588
588
  partition(&exclude.first)
589
589
  else
590
+ exclude.map! { |pat| Regexp.new(pat) }
590
591
  partition do |val|
591
- next false if pattern && OptionPartition.pattern?(val)
592
+ val = val.to_s
593
+ next if pattern && OptionPartition.pattern?(val)
592
594
 
593
- exclude.none? { |pat| val.match?(Regexp.new(pat)) }
595
+ exclude.none? { |pat| val.match?(pat) }
594
596
  end
595
597
  end
596
598
  unless temp.empty?
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.8
4
+ version: 0.6.10
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: []