squared 0.6.5 → 0.6.6

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: 42ae11aaf561b6e6d821f7590e37982c408cb4f09aa4946084e4d3ec29c6fdff
4
- data.tar.gz: 3ef75c9101dfd1676c035396055bd5585b33e3be41498dbd19eac2a98ea80a81
3
+ metadata.gz: eef895f1332463b52f24d46188726f55878170e90ba8ed9c7dcf1a1fac3bdd41
4
+ data.tar.gz: d8ac6097a8ec74b0dd266558ad273e8ea23ba5994f5c79602875e6ce75d7367a
5
5
  SHA512:
6
- metadata.gz: cf24602228107b3e1a760749acf96f367cd0877ea6d45a2b0153ea08ba2a3bb014b547986e2406d2aaca4744e005bad2d9994d4a5807a7cc1afe517191aca775
7
- data.tar.gz: 87e429e0eb78518ea637ecd863aab3359fef584b3c87340cc5a4d9f83718e7b89ac7b258a9e7a9f7d7ece3169776a8fb61d6e5f575c7420778510f3a122d84db
6
+ metadata.gz: 8569824e8b5cedbb189666ba9e1b67590887afa004ac43bd5c42cc854cf1a61f51ea5709f16a0c55988cfc7ad5cadab0b4b751ce4864bbb46195f3bc97181248
7
+ data.tar.gz: 7f3c48efd9652ee0ad67f5f35bfba87596e6c13f4bb5fb45ebd68aecfb2947e7f43c0ea7dad1bb04e365d45a001d82651e8b59f976274b07e6dda806d0e3bb4c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.6] - 2025-11-30
4
+
5
+ ### Added
6
+
7
+ - Python application method with stored command options was created.
8
+ - Ruby task depend can install binstubs through ENV.
9
+ - Project application methods can throw exceptions to halt processing.
10
+ - Project application methods can read multiple files from STDIN.
11
+ - Ruby attribute setter gemdir for copy method was created.
12
+
13
+ ### Changed
14
+
15
+ - Project base method semgte? optional argument compares with RUBY_VERSION.
16
+ - Project task branch in a single workspace displays all branches.
17
+ - Ruby application method first argument can be used as a symbol flag.
18
+ - Ruby task copy does not write into protected system directories.
19
+
20
+ ### Fixed
21
+
22
+ - RuboCop did not include config file when default was not found.
23
+ - RuboCop path globs are not expanded except for choice selections.
24
+ - Ruby target application file appeared before the delimiter.
25
+ - JoinSet can keep arguments with a duplicate value.
26
+ - OptionPartition did not quarantine options added from extras.
27
+ - Python method pyprojectfile did not always return nil.
28
+
29
+ ## [0.5.18] - 2025-11-25
30
+
31
+ ### Fixed
32
+
33
+ - See `0.5.18`.
34
+
35
+ ## [0.4.32] - 2025-11-25
36
+
37
+ ### Fixed
38
+
39
+ - Git method commit did not include --dry-run with add command.
40
+ - JoinSet method include? did not always search to start of delimiter.
41
+ - Config viewer did not check for a readable package registry document.
42
+ - Powershell executable did not check for alternate path location.
43
+
44
+ ## [0.5.17] - 2025-11-22
45
+
46
+ ### Fixed
47
+
48
+ - See `0.4.31`.
49
+
50
+ ## [0.4.31] - 2025-11-22
51
+
52
+ ### Changed
53
+
54
+ - Ruby command flag is given precedence to a program file.
55
+
56
+ ### Fixed
57
+
58
+ - Project change directory context did not always restore when raised.
59
+ - Ruby file method attributes did not always return nil.
60
+ - JoinSet with a delimiter did not report correct size.
61
+
3
62
  ## [0.6.5] - 2025-11-18
4
63
 
5
64
  ### Added
@@ -1434,12 +1493,15 @@
1434
1493
 
1435
1494
  - Changelog was created.
1436
1495
 
1496
+ [0.6.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.6
1437
1497
  [0.6.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.5
1438
1498
  [0.6.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.4
1439
1499
  [0.6.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.3
1440
1500
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1441
1501
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1442
1502
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1503
+ [0.5.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.18
1504
+ [0.5.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.17
1443
1505
  [0.5.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.16
1444
1506
  [0.5.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.15
1445
1507
  [0.5.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.14
@@ -1457,6 +1519,8 @@
1457
1519
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1458
1520
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1459
1521
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1522
+ [0.4.32]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.32
1523
+ [0.4.31]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.31
1460
1524
  [0.4.30]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.30
1461
1525
  [0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
1462
1526
  [0.4.28]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.28
data/README.md CHANGED
@@ -24,23 +24,9 @@ The range chart indicates the latest Ruby tested against at the time of release.
24
24
  gem install squared
25
25
  ```
26
26
 
27
- ### Optional
28
-
29
- * [Repo](https://source.android.com/docs/setup/reference/repo)
30
- * https://github.com/anpham6/squared-repo
31
- * Python 3.6
32
- * Not compatible with Windows
33
-
34
- ```sh
35
- mkdir -p ~/.bin
36
- PATH="${HOME}/.bin:${PATH}"
37
- curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
38
- chmod a+rx ~/.bin/repo
39
- ```
40
-
41
27
  ## Example - Rakefile
42
28
 
43
- Projects from any accessible folder can be added relative to the parent directory (e.g. *REPO_ROOT*) or absolutely. The same Rakefile can also manage other similarly cloned `Repo` repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
29
+ Projects from any accessible folder can be added relative to the parent directory or absolutely. Missing projects will simply be excluded from the task runner.
44
30
 
45
31
  ```ruby
46
32
  require "squared"
@@ -56,14 +42,6 @@ require "squared/app" # All workspace related mod
56
42
 
57
43
  # NODE_ENV = production
58
44
 
59
- # REPO_ROOT = /workspaces |
60
- # REPO_HOME = /workspaces/squared | Dir.pwd
61
- # rake = /workspaces/squared/Rakefile | main?
62
- # OR
63
- # REPO_ROOT = /workspaces | Dir.pwd
64
- # rake = /workspaces/Rakefile |
65
- # REPO_HOME = /workspaces/squared | main: "squared"
66
-
67
45
  # pathname = /workspaces/pathname
68
46
  # optparse = /workspaces/optparse
69
47
  # log = /workspaces/logger
@@ -82,7 +60,6 @@ Workspace::Application.load_ref('lib/squared/workspace/project', gem: 'squared')
82
60
  Workspace::Application
83
61
  .new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
84
62
  .banner("group", "project", styles: ["yellow", "black"], border: "bold") # name | project | path | ref | group? | parent? | version?
85
- .repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "prod"], install: "#{ENV["HOME"]}/.bin", ref: :node) # Repo (optional)
86
63
  .run("rake install", ref: :ruby)
87
64
  .depend(false, group: "default")
88
65
  .clean("rake clean", group: "default")
@@ -92,7 +69,9 @@ Workspace::Application
92
69
  "CFLAGS" => "-fPIC -O1"
93
70
  })
94
71
  .add("optparse", doc: "rake rdoc", gemspec: "optparse.gemspec", group: "default") # Uses bundler/gem_tasks (without C extensions)
95
- .add("logger", copy: { from: "lib", glob: "**/*.rb", into: "~/.rvm/gems/ruby-3.4.0/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true | "rvm" | "rbenv" | "asdf" | "bundler"
72
+ .add("logger", copy: { from: "lib", glob: "**/*.rb", into: "/home/user/.local/gem/ruby/3.4.0/gems/logger-1.7.0" }, clean: ["tmp/"]) do # autodetect: true | "rvm" | "rbenv" | "asdf" | "bundler"
73
+ self.gemdir = "/home/user/.local/gem/ruby/3.4.0/gems/logger-1.7.0" # Default for "into"
74
+ end
96
75
  .add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
97
76
  .add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
98
77
  .add("pi-r2", "pir2", copy: { from: :npm, also: %i[squared express], files: ["LICENSE", ["README.md.ruby", "README.md"]] }) # Uses dist files from NPM package spec
@@ -780,7 +759,37 @@ Workspace::Application
780
759
 
781
760
  ### Repo
782
761
 
783
- These global options also can target the application main suffix `${NAME}`. (e.g. REPO_ROOT_SQUARED)
762
+ * [Repo](https://source.android.com/docs/setup/reference/repo)
763
+ * https://github.com/anpham6/squared-repo
764
+ * Python 3.6
765
+ * Not compatible with Windows
766
+
767
+ ```sh
768
+ mkdir -p ~/.bin
769
+ PATH="${HOME}/.bin:${PATH}"
770
+ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
771
+ chmod a+rx ~/.bin/repo
772
+ ```
773
+
774
+ ```ruby
775
+ # REPO_ROOT = /workspaces |
776
+ # REPO_HOME = /workspaces/squared | Dir.pwd
777
+ # rake = /workspaces/squared/Rakefile | main?
778
+ #
779
+ # OR
780
+ #
781
+ # REPO_ROOT = /workspaces | Dir.pwd
782
+ # rake = /workspaces/Rakefile |
783
+ # REPO_HOME = /workspaces/squared | main: "squared"
784
+
785
+ Workspace::Application
786
+ .new(main: "squared")
787
+ .repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "prod"], install: "#{ENV["HOME"]}/.bin", ref: :node)
788
+ .add("squared", script: ["build:stage1", "build:stage2"])
789
+ .build
790
+ ```
791
+
792
+ These global options also can target the application main suffix `${NAME}`. (e.g. *REPO_ROOT_SQUARED*)
784
793
 
785
794
  ```sh
786
795
  REPO_ROOT # parent dir
@@ -801,6 +810,51 @@ REPO_Y # 0,1
801
810
  REPO_TIMEOUT # confirm dialog (seconds)
802
811
  ```
803
812
 
813
+ Other similarly cloned `Repo` repositories can be managed remotely by setting the `REPO_ROOT` environment variable to the location.
814
+
815
+ ### Project
816
+
817
+ Features can be enabled through ENV when calling global tasks such as through *CI/CD* automation (e.g. Repo).
818
+
819
+ #### Ruby
820
+
821
+ * Prefix: BUNDLE/GEM/RBS
822
+
823
+ | Command | Flag | ENV |
824
+ | :--------- | :-------- | :---------------------------------------------------------------- |
825
+ | depend | - | BINSTUBS=s JOBS=n |
826
+ | outdated | - | U|UPDATE=major|minor|patch DRY_RUN |
827
+ | gem | outdated | DOCUMENT=0,1 USER_INSTALL=0,1 |
828
+ | rbs | prototype | Y=0,1 |
829
+
830
+ #### Node
831
+
832
+ * Prefix: NPM/PNPM/YARN
833
+
834
+ | Command | Flag | ENV |
835
+ | :------------- | :------------- | :------------------------------------------------------- |
836
+ | depend | - | FORCE CI IGNORE_SCRIPTS |
837
+ | outdated | - | U|UPDATE=major|minor|patch DIFF DRY_RUN |
838
+ | publish | - | OTP=s TAG=s ACCESS=0,1,s DRY_RUN |
839
+ | depend package | * | PACAKGE_LOCK|LOCKFILE=0 NO_LOCKFILE=1 Y |
840
+ | npm pnpm | depend package | CPU=s OS=s LIBC=s |
841
+ | npm | package | SAVE IGNORE_SCRIPTS STRICT_PEER_DEPS |
842
+ | pnpm | depend | ALLOW_BUILD=s PUBLIC_HOIST_PATTERN=s |
843
+ | yarn | depend package | IGNORE_ENGINES=0 |
844
+
845
+ #### Python
846
+
847
+ * Prefix: PIP/POETRY
848
+
849
+ | Command | Flag | ENV |
850
+ | :--------- | :-------- | :---------------------------------------------------------------- |
851
+ | global | * | CACHE_DIR=0,s PROXY=s PYTHON=s COLOR=0 |
852
+ | depend | - | E|EDITABLE=0,s BUILD_ISOLATION=0 |
853
+ | outdated | - | U|UPDATE=major|minor|patch NOT_REQUIRED=0 L|LOCAL DRY_RUN |
854
+ | venv | exec | INTERACTIVE=0 |
855
+ | poetry | * | PROJECT=s |
856
+ | poetry | depend | NO_ROOT |
857
+
804
858
  ## LICENSE
805
859
 
806
860
  BSD 3-Clause
@@ -219,6 +219,10 @@ module Squared
219
219
  end
220
220
  end
221
221
 
222
+ def log_warn(*args, **kwargs)
223
+ log_message(Logger::WARN, *args, **kwargs)
224
+ end
225
+
222
226
  def log_console(*args, pipe: 1)
223
227
  return if args.first == false && args.size == 1
224
228
 
@@ -266,7 +270,7 @@ module Squared
266
270
  out = []
267
271
  draw = lambda do |a, b|
268
272
  ret = a + (b1 * (n + 2)) + b
269
- next ret unless border
273
+ return ret unless border
270
274
 
271
275
  sub_style ret, border
272
276
  end
@@ -83,7 +83,11 @@ module Squared
83
83
  end
84
84
  sep = unless flag.empty?
85
85
  if flag[0] == '-'
86
- flag[1] == '-' ? sep : ' '
86
+ if flag[1] == '-'
87
+ sep
88
+ else
89
+ merge ? '' : ' '
90
+ end
87
91
  elsif flag.size == 1
88
92
  pre = '-'
89
93
  merge ? '' : ' '
@@ -146,7 +150,8 @@ module Squared
146
150
  end
147
151
 
148
152
  def shell_bin(name, env: true)
149
- key = name.upcase
153
+ key = name.to_s.upcase
154
+ key = File.basename(key, '.*') if Rake::Win32.windows?
150
155
  shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
151
156
  option: false, force: false, double: true)
152
157
  end
@@ -22,8 +22,8 @@ module Squared
22
22
  nil
23
23
  end
24
24
 
25
- def link(project, main = project.dependfile.basename, name = nil, **kwargs, &blk)
26
- return unless project.enabled?
25
+ def link(project, main = project.dependfile&.basename, name = nil, **kwargs, &blk)
26
+ return unless project.enabled? && main
27
27
 
28
28
  ret = new(main, name, project: project, **kwargs)
29
29
  ret.instance_eval(&blk) if block_given?
@@ -87,7 +87,7 @@ module Squared
87
87
  @required = true
88
88
  project ? [project, 'missing'] : %w[name missing]
89
89
  end
90
- warn log_message(Logger::WARN, msg, subject: self.class, hint: hint)
90
+ warn log_warn(msg, subject: self.class, hint: hint)
91
91
  end
92
92
 
93
93
  def build
@@ -159,7 +159,7 @@ module Squared
159
159
  end
160
160
 
161
161
  def also(path, type = nil, name: nil, **kwargs)
162
- return self if @mime.frozen? || !(file = basepath(path)).exist?
162
+ return self unless (file = basepath(path)).exist? && !@mime.frozen?
163
163
 
164
164
  ext = mimetype file
165
165
  type ||= ext
@@ -242,7 +242,7 @@ module Squared
242
242
  opt_style(theme[:key], /\A((?~ : ))( : (?!undefined).+)\z/m),
243
243
  opt_style(theme[:number], /\A((?~: ): )(-?[\d.]+)(\s*)\z/m, 2),
244
244
  opt_style(theme[:string], /\A((?~: ): ")(.+)("\s*)\z/m, 2),
245
- opt_style(theme[:hash], /\A((?~: ): \{)(.+)(}\s*)\z/m, 2),
245
+ opt_style(theme[:hash], /\A((?~: ): \{)(.+)(\}\s*)\z/m, 2),
246
246
  opt_style(theme[:array], /\A((?~: ): \[)(.+)(\]\s*)\z/m, 2),
247
247
  opt_style(theme[:boolean], /\A((?~: ): )(true|false)(\s*)\z/m, 2),
248
248
  opt_style(theme[:value], /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, 2)
@@ -287,7 +287,7 @@ module Squared
287
287
  if stdin?
288
288
  puts out.map!(&:last).join("\n")
289
289
  else
290
- out.map! { |item| '%-*s : %s' % [pad, item[0], item[1]] }
290
+ out.map! { |a, b| '%-*s : %s' % [pad, a, b] }
291
291
  end
292
292
  end
293
293
 
@@ -316,7 +316,9 @@ module Squared
316
316
  end
317
317
 
318
318
  def warning?
319
- project ? project.workspace.warning : true
319
+ return true unless project
320
+
321
+ project.workspace.warning
320
322
  end
321
323
 
322
324
  def stdin?
@@ -341,7 +343,9 @@ module Squared
341
343
  end
342
344
 
343
345
  def basepath(*args)
344
- project ? project.basepath(*args) : Pathname.pwd.join(*args)
346
+ return Pathname.pwd.join(*args) unless project
347
+
348
+ project.basepath(*args)
345
349
  end
346
350
  end
347
351
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.5'
4
+ VERSION = '0.6.6'
5
5
  end
@@ -191,15 +191,11 @@ module Squared
191
191
  end
192
192
  series.populate(proj, **kwargs)
193
193
  end
194
-
195
194
  Application.kind_project.each { |obj| obj.populate(self, **kwargs) }
196
195
  @extensions.uniq.each { |ext| __send__(ext, **kwargs) }
197
-
198
196
  series.build(**kwargs)
199
197
  __build__(**kwargs)
200
-
201
198
  yield self if block_given?
202
-
203
199
  __chain__(**kwargs)
204
200
  @closed = true
205
201
  self
@@ -240,18 +236,16 @@ module Squared
240
236
 
241
237
  def chain(task, *action, project: nil, step: 0, with: nil, before: nil, after: nil, sync: false,
242
238
  group: @group, ref: @ref)
243
- keys = if project
244
- action.map! { |val| task_join(project.name, val) }
245
- nil
246
- elsif (target = group || ref)
247
- action.map! { |val| task_name(task_join(val, target)) }
248
- nil
249
- else
250
- action.map! { |val| task_name(val) }
251
- @project.keys unless prefix
252
- end
239
+ if project
240
+ action.map! { |val| task_join(project.name, val) }
241
+ elsif (target = group || ref)
242
+ action.map! { |val| task_name(task_join(val, target)) }
243
+ else
244
+ action.map! { |val| task_name(val) }
245
+ keys = @project.keys unless prefix
246
+ end
253
247
  ns = lambda do |val|
254
- next if (ret = as_a(val, :to_s, flat: true)).empty?
248
+ return if (ret = as_a(val, :to_s, flat: true)).empty?
255
249
 
256
250
  ret.map! do |arg|
257
251
  if arg.include?(':') || (keys && !keys.include?(arg))
@@ -433,7 +427,7 @@ module Squared
433
427
  if key.start_with?(/(\\A|\^)/) || key.match?(/(\\z|\$)\z/)
434
428
  @describe[:replace] << [Regexp.new(key), val]
435
429
  else
436
- @describe[val.is_a?(Regexp) ? :pattern : :alias][key.to_s] = val
430
+ @describe[val.is_a?(Regexp) ? :pattern : :alias][key] = val
437
431
  end
438
432
  end
439
433
  self
@@ -452,7 +446,7 @@ module Squared
452
446
  if ret.empty? && (path || name)
453
447
  path &&= rootpath path
454
448
  name &&= name.to_s
455
- if (proj = find { |item| (path && item.path == path) || (name && item.name == name) })
449
+ if (proj = find { |item| item.path == path || item.name == name })
456
450
  ret << proj
457
451
  end
458
452
  end
@@ -592,9 +586,9 @@ module Squared
592
586
 
593
587
  def script_find(*args)
594
588
  args.reverse_each do |val|
595
- next unless val && (ret = val.is_a?(Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
596
-
597
- return ret
589
+ if val && (ret = val.is_a?(Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
590
+ return ret
591
+ end
598
592
  end
599
593
  @script[:ref!][:''] ||= scriptobj
600
594
  end
@@ -429,7 +429,7 @@ module Squared
429
429
  .sort { |a, b| b <=> a }
430
430
  .push('latest', 'system'),
431
431
  accept: [accept_y('Confirm?')],
432
- values: 'Options', force: true)
432
+ values: 'Options')
433
433
  OptionPartition.strip(opts)
434
434
  end
435
435
  asdf(flag, args, version: version)
@@ -1158,7 +1158,7 @@ module Squared
1158
1158
  path.parent.ascend.each do |dir|
1159
1159
  target = dir.join(*args)
1160
1160
  return target if target.exist?
1161
- break if (ascend && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1161
+ break if (ascend.is_a?(String) && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1162
1162
  end
1163
1163
  ret
1164
1164
  end
@@ -1249,7 +1249,7 @@ module Squared
1249
1249
  single: false, last: false, context: nil)
1250
1250
  tag = ->(proj) { "#{proj.name}#{"@#{proj.version}" if SEM_VER.match?(proj.version)}" }
1251
1251
  uniq = lambda do |name|
1252
- next [] unless (ret = data[name])
1252
+ return [] unless (ret = data[name])
1253
1253
 
1254
1254
  ret.dup.each do |proj|
1255
1255
  next if proj.name == name
@@ -1528,7 +1528,9 @@ module Squared
1528
1528
  end
1529
1529
 
1530
1530
  def print_error(*args, loglevel: Logger::WARN, **kwargs)
1531
- warn log_message(loglevel, *args, **kwargs) if warning?
1531
+ return unless warning?
1532
+
1533
+ warn log_message(loglevel, *args, **kwargs)
1532
1534
  end
1533
1535
 
1534
1536
  def print_run(cmd, banner = true, verbose: nil, **)
@@ -1696,8 +1698,8 @@ module Squared
1696
1698
  msg.subhint(obj.is_a?(Numeric) ? "#{obj} #{title}" : message(title, obj.to_s))
1697
1699
  end
1698
1700
 
1699
- def append_repeat(flag, opts, target: @session)
1700
- opts.each { |val| target << shell_option(flag, val) }
1701
+ def append_repeat(flag, opts, target: @session, **kwargs)
1702
+ opts.each { |val| target << shell_option(flag, val, **kwargs) }
1701
1703
  end
1702
1704
 
1703
1705
  def append_hash(data, target: @session || [], build: false)
@@ -1722,6 +1724,8 @@ module Squared
1722
1724
  target << basic_option(key, val)
1723
1725
  when FalseClass
1724
1726
  target << shell_option(key).sub(/^--(?!no-)/, '--no-')
1727
+ when Pathname
1728
+ target << shell_option(key, val, escape: false)
1725
1729
  else
1726
1730
  target << shell_option(key, (val if val.is_a?(String)))
1727
1731
  end
@@ -1774,20 +1778,18 @@ module Squared
1774
1778
  return if list.empty?
1775
1779
 
1776
1780
  kwargs[:ignore] = false if no && !kwargs.key?(:ignore)
1777
- [].tap do |ret|
1778
- list.flatten.each do |flag|
1779
- next unless (val = option(flag, target: target, **kwargs))
1781
+ ret = []
1782
+ list.flatten.each do |flag|
1783
+ next unless (val = option(flag, target: target, **kwargs))
1780
1784
 
1781
- if no && val == '0'
1782
- flag = "no-#{flag}"
1783
- val = nil
1784
- end
1785
- ret << shell_option(flag, (val if equals), escape: escape, quote: quote, force: force)
1785
+ if no && val == '0'
1786
+ flag = "no-#{flag}"
1787
+ val = nil
1786
1788
  end
1787
- next if ret.empty?
1788
-
1789
- merge_list target, ret
1789
+ ret << shell_option(flag, (val if equals), escape: escape, quote: quote, force: force)
1790
1790
  end
1791
+ merge_list target, ret unless ret.empty?
1792
+ ret
1791
1793
  end
1792
1794
 
1793
1795
  def append_nocolor(target: @session)
@@ -2003,10 +2005,15 @@ module Squared
2003
2005
  nil
2004
2006
  end
2005
2007
 
2006
- def command(*args)
2007
- return args.join(' && ') unless workspace.powershell?
2008
-
2009
- "powershell.exe -Command #{shell_quote("& {#{args.join(' ; ')}}", option: false, double: true)}"
2008
+ def command(*args, verbose: true)
2009
+ out = unless verbose
2010
+ [">#{File::NULL}", '2>&1'].tap { |a| a.reverse if File::NULL == 'NUL' }.unshift('').join(' ')
2011
+ end
2012
+ if workspace.powershell?
2013
+ "#{shell_bin('powershell.exe')} -Command \"& {#{args.join(' ; ')}}\"#{out}"
2014
+ else
2015
+ args.map! { |val| "#{val}#{out}" }.join(' && ')
2016
+ end
2010
2017
  end
2011
2018
 
2012
2019
  def relativepath(*list, all: false)
@@ -2117,7 +2124,11 @@ module Squared
2117
2124
  end
2118
2125
  end
2119
2126
 
2120
- def semgte?(val, other)
2127
+ def semgte?(val, other = nil)
2128
+ unless other
2129
+ other = val
2130
+ val = RUBY_VERSION
2131
+ end
2121
2132
  semcmp(val, other) != 1
2122
2133
  end
2123
2134
 
@@ -2210,13 +2221,15 @@ module Squared
2210
2221
  end
2211
2222
 
2212
2223
  def pwd_set(pass: false, exception: self.exception, dryrun: false, from: nil)
2213
- pwd = Dir.pwd
2214
- return yield if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
2224
+ return yield if (path.to_s == Dir.pwd || pass == true) && (workspace.mri? || !workspace.windows?)
2215
2225
 
2216
- Dir.chdir path
2217
- yield.tap { Dir.chdir pwd }
2226
+ pwd = Dir.pwd
2227
+ Dir.chdir(path)
2228
+ yield
2218
2229
  rescue StandardError => e
2219
2230
  on_error(e, from, exception: exception, dryrun: dryrun)
2231
+ ensure
2232
+ Dir.chdir(pwd) if pwd
2220
2233
  end
2221
2234
 
2222
2235
  def run_set(cmd, val = nil, opts: nil, global: false, **)