squared 0.8.2 → 0.8.3

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: 53991d0e40acab903d9e2715fcc37a2f69853bcbc25ba610c04c1a7331ac865c
4
- data.tar.gz: fa4913add4c429e7bbceda66f75721af58620b54549591a911bb7b4b4081e913
3
+ metadata.gz: 037121270d4c460552bc1b0c24580e95dc6d70c678ab2d82f3339567ab652c84
4
+ data.tar.gz: 7d7bdbb4164fe03ddfdc64ae0d5b0640cd6d688fa8660f0193399d816f418de1
5
5
  SHA512:
6
- metadata.gz: 5a81aadedff0d5e4288879f31f80aa0cc3c1d2997958278e0724067da6faa0452223660829870349334d35f37d6936b6ea83313c76981f67b5d095a3f8f85202
7
- data.tar.gz: 84a885286b2abad87cd7b381e1fb2b71c0f7619b0486b6647b5b766eccae2fc8bb9ae845853f42115ff019e10b9d15e225b4f19d480288b9b9d194a4730b2fd3
6
+ metadata.gz: f96c91ee8cc22e2b81159529e6037b72c07047d7b5fe86834f7fbcf4e89ad884141002d2e47bc121f04c1041a3eb8abc10514f79509e4ee83a1d561dad6d5155
7
+ data.tar.gz: 5984989ccad4013691a522196eaee92d047a1a2ab0636731952143fde8ac20b96ae9789fcde670586f46c474217443840bee1e22b54b8b49991cd3032717ef0d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.3] - 2026-08-18
4
+
5
+ ### Added
6
+
7
+ - Docker command options were updated to 29.6.
8
+ - Git command clone was implemented.
9
+ - Docker command [container|compose] action logs was implemented.
10
+ - Git command [refs|files] action remote is interactive.
11
+ - Git command push was implemented.
12
+ - Git command commit action head was implemented.
13
+
14
+ ### Changed
15
+
16
+ - Python virtual environment will use a detected package manager.
17
+ - Git command argument ref was renamed commit with interactive.
18
+
19
+ ### Fixed
20
+
21
+ - Common prompt method choice did not grep list items.
22
+
23
+ ## [0.7.10] - 2026-08-06
24
+
25
+ ### Fixed
26
+
27
+ - See `0.6.17`.
28
+
29
+ ## [0.6.17]
30
+
31
+ ### Added
32
+
33
+ - NPM command install can bypass engines with ENV and engine-strict=false.
34
+
35
+ ### Fixed
36
+
37
+ - Ruby command gem action push interactive file selector did nothing.
38
+ - Git choice prompt did not permit optional empty values.
39
+
40
+ ## [0.4.40]
41
+
42
+ ### Changed
43
+
44
+ - Series method exclude? was made compatible with v0.8 signature.
45
+
3
46
  ## [0.8.2] - 2026-07-05
4
47
 
5
48
  ### Added
@@ -1985,9 +2028,11 @@
1985
2028
 
1986
2029
  - Changelog was created.
1987
2030
 
2031
+ [0.8.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.3
1988
2032
  [0.8.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.2
1989
2033
  [0.8.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.1
1990
2034
  [0.8.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.0
2035
+ [0.7.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.10
1991
2036
  [0.7.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.9
1992
2037
  [0.7.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.8
1993
2038
  [0.7.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.7
@@ -1998,6 +2043,7 @@
1998
2043
  [0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
1999
2044
  [0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
2000
2045
  [0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
2046
+ [0.6.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.17
2001
2047
  [0.6.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.16
2002
2048
  [0.6.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.15
2003
2049
  [0.6.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.14
@@ -2041,6 +2087,7 @@
2041
2087
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
2042
2088
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
2043
2089
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
2090
+ [0.4.40]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.40
2044
2091
  [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
2045
2092
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
2046
2093
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
data/README.md CHANGED
@@ -548,6 +548,7 @@ Most project classes will inherit from `Git` which enables these tasks:
548
548
  | log | log | view between contain |
549
549
  | merge | merge | commit no-commit send |
550
550
  | pull | pull | origin remote all |
551
+ | push | push | origin remote commit all tags |
551
552
  | range-diff | range-diff | view between contain |
552
553
  | rebase | rebase | branch onto send |
553
554
  | remote | remote | add select |
@@ -702,7 +703,7 @@ GIT_COUNT=50 # list display limit
702
703
  | clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s BARE=1 LOCAL=0,1 |
703
704
  | | | SINGLE_BRANCH=0,1 NO_CHECKOUT=1 NO_TAGS=1 QUIET=1 |
704
705
  | commit | amend | F|FORCE |
705
- | commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
706
+ | commit | * | UPSTREAM|ORIGIN=s DRY_RUN EDIT=0 M|MESSAGE=s |
706
707
  | diff | head branch | INDEX=n |
707
708
  | diff | * | PATHSPEC=s |
708
709
  | fetch | -remote | ALL |
@@ -714,6 +715,7 @@ GIT_COUNT=50 # list display limit
714
715
  | pull | -remote | REBASE=0,1 ALL |
715
716
  | pull | all | FF_ONLY=0 |
716
717
  | pull | * | AUTOSTASH F|FORCE RECURSE_SUBMODULES=0,1,s |
718
+ | push | all,tags | ORIGIN=s |
717
719
  | range-diff | * | PATHSPEC=s |
718
720
  | rebase | branch | HEAD=s |
719
721
  | rebase | onto | INTERACTIVE I HEAD=s |
@@ -737,7 +739,7 @@ GIT_COUNT=50 # list display limit
737
739
 
738
740
  ### Docker
739
741
 
740
- * Version: [29.1](https://docs.docker.com/engine/release-notes/29)
742
+ * Version: [29.6](https://docs.docker.com/engine/release-notes/29)
741
743
 
742
744
  ```sh
743
745
  DOCKER_OPTIONS=q,no-cache # all
@@ -91,6 +91,13 @@ module Squared
91
91
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
92
92
  end
93
93
 
94
+ def __arg__(key, name = nil, &blk)
95
+ ret = ARG[key.to_sym]
96
+ return ret unless name && ret.is_a?(::Hash)
97
+
98
+ ret[name = name.downcase] || (block_given? ? ret.fetch(name.to_sym, &blk) : ret[name.to_sym])
99
+ end
100
+
94
101
  def __freeze__
95
102
  PATH.freeze
96
103
  ARG.freeze
@@ -55,19 +55,23 @@ module Squared
55
55
  end
56
56
 
57
57
  def choice(msg, list = nil, min: 1, max: 1, multiple: false, index: false, grep: nil, border: nil, auto: true,
58
- force: true, attempts: 3, timeout: 0)
58
+ force: true, attempts: 3, timeout: 0, empty: nil)
59
59
  require 'timeout'
60
60
  if list
61
61
  grep &&= Array(grep).map { |val| Regexp.new(val) }
62
62
  items = list.each_with_object([]) do |val, out|
63
- next if grep&.none? { |pat| pat.match?(line) }
63
+ next if grep&.none? { |pat| pat.match?(val) }
64
64
 
65
65
  out << val.to_s.chomp
66
66
  puts '%2d. %s' % [out.size, val]
67
67
  end
68
68
  max = items.size
69
- raise ArgumentError, 'empty selection list' if max == 0
69
+ if max == 0
70
+ raise ArgumentError, 'empty selection list' unless empty
70
71
 
72
+ puts empty
73
+ exit 1
74
+ end
71
75
  min = grep ? 1 : [min, max].min
72
76
  if auto
73
77
  auto.times { puts } if auto.is_a?(::Numeric)
@@ -81,7 +85,7 @@ module Squared
81
85
  end}] "
82
86
  end
83
87
  end
84
- between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
88
+ between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max <= min ? Float::INFINITY : max) }
85
89
  Timeout.timeout(timeout) do
86
90
  while (ch = Prompt.reline.readline(msg))
87
91
  ch.strip!
@@ -324,8 +324,7 @@ module Squared
324
324
  'yaml'
325
325
  when 'js'
326
326
  'json'
327
- when ''
328
- nil
327
+ when '' then nil
329
328
  else
330
329
  ret
331
330
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.8.2'
4
+ VERSION = '0.8.3'
5
5
  end
@@ -1175,6 +1175,18 @@ module Squared
1175
1175
  ret
1176
1176
  end
1177
1177
 
1178
+ def emptypath(val, create: true)
1179
+ ret = basepath(val).realdirpath
1180
+ if ret.exist?
1181
+ raise Errno::EEXIST, message(val, hint: 'not empty') unless ret.directory? && ret.empty?
1182
+
1183
+ ret.rmdir unless create
1184
+ elsif create
1185
+ ret.mkpath
1186
+ end
1187
+ ret
1188
+ end
1189
+
1178
1190
  def localname
1179
1191
  workspace.task_localname(name)
1180
1192
  end
@@ -1556,7 +1568,7 @@ module Squared
1556
1568
  def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
1557
1569
  name = "#{key}_#{envname_get}"
1558
1570
  ret = if suffix
1559
- ENV.fetch("#{name}_#{suffix}", '')
1571
+ ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1560
1572
  elsif strict
1561
1573
  ENV[name].to_s
1562
1574
  else
@@ -1908,7 +1920,7 @@ module Squared
1908
1920
  end
1909
1921
 
1910
1922
  def append_hash(data, target: @session || [], build: false)
1911
- if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1923
+ if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1912
1924
  if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
1913
1925
  data = data.merge(extra)
1914
1926
  else
@@ -2092,8 +2104,8 @@ module Squared
2092
2104
  args
2093
2105
  end
2094
2106
 
2095
- def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
2096
- return true if prefix ? option('y', prefix: prefix) : target && option('y', target: target)
2107
+ def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
2108
+ return true if option('y', prefix: prefix)
2097
2109
 
2098
2110
  confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", accept, **kwargs)
2099
2111
  end
@@ -2715,6 +2727,10 @@ module Squared
2715
2727
  end
2716
2728
  end
2717
2729
 
2730
+ def dryrun?(target: @session, prefix: target&.first, **)
2731
+ Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2732
+ end
2733
+
2718
2734
  def pwd?
2719
2735
  path == Pathname.pwd
2720
2736
  end
@@ -13,11 +13,11 @@ module Squared
13
13
  buildx: {
14
14
  common: %w[builder=b D|debug],
15
15
  build: %w[add-host=q annotation=q attest=q build-arg=qq build-context=qq cache-from=q cache-to=q
16
- cgroup-parent=b iidfile=p label=q network=b no-cache-filter=b o|output=q platform=q
17
- q|quiet secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
18
- bake: %w[print list=q set=q].freeze,
19
- shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p progress=b provenance=q
20
- sbom=q].freeze
16
+ cgroup-parent=b iidfile=p label=q network=b no-cache-filter=b o|output=q platform=q q|quiet
17
+ resource=q secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
18
+ bake: %w[print list=q set=qq var=qq].freeze,
19
+ shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p policy=q progress=b
20
+ provenance=q sbom=q].freeze
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
@@ -34,7 +34,8 @@ module Squared
34
34
  quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
35
35
  exit-code-from=b no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze,
36
36
  down: %w[remove-orphans v|volumes rmi=b t|timeout=i].freeze,
37
- publish: %w[app resolve-image-digests with-env y|yes oci-version=b].freeze
37
+ publish: %w[app resolve-image-digests with-env y|yes oci-version=b].freeze,
38
+ logs: %w[dry-run f|follow no-color no-log-prefix t|timestamps index=i since=q n|tail=b until=q].freeze
38
39
  }.freeze,
39
40
  container: {
40
41
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
@@ -55,7 +56,8 @@ module Squared
55
56
  restart=q].freeze,
56
57
  exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p u|user=e
57
58
  w|workdir=q].freeze,
58
- commit: %w[no-pause a|author=q c|change=q m|message=q pause=b?].freeze,
59
+ commit: %w[no-pause a|author=q c|change=q m|message=q].freeze,
60
+ logs: %w[details f|follow t|timestamps since=q n|tail=b until=q].freeze,
59
61
  inspect: %w[s|size f|format=q].freeze,
60
62
  start: %w[a|attach i|interactive detach-keys=q].freeze,
61
63
  stop: %w[s|signal=b t|timeout=i].freeze,
@@ -115,10 +117,10 @@ module Squared
115
117
 
116
118
  subtasks({
117
119
  'build' => %i[tag context].freeze,
118
- 'compose' => %i[build create publish run exec up down service].freeze,
120
+ 'compose' => %i[build create publish run exec up down logs service].freeze,
119
121
  'bake' => %i[build compose check].freeze,
120
122
  'image' => %i[ls rm pull push tag save inspect history].freeze,
121
- 'container' => %i[attach commit create diff exec inspect kill pause restart rm run start stats stop top
123
+ 'container' => %i[attach commit create diff exec logs top inspect kill pause restart rm run start stats stop
122
124
  unpause update].freeze,
123
125
  'network' => %i[connect disconnect create].freeze,
124
126
  'ls' => nil
@@ -299,7 +301,11 @@ module Squared
299
301
  end
300
302
  end
301
303
  else
302
- format_desc action, flag, "opts*,id/name#{flag == :update || flag == :inspect ? '+' : '*'}"
304
+ format_desc action, flag, "opts*,id/name#{case flag
305
+ when :stats then '*'
306
+ when :logs, :diff, :attach, :top then nil
307
+ else '+'
308
+ end}"
303
309
  task flag do |_, args|
304
310
  container flag, args.to_a
305
311
  end
@@ -411,11 +417,9 @@ module Squared
411
417
  when String
412
418
  ret << quote_option('secret', @secrets, double: true)
413
419
  when Hash
414
- append = lambda do |key|
420
+ %i[file env].each do |key|
415
421
  ret.merge(Array(@secrets[key]).map { |arg| quote_option('secret', "type=#{key},#{arg}", double: true) })
416
422
  end
417
- append.call(:file)
418
- append.call(:env)
419
423
  else
420
424
  ret.merge(Array(@secrets).map { |arg| quote_option('secret', arg) })
421
425
  end
@@ -443,7 +447,7 @@ module Squared
443
447
  .parse(data[flag == :bake ? :bake : :build] + (shared || data[:shared]))
444
448
  case flag
445
449
  when :build, :context
446
- append_tag(tag || option('tag', ignore: false) || self.tag)
450
+ append_tag tag || option('tag', ignore: false) || self.tag
447
451
  if shared
448
452
  op.add_quote(context, preserve: false)
449
453
  else
@@ -460,7 +464,7 @@ module Squared
460
464
  context = basepath context
461
465
  op.each { |name| op.add_option('set', "#{name}.context=#{context}", escape: false) }
462
466
  end
463
- op.append(escape: true, strip: /^:/, clear: true)
467
+ op.append(escape: true, strip: ':', clear: true)
464
468
  end
465
469
  end
466
470
  op.clear(pass: false)
@@ -502,7 +506,7 @@ module Squared
502
506
  end
503
507
  if multiple
504
508
  op.concat(service) if service
505
- op.append(delim: true, escape: true, strip: /^:/)
509
+ op.append(delim: true, escape: true, strip: ':')
506
510
  else
507
511
  raise ArgumentError, message('no service was selected', hint: flag) unless service
508
512
 
@@ -570,7 +574,7 @@ module Squared
570
574
  when :update, :inspect
571
575
  raise ArgumentError, message('missing container', hint: flag) if op.empty?
572
576
 
573
- op.append(escape: true, strip: /^:/)
577
+ op.append(escape: true, strip: ':')
574
578
  when :commit
575
579
  latest = op.shift || tagmain
576
580
  cmd << id << latest
@@ -600,7 +604,17 @@ module Squared
600
604
  end
601
605
  return
602
606
  end
603
- op.append(escape: true, strip: /^:/)
607
+ case flag
608
+ when :logs, :diff, :attach, :top
609
+ op.add_first(escape: true, strip: ':')
610
+ if flag == :top
611
+ op.append(delim: true)
612
+ else
613
+ op.clear
614
+ end
615
+ else
616
+ op.append(escape: true, strip: ':')
617
+ end
604
618
  end
605
619
  run(from: from)
606
620
  end
@@ -691,10 +705,10 @@ module Squared
691
705
  raise ArgumentError, message('missing image', hint: flag) if op.empty?
692
706
 
693
707
  if flag == :history
694
- op.add_first(escape: true, strip: /^:/)
708
+ op.add_first(escape: true, strip: ':')
695
709
  .clear
696
710
  else
697
- op.append(escape: true, strip: /^:/)
711
+ op.append(escape: true, strip: ':')
698
712
  end
699
713
  end
700
714
  success?(run(sync: sync, exception: exception, banner: banner, from: from), flag == :tag || flag == :save)