squared 0.9.0.pre1 → 0.9.0.pre2

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: ebde7859df22cda9eadd92f6bf88141ba9095a7528a8bba9e469333f1bb14370
4
- data.tar.gz: af5a6e759a021e46d76f4043dcea544b1a7e25dacaddad8389824782fbd1fe78
3
+ metadata.gz: c463103c9731435a61c03a50774d321728675919d1299f92179ee3283c43c570
4
+ data.tar.gz: 608c26522a45d3a91dad5d3c8f094d9da571f8010a16bccc2bb88dc1a92bd90e
5
5
  SHA512:
6
- metadata.gz: 3a00a2d227203bd36460e5a3242de692e7ae2822c1f2812a1a2ec271c4f5d8ffe32af050522e3e20e451920f57d8f5d7363933f7c5abdfb5cbe27e5989e7d41c
7
- data.tar.gz: 29ef41a9d546d00b4701bc763362a61426312b530b8d5378e60f309cd5469960cab206f969da791936f4da68f9d25772bbfa44dd759c90a5a500b8c504defb44
6
+ metadata.gz: e352c390e9299f58b66066f3bdf28ad24d60496b00155eaf8d1dc26b64311f7fef2203bb861c17a021fecc16f2f09849a40d563179a1591eec8db25f502164d3
7
+ data.tar.gz: '0598d79fac00ed9a272582db5b655bd5cf75b5597f15d67ec48dd00b6be990e4ef9b171facf19a4c62c54616187f58c46c0f886853dea75ed4a694198640708f'
data/CHANGELOG.md CHANGED
@@ -18,6 +18,7 @@
18
18
  - Docker command network action rm is interactive.
19
19
  - Docker command container action rm is interactive.
20
20
  - Docker command run action entrypoint is interactive.
21
+ - Node command tsc accepts unfiltered arbitrary option flags.
21
22
 
22
23
  ### Changed
23
24
 
@@ -34,6 +35,7 @@
34
35
  - Repo sync option --fetch-submodules was renamed --recurse-submodules.
35
36
  - Ruby command script does not run code until it has passed validation.
36
37
  - Ruby gem io-console is used for default console size.
38
+ - Node program tsc boolean options support explicit values.
37
39
 
38
40
  ### Removed
39
41
 
@@ -42,6 +44,35 @@
42
44
  - Docker private method charname was replaced with subdomainname.
43
45
  - Git command show was relocated into command git action show.
44
46
 
47
+ ## [0.8.6] - 2026-10-01
48
+
49
+ ### Added
50
+
51
+ - Pip command options were updated to 26.2.
52
+ - Application method assign for appending project instance methods was created.
53
+
54
+ ### Fixed
55
+
56
+ - Bundle exec wrapper did not accept boolean values.
57
+ - RuboCop did not resolve config to project directory.
58
+
59
+ ## [0.7.13] - 2026-09-25
60
+
61
+ ### Fixed
62
+
63
+ - OptionPartition did not parse quoted option values.
64
+
65
+ ## [0.6.20] - 2026-09-25
66
+
67
+ ### Added
68
+
69
+ - Prompt choice optional selection can be bypassed with a single dash.
70
+ - OptionPartition can parse supplementary option flags for plain output.
71
+
72
+ ### Fixed
73
+
74
+ - Git interactive commit selection did not accept additional values.
75
+
45
76
  ## [0.8.5] - 2026-09-23
46
77
 
47
78
  ### Added
@@ -2166,12 +2197,14 @@
2166
2197
 
2167
2198
  - Changelog was created.
2168
2199
 
2200
+ [0.8.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.6
2169
2201
  [0.8.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.5
2170
2202
  [0.8.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.4
2171
2203
  [0.8.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.3
2172
2204
  [0.8.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.2
2173
2205
  [0.8.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.1
2174
2206
  [0.8.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.0
2207
+ [0.7.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.13
2175
2208
  [0.7.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.12
2176
2209
  [0.7.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.11
2177
2210
  [0.7.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.10
@@ -2185,6 +2218,7 @@
2185
2218
  [0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
2186
2219
  [0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
2187
2220
  [0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
2221
+ [0.6.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.20
2188
2222
  [0.6.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.19
2189
2223
  [0.6.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.18
2190
2224
  [0.6.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.17
data/README.md CHANGED
@@ -47,7 +47,7 @@ Usage: sqd [options] [rake options] [global...] [:targets...] -- [rake targets..
47
47
  -y, --yes [STR,STR] Enable auto-approve through ENV by application
48
48
  -d, --dry-run Run commands without any modifying actions
49
49
 
50
- -S, --select PAGE:CHOICE Prompt menu selection pagination limits
50
+ -S, --select PAGE[:CHOICE] Prompt menu selection pagination display (e.g. 15:75)
51
51
 
52
52
  -p, --pipe 0|1|2 Set file descriptor for communication
53
53
  -o, --pipe-out FILE Write command data stream to a file
@@ -132,13 +132,13 @@ Workspace::Application
132
132
  apply :clean, ["build/sqd/"] # variable_set (alias)
133
133
  end
134
134
  .with(:docker, only: ["build", "compose"], hide: [:windows?]) do # When true hide entire group
135
- .add("squared", "docker", file: "Dockerfile", tag: "latest",
136
- registry: "localhost:5000", username: "squared", # compose publish => { oci: "oci://docker.io" }
137
- args: "--ssh=default",
138
- context: ".", # Optional
139
- client: { config: '/home/user/.docker', tls: true }, # global options
140
- secrets: ["id=github,env=GITHUB_TOKEN"],
141
- mounts: ["src=.,dst=/project,ro,bind-propagation=rshared"]) do
135
+ add("squared", "docker", file: "Dockerfile", tag: "latest",
136
+ registry: "localhost:5000", username: "squared", # compose publish => { oci: "oci://docker.io" }
137
+ args: "--ssh=default",
138
+ context: ".", # Optional
139
+ client: { config: '/home/user/.docker', tls: true }, # global options
140
+ secrets: ["id=github,env=GITHUB_TOKEN"],
141
+ mounts: ["src=.,dst=/project,ro,bind-propagation=rshared"]) do
142
142
  series(:clean) do # run | depend | doc | lint | test | copy | clean
143
143
  File.read(basepath("docker-bake.hcl"))
144
144
  .scan(/\btags\s+=\s+\["([^"]+)"\]/)
@@ -146,6 +146,15 @@ Workspace::Application
146
146
  end
147
147
  end
148
148
  end
149
+ .assign(:ruby) do # Add or override instance methods
150
+ def vmname(bin: false)
151
+ bin ? ['rbenv', '/usr/bin/rbenv'] : 'rbenv'
152
+ end
153
+
154
+ def copy?
155
+ false
156
+ end
157
+ end
149
158
  .pass("pull", group: "default") { test? || doc? } # rake pathname:pull optparse:pull
150
159
  .style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
151
160
  .build(default: "build", parallel: ["pull", "fetch", "rebase", "archive", "clean", /^outdated:/], pass: ["publish"]) do |workspace|
@@ -388,10 +397,10 @@ Workspace::Application
388
397
  run([nil, "build:dev", { "PATH" => "~/.bin" }, "--workspace", "--silent"]) # PATH="~/.bin" npm run build:dev --workspace -- --silent
389
398
  # OR
390
399
  run({
391
- script: "build:dev",
392
- env: { "PATH" => "~/.bin" },
393
- opts: "--workspace",
394
- args: "--silent"
400
+ script: "build:dev",
401
+ env: { "PATH" => "~/.bin" },
402
+ opts: "--workspace",
403
+ args: "--silent"
395
404
  })
396
405
 
397
406
  add("e-mc", "emc") do
data/exe/sqd CHANGED
@@ -112,7 +112,7 @@ class SqdParser < OptionParser
112
112
  end
113
113
 
114
114
  def error_exit(*val, hint)
115
- raise OptionParser::InvalidArgument, message(*val, hint: hint)
115
+ raise OptionParser::InvalidArgument, message(*val, hint: hint), caller(1)
116
116
  end
117
117
  end
118
118
 
@@ -134,7 +134,6 @@ SqdParser.new do |sqd|
134
134
  end
135
135
  sqd.on('-e', '--project-env KEY=STR', 'Provide command ENV variables for :targets (multiple)') do |val|
136
136
  sqd.error_exit('missing value', "#{val}=") unless val.include?('=')
137
-
138
137
  sqd.options[:'project-env'] << val
139
138
  end
140
139
  sqd.separator ''
@@ -155,10 +154,9 @@ SqdParser.new do |sqd|
155
154
  ENV['DRY_RUN'] = 'true'
156
155
  end
157
156
  sqd.separator ''
158
- sqd.on('-S', '--select PAGE:CHOICE', 'Prompt menu selection pagination limits') do |val|
157
+ sqd.on('-S', '--select PAGE[:CHOICE]', 'Prompt menu selection pagination display (e.g. 15:75)') do |val|
159
158
  page, choice = val.split(/\D/, 2).map(&:to_i)
160
159
  sqd.error_exit('not an integer', val) if choice.nil? ? page == 0 : choice == 0
161
-
162
160
  session[:PAGE] = page if page > 0
163
161
  session[:CHOICE] = choice if choice.to_i > 0
164
162
  ENV['SELECT'] = "#{page}:#{choice}"
@@ -166,17 +164,14 @@ SqdParser.new do |sqd|
166
164
  sqd.separator ''
167
165
  sqd.on('-p', '--pipe 0|1|2', Integer, 'Set file descriptor for communication') do |val|
168
166
  sqd.error_exit('out of range', val) unless val.between?(0, 2)
169
-
170
167
  session[:PIPE] = val
171
168
  end
172
169
  sqd.on('-o', '--pipe-out FILE', 'Write command data stream to a file') do |val|
173
170
  sqd.error_exit("missing an explicit \".#{File::SEPARATOR}\"", val) unless val.include?(File::SEPARATOR)
174
-
175
171
  session[:OUT] = val
176
172
  end
177
173
  sqd.on('--fail 0..4', Integer, 'Set application exception level') do |val|
178
174
  sqd.error_exit('out of range', val) unless val.between?(0, 4)
179
-
180
175
  session[:FAIL] = val
181
176
  end
182
177
  %i[debug info warn error fatal].then do |state|
@@ -42,7 +42,7 @@ module Squared
42
42
  end
43
43
  rescue Interrupt
44
44
  puts
45
- exit 0
45
+ exit
46
46
  else
47
47
  exit 1 if force
48
48
  false
@@ -122,7 +122,9 @@ module Squared
122
122
  while (ch = Prompt.reline.readline(msg))
123
123
  ch.strip!
124
124
  if !ch.empty?
125
- if multiple
125
+ if ch == '-' && !force
126
+ break
127
+ elsif multiple
126
128
  k = if ch == '*'
127
129
  (min..max).to_a
128
130
  else
@@ -161,7 +163,7 @@ module Squared
161
163
  end
162
164
  rescue Interrupt
163
165
  std.puts
164
- exit 0
166
+ exit
165
167
  else
166
168
  [] if multiple
167
169
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.9.0.pre1'
4
+ VERSION = '0.9.0.pre2'
5
5
  end
@@ -406,7 +406,7 @@ module Squared
406
406
  end
407
407
  unless ref.is_a?(Symbol) && (proj = @base.find { |item| item.ref == ref })
408
408
  proj = if !ref.is_a?(Class)
409
- require_project(ref) || Application.find(ref: ref, path: path)
409
+ find_project(ref: ref, path: path)
410
410
  elsif Application.extends(ref)
411
411
  ref
412
412
  end || @kind[name]&.last
@@ -454,6 +454,16 @@ module Squared
454
454
  self
455
455
  end
456
456
 
457
+ def assign(ref = @ref, &blk)
458
+ proj = ref && find_project(ref: ref)
459
+ if proj
460
+ proj.class_eval(&blk)
461
+ else
462
+ warn log_message(Logger::ERROR, 'class not found', subject: main, hint: ref)
463
+ end
464
+ self
465
+ end
466
+
457
467
  def stage(val, first: false, &blk)
458
468
  data = @stage[val]
459
469
  if first == true
@@ -481,7 +491,7 @@ module Squared
481
491
  obj = begin
482
492
  JSON.parse(homepath(obj).read, { symbolize_names: true })
483
493
  rescue => e
484
- warn log_message(Logger::ERROR, e)
494
+ warn log_message(Logger::ERROR, e, subject: main)
485
495
  end
486
496
  end
487
497
  apply_style(data || theme, obj, args, empty: empty) if obj && (!target || data)
@@ -1091,6 +1101,10 @@ module Squared
1091
1101
  nil
1092
1102
  end
1093
1103
 
1104
+ def find_project(ref:, path: nil)
1105
+ require_project(ref) || Application.find(ref: ref, path: path)
1106
+ end
1107
+
1094
1108
  def root?(path, pass: [])
1095
1109
  return false unless path.directory?
1096
1110
 
@@ -1174,10 +1174,20 @@ module Squared
1174
1174
  ret = basepath(*args)
1175
1175
  return ret unless ascend && !ret.exist?
1176
1176
 
1177
+ case ascend
1178
+ when String, Pathname
1179
+ root = Pathname.new(ascend).cleanpath
1180
+ root = nil unless root.absolute? && root.directory?
1181
+ end
1177
1182
  path.parent.ascend.each do |dir|
1178
1183
  target = dir.join(*args)
1179
1184
  return target if target.exist?
1180
- break if (ascend.is_a?(String) && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1185
+
1186
+ if root
1187
+ break if dir == root
1188
+ elsif workspace.root == dir || parent&.path == dir || (ascend.is_a?(String) && dir.join(ascend).exist?)
1189
+ break
1190
+ end
1181
1191
  end
1182
1192
  ret
1183
1193
  end
@@ -1364,7 +1374,7 @@ module Squared
1364
1374
  run(val, var, sync: sync, banner: banner, **kwargs)
1365
1375
  end
1366
1376
  rescue => e
1367
- on_error(e, exception: kwargs.fetch(:exception, exception?))
1377
+ on_error(e, exception: exception?(**kwargs))
1368
1378
  end
1369
1379
  on :last, from
1370
1380
  end
@@ -2134,6 +2144,10 @@ module Squared
2134
2144
 
2135
2145
  def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
2136
2146
  if args && key
2147
+ if key.is_a?(Array)
2148
+ return key.map { |val| param_guard(action, flag, args: args, key: val, pat: pat, values: values) }
2149
+ end
2150
+
2137
2151
  val = args.fetch(key, nil)
2138
2152
  return val unless val.nil? || (pat && !val.match?(pat)) || (values && !values.include?(val))
2139
2153
 
@@ -2820,7 +2834,9 @@ module Squared
2820
2834
  workspace.warning
2821
2835
  end
2822
2836
 
2823
- def exception?(*level)
2837
+ def exception?(*level, **kwargs)
2838
+ return kwargs[:exception] if kwargs.key?(:exception)
2839
+
2824
2840
  ret = exception
2825
2841
  return ret unless ret.is_a?(Numeric)
2826
2842
 
@@ -481,8 +481,7 @@ module Squared
481
481
  when :url
482
482
  format_desc action, flag, 'path,url,opts*'
483
483
  task flag, [:path, :url] do |_, args|
484
- path = param_guard(action, flag, args: args, key: :path)
485
- url = param_guard(action, flag, args: args, key: :url)
484
+ path, url = param_guard(action, flag, args: args, key: %i[path url])
486
485
  submodule(flag, args.extras, path: path, url: url)
487
486
  end
488
487
  else
@@ -663,9 +662,9 @@ module Squared
663
662
  when :files
664
663
  format_desc action, flag, 'path1,path2,patch?'
665
664
  task flag, [:path1, :path2, :patch] do |_, args|
666
- path1 = param_guard(action, flag, args: args, key: :path1)
667
- path2 = param_guard(action, flag, args: args, key: :path2)
668
- diff(flag, refs: [path1, path2, args.patch])
665
+ refs = param_guard(action, flag, args: args, key: %i[path1 path2])
666
+ refs << args.patch if args.patch
667
+ diff(flag, refs: refs)
669
668
  end
670
669
  when :grep
671
670
  format_desc action, flag, 'pattern+,a/ll-match?,in/vert-grep?,i/E/F/P?,max-count?=i,f/ormat?=s'
@@ -860,8 +859,7 @@ module Squared
860
859
  when :branch
861
860
  format_desc action, flag, 'branch/:,opts*'
862
861
  task flag, [:branch] do |_, args|
863
- branch = args.branch
864
- branch = nil if branch == ':'
862
+ branch = args.branch unless args.branch == ':'
865
863
  switch(flag, args.extras, branch: branch || choice_refs('Choose a branch'))
866
864
  end
867
865
  end
@@ -889,7 +887,7 @@ module Squared
889
887
  reset(flag, args.to_a, refs: [])
890
888
  end
891
889
  when :mode
892
- format_desc action, flag, 'mode,ref/:'
890
+ format_desc action, flag, 'mode,ref?|:'
893
891
  task flag, [:mode, :ref] do |_, args|
894
892
  mode = param_guard(action, flag, args: args, key: :mode)
895
893
  ref = commithead args.ref
@@ -942,10 +940,13 @@ module Squared
942
940
  when :commit, :'no-commit'
943
941
  format_desc action, flag, 'branch|:,ours|theirs?,opts*'
944
942
  task flag, [:branch] do |_, args|
945
- branch = args.branch
946
- current = git_spawn('branch --show-current').chomp
943
+ branch = if args.branch == ':'
944
+ choice_refs('Choose a branch', accept: "#{action.capitalize}?")
945
+ else
946
+ args.branch
947
+ end
948
+ current = git_value 'branch --show-current'
947
949
  if branch
948
- branch = choice_refs('Choose a branch', accept: "#{action.capitalize}?") if branch == ':'
949
950
  opts = args.extras
950
951
  if has_value!(opts, 'ours')
951
952
  opts << 's=ort' << 'X=ours'
@@ -1070,8 +1071,7 @@ module Squared
1070
1071
  if flag == :add
1071
1072
  format_desc action, flag, 'name,url,opts*'
1072
1073
  task flag, [:name, :url] do |_, args|
1073
- name = param_guard(action, flag, args: args, key: :name)
1074
- url = param_guard(action, flag, args: args, key: :url)
1074
+ name, url = param_guard(action, flag, args: args, key: %i[name url])
1075
1075
  raise ArgumentError, message('invalid url', hint: url) unless url.match?(GIT_PROTO)
1076
1076
 
1077
1077
  git(:remote, args.extras, extras: [name, url])
@@ -1201,7 +1201,7 @@ module Squared
1201
1201
  (heads.dup << cur).each_with_index do |branch, i|
1202
1202
  next unless (i < heads.size && cur != branch) || i == heads.size
1203
1203
 
1204
- git_spawn 'switch --quiet', force && '--force', shell_quote(branch)
1204
+ git_spawn('switch --quiet', force && '--force', shell_quote(branch))
1205
1205
  pull(nil, opts, sync: false, hint: branch) if heads.include?(branch)
1206
1206
  end
1207
1207
  return
@@ -1277,13 +1277,13 @@ module Squared
1277
1277
  if flag
1278
1278
  return unless dir && ref
1279
1279
 
1280
- url = git_spawn("config --get remote.#{remotetrack}.url")
1280
+ url = git_value "config --get remote.#{remotetrack}.url"
1281
1281
  cmd, opts = git_session('clone', worktree: false, opts: opts)
1282
1282
  op = OptionPartition.new(opts, OPT_GIT[:clone], cmd, project: self, strict: strict?,
1283
1283
  no: OPT_GIT[:no][:clone])
1284
1284
  op.add_option('b', ref)
1285
1285
  .delim
1286
- .add_quote(url.chomp)
1286
+ .add_quote(url)
1287
1287
  .add_path(dir)
1288
1288
  .clear
1289
1289
  source
@@ -1476,7 +1476,7 @@ module Squared
1476
1476
  end
1477
1477
  return
1478
1478
  end
1479
- sha = git_spawn('rev-parse --verify HEAD').chomp
1479
+ sha = git_value 'rev-parse --verify HEAD'
1480
1480
  return if sha.empty?
1481
1481
 
1482
1482
  sync = kwargs.fetch(:sync) { invoked_sync?('revbuild', flag) }
@@ -1539,7 +1539,7 @@ module Squared
1539
1539
  .clear(pass: false)
1540
1540
  when :commit
1541
1541
  exit 1 unless ref
1542
- branch ||= git_spawn('name-rev --name-only', ref).chomp
1542
+ branch ||= git_value('name-rev --name-only', ref)
1543
1543
  raise ArgumentError, message('could not resolve upstream branch', hint: ref) if branch.empty?
1544
1544
 
1545
1545
  op.append(remotetrack, "#{ref}:#{branch}")
@@ -1734,7 +1734,7 @@ module Squared
1734
1734
  end
1735
1735
  if (n = op.index('>'))
1736
1736
  patch = op.slice!(n, 2)[1]
1737
- elsif !op.exist?(op.last)
1737
+ elsif !op.last.include?('*') && !op.exist?(op.last)
1738
1738
  patch ||= op.pop
1739
1739
  end
1740
1740
  append_pathspec op.extras
@@ -1946,7 +1946,8 @@ module Squared
1946
1946
  list_result(ret, 'branches', banner: banner, from: from)
1947
1947
  return
1948
1948
  else
1949
- if (head = git_spawn('rev-parse --abbrev-ref HEAD').chomp).empty?
1949
+ head = git_value 'rev-parse --abbrev-ref HEAD'
1950
+ if head.empty?
1950
1951
  ret = 0
1951
1952
  else
1952
1953
  git_spawn 'fetch --all --prune --quiet' if option('sync')
@@ -2044,7 +2045,7 @@ module Squared
2044
2045
  else
2045
2046
  ref
2046
2047
  end)
2047
- return git_spawn(cmd, exception: false).chomp
2048
+ return git_value(cmd, exception: false)
2048
2049
  when :output
2049
2050
  if opts.delete('sq-quote')
2050
2051
  cmd << '--sq-quote'
@@ -2326,7 +2327,7 @@ module Squared
2326
2327
  ret = choice_index(msg, git_spawn(cmd, stdout: false), column: /^(\S+)/, force: force, **kwargs)
2327
2328
  case ret
2328
2329
  when Array
2329
- ret.map { |val| val&.stripstyle }
2330
+ ret.map { |val| val.is_a?(Array) ? val.map { |s| s&.stripstyle } : val&.stripstyle }
2330
2331
  when String
2331
2332
  ret.stripstyle
2332
2333
  else
@@ -2504,6 +2505,10 @@ module Squared
2504
2505
  stdout: stdout, banner: banner, **kwargs)
2505
2506
  end
2506
2507
 
2508
+ def git_value(*cmd, exception: true)
2509
+ git_spawn(*cmd, exception: exception).chomp
2510
+ end
2511
+
2507
2512
  def git_grep(cmd, *grep, equals: true, **kwargs)
2508
2513
  ret = []
2509
2514
  git_spawn(cmd, **kwargs).lines(chomp: true).each do |line|
@@ -69,7 +69,7 @@ module Squared
69
69
  install: %w[check-cache check-resolutions immutable immutable-cache inline-builds json refresh-lockfile
70
70
  mode=b].freeze,
71
71
  add: %w[cached D|dev json O|optional P|peer prefer-dev].freeze,
72
- add_a: %w[C|caret E|exact F|fixed interactive T|tilde mode=b].freeze,
72
+ add_a: %w[C|caret E|exact F|fixed i|interactive no-time-gate T|tilde mode=b].freeze,
73
73
  update: %w[R|recursive].freeze,
74
74
  dedupe: %w[check json mode=b strategy=b].freeze,
75
75
  run: %w[B|binaries-only inspect inspect-brk T|top-level require=q].freeze,
@@ -77,39 +77,37 @@ module Squared
77
77
  }.freeze
78
78
  OPT_TSC = {
79
79
  base: %w[all b|build init listFilesOnly locale=b p|project=p showConfig w|watch].freeze,
80
- compiler: %w[allowArbitraryExtensions=!? allowImportingTsExtensions=!? allowJs=!? allowUmdGlobalAccess=!?
81
- allowUnreachableCode=!? allowUnusedLabels=!? assumeChangesOnlyAffectDirectDependencies=!?
82
- charset=b checkJs=!? composite=!? customConditions=q d|declaration=!? declarationDir=p
83
- declarationMap=!? diagnostics=!? disableReferencedProjectLoad=!? disableSizeLimit=!?
84
- disableSolutionSearching=!? emitBOM=!? emitDeclarationOnly=!? emitDecoratorMetadata=!?
85
- erasableSyntaxOnly=!? exactOptionalPropertyTypes=!? experimentalDecorators=!? explainFiles=!?
86
- extendedDiagnostics=!? forceConsistentCasingInFileNames=!? generateCpuProfile=b ignoreConfig=!?
87
- importHelpers=!? importsNotUsedAsValues=b incremental=!? inlineSourceMap=!? inlineSources=!?
88
- isolatedDeclarations=!? isolatedModules=!? jsx=b jsxFactory=q jsxFragmentFactory=q
89
- jsxImportSource=q keyofStringsOnly=!? lib=q libReplacement=!? listEmittedFiles=!? listFiles=!?
90
- mapRoot=p maxNodeModuleJsDepth=i m|module=b moduleDetection=b moduleResolution=b moduleSuffixes=b
91
- newLine=b noCheck=!? noEmit=!? noEmitHelpers=!? noEmitOnError=!? noErrorTruncation=!?
92
- noFallthroughCasesInSwitch=!? noImplicitAny=!? noImplicitOverride=!? noImplicitReturns=!?
93
- noImplicitThis=!? noImplicitUseStrict=!? noLib=!? noPropertyAccessFromIndexSignature=!?
94
- noResolve=!? noStrictGenericChecks=!? noUncheckedIndexedAccess=!? noUncheckedSideEffectImports=!?
95
- noUnusedLocals=!? noUnusedParameters=!? outDir=p paths=q plugins=b preserveConstEnums=!?
96
- preserveSymlinks=!? preserveValueImports=!? preserveWatchOutput=!? pretty=!? reactNamespace=b
97
- removeComments=!? resolveJsonModule=!? resolvePackageJsonExports=!? resolvePackageJsonImports=!?
98
- rewriteRelativeImportExtensions=!? rootDir=p rootDirs=p skipDefaultLibCheck=!? skipLibCheck=!?
99
- sourceMap=!? sourceRoot=p stableTypeOrdering=!? stopBuildOnErrors=!? strict=!?
100
- strictBindCallApply=!? strictBuiltinIteratorReturn=!? strictFunctionTypes=!? strictNullChecks=!?
101
- strictPropertyInitialization=!? stripInternal=!? suppressExcessPropertyErrors=!?
102
- suppressImplicitAnyIndexErrors=!? t|target=b traceResolution=!? tsBuildInfoFile=p typeRoots=p
103
- types=b useDefineForClassFields=!? useUnknownInCatchVariables=!? verbatimModuleSyntax=!?].freeze,
104
- build: %w[clean=!? dry=!? force=!? v|verbose=!?].freeze,
105
- watch: %w[excludeDirectories=p excludeFiles=p fallbackPolling=b synchronousWatchDirectory=!? watchDirectory=b
80
+ compiler: %w[allowArbitraryExtensions allowImportingTsExtensions allowJs allowUmdGlobalAccess
81
+ allowUnreachableCode allowUnusedLabels assumeChangesOnlyAffectDirectDependencies charset=b
82
+ checkJs composite customConditions=q d|declaration declarationDir=p declarationMap diagnostics
83
+ disableReferencedProjectLoad disableSizeLimit disableSolutionSearching emitBOM
84
+ emitDeclarationOnly emitDecoratorMetadata erasableSyntaxOnly exactOptionalPropertyTypes
85
+ experimentalDecorators explainFiles extendedDiagnostics forceConsistentCasingInFileNames
86
+ generateCpuProfile=b ignoreConfig importHelpers importsNotUsedAsValues=b incremental
87
+ inlineSourceMap inlineSources isolatedDeclarations isolatedModules jsx=b jsxFactory=q
88
+ jsxFragmentFactory=q jsxImportSource=q keyofStringsOnly lib=q libReplacement listEmittedFiles
89
+ listFiles mapRoot=p maxNodeModuleJsDepth=i m|module=b moduleDetection=b moduleResolution=b
90
+ moduleSuffixes=b newLine=b noCheck noEmit noEmitHelpers noEmitOnError noErrorTruncation
91
+ noFallthroughCasesInSwitch noImplicitAny noImplicitOverride noImplicitReturns noImplicitThis
92
+ noImplicitUseStrict noLib noPropertyAccessFromIndexSignature noResolve noStrictGenericChecks
93
+ noUncheckedIndexedAccess noUncheckedSideEffectImports noUnusedLocals noUnusedParameters outDir=p
94
+ paths=q plugins=b preserveConstEnums preserveSymlinks preserveValueImports preserveWatchOutput
95
+ pretty reactNamespace=b removeComments resolveJsonModule resolvePackageJsonExports
96
+ resolvePackageJsonImports rewriteRelativeImportExtensions rootDir=p rootDirs=p
97
+ skipDefaultLibCheck skipLibCheck sourceMap sourceRoot=p stableTypeOrdering stopBuildOnErrors
98
+ strict strictBindCallApply strictBuiltinIteratorReturn strictFunctionTypes strictNullChecks
99
+ strictPropertyInitialization stripInternal suppressExcessPropertyErrors
100
+ suppressImplicitAnyIndexErrors t|target=b traceResolution tsBuildInfoFile=p typeRoots=p types=b
101
+ useDefineForClassFields useUnknownInCatchVariables verbatimModuleSyntax].freeze,
102
+ build: %w[clean dry force v|verbose].freeze,
103
+ watch: %w[excludeDirectories=p excludeFiles=p fallbackPolling=b synchronousWatchDirectory watchDirectory=b
106
104
  watchFile=b].freeze,
107
105
  v7: {
108
106
  compiler: %w[builders=i checkers=i singleThreaded=!?]
109
107
  },
110
108
  v5: {
111
- compiler: %w[allowSyntheticDefaultImports=!? alwaysStrict=!? baseUrl=p downlevelIteration=!?
112
- esModuleInterop=!? outFile=p].freeze
109
+ compiler: %w[allowSyntheticDefaultImports alwaysStrict baseUrl=p downlevelIteration esModuleInterop
110
+ outFile=p].freeze
113
111
  }.freeze
114
112
  }.freeze
115
113
  PASS_NODE = {
@@ -350,7 +348,7 @@ module Squared
350
348
  .map { |name, ver| name.ljust(pad + 4) + ver }
351
349
  if list.empty?
352
350
  puts log_message('no packages to review', subject: name, hint: "#{flag}-scripts")
353
- exit 0
351
+ exit
354
352
  end
355
353
  args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
356
354
  end
@@ -664,7 +662,7 @@ module Squared
664
662
  end
665
663
  if nolockfile?(prefix: 'yarn')
666
664
  cmd << '--no-lockfile'
667
- elsif ci? && exist?('yarn.lock')
665
+ elsif ci? && exist?(yarnlock)
668
666
  if yarn == 1
669
667
  cmd << '--frozen-lockfile'
670
668
  elsif !flag
@@ -700,13 +698,13 @@ module Squared
700
698
  '--force'
701
699
  elsif nolockfile?(prefix: 'pnpm')
702
700
  '--no-lockfile'
703
- elsif ci? && exist?('pnpm-lock.yaml')
701
+ elsif ci? && exist?(pnpmlock)
704
702
  '--frozen-lockfile'
705
703
  end
706
704
  cmd << '--ignore-scripts' if option('ignore-scripts')
707
705
  cmd << '--dangerously-allow-all-builds' if option('approve-builds')
708
706
  else
709
- cmd = session('npm', ci = ci? && exist?('package-lock.json') ? 'ci' : 'install')
707
+ cmd = session('npm', ci = ci? && exist?(npmlock) ? 'ci' : 'install')
710
708
  option('approve-scripts') do |val|
711
709
  cmd = npm_output 'approve-scripts'
712
710
  cmd << case val
@@ -759,7 +757,7 @@ module Squared
759
757
  append_platform
760
758
  end
761
759
  end
762
- cmd << '--package-lock=false' << 'save=false' if nolockfile?(prefix: 'npm')
760
+ cmd << '--package-lock=false' << '--save=false' if nolockfile?(prefix: 'npm')
763
761
  cmd << '--ignore-scripts' if option('ignore-scripts')
764
762
  end
765
763
  if add
@@ -772,7 +770,7 @@ module Squared
772
770
  end
773
771
 
774
772
  def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
775
- cmd = session(pnpm? && exist?('pnpm-lock.yaml') ? 'pnpm' : 'npm', 'outdated')
773
+ cmd = session(pnpm? && exist?(pnpmlock) ? 'pnpm' : 'npm', 'outdated')
776
774
  dryrun = has_value?(opts, 'd', 'dry-run') || dryrun?
777
775
  unless dryrun
778
776
  log.info cmd.to_s
@@ -1351,39 +1349,47 @@ module Squared
1351
1349
  end
1352
1350
 
1353
1351
  def tsc(*args, with: nil, pass: PASS_NODE[:tsc], sync: true, banner: verbose?, from: :tsc, **kwargs)
1354
- session_apply(with, args: args, kwargs: kwargs, pass: pass) if with
1352
+ opts = session_opts(with, args: args, kwargs: kwargs, pass: pass)
1355
1353
  p = kwargs[:project]
1356
1354
  b = kwargs[:build]
1357
1355
  w = kwargs[:watch]
1358
1356
  list = OPT_TSC[:base] + OPT_TSC[:compiler]
1359
1357
  kwargs[:legacy] = semapp('npx', 'tsc', '--version', minor: false) if kwargs[:detect]
1360
1358
  list.concat(Array(kwargs[:legacy]).flat_map { |n| OPT_TSC.fetch(:"v#{n}", {}).fetch(:compiler, []) })
1359
+ auto = %w[h|help v|version]
1361
1360
  cmd = session 'tsc', if p
1362
1361
  quote_option 'p', basepath(p)
1363
1362
  elsif b
1364
1363
  list.concat(OPT_TSC[:build])
1364
+ auto[1] = 'version'
1365
1365
  '-b'
1366
1366
  end
1367
1367
  if w
1368
1368
  list.concat(OPT_TSC[:watch])
1369
1369
  cmd << '-w'
1370
1370
  end
1371
- op = OptionPartition.new(args, list, cmd, project: self, strict: strict?, sep: ' ')
1372
- unless p
1373
- if b.is_a?(String)
1374
- op.add_path(b)
1375
- elsif w.is_a?(String)
1376
- op.add_path(w)
1377
- else
1378
- op.exist?(add: true)
1371
+ flags, args = args.partition { |val| val.start_with?('-') }
1372
+ op = OptionPartition.new(opts + args, list, cmd, project: self, strict: strict?, auto: auto, explicit: true,
1373
+ sep: ' ')
1374
+ if op.stdout
1375
+ banner = false
1376
+ else
1377
+ unless p
1378
+ if b.is_a?(String)
1379
+ op.add_path(b)
1380
+ elsif w.is_a?(String)
1381
+ op.add_path(w)
1382
+ else
1383
+ op.exist?(add: true)
1384
+ end
1379
1385
  end
1386
+ op.append(flags, escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
1387
+ .clear
1388
+ print_run(op, banner, **kwargs)
1389
+ start = time_epoch if kwargs.fetch(:verbose, verbose? && !stdin?)
1380
1390
  end
1381
- op.clear
1382
- cmd = session_done(op.target)
1383
- print_run(cmd, banner, **kwargs)
1384
- session 'npx', cmd
1385
- start = time_epoch if kwargs.fetch(:verbose, verbose? && !stdin?)
1386
- ret = run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: from)
1391
+ session 'npx', session_done(op.target)
1392
+ ret = run(sync: sync, banner: banner, exception: exception?(**kwargs), from: from)
1387
1393
  print_status(name, subject: 'tsc', start: start) if success?(ret, banner, start.nil?) && start
1388
1394
  ret
1389
1395
  end
@@ -1454,7 +1460,7 @@ module Squared
1454
1460
  end
1455
1461
 
1456
1462
  def yarn?
1457
- (@pm[:yarn] ||= if rootpath('yarn.lock', ascend: dependroot).exist?
1463
+ (@pm[:yarn] ||= if rootpath(yarnlock, ascend: dependroot).exist?
1458
1464
  yarntype
1459
1465
  elsif (ver = read_package || read_install)
1460
1466
  if ver =~ /^yarn(?:@(\d)|$)/
@@ -1475,7 +1481,7 @@ module Squared
1475
1481
  end
1476
1482
 
1477
1483
  def pnpm?
1478
- (@pm[:pnpm] ||= if rootpath('pnpm-lock.yaml', ascend: dependroot).exist?
1484
+ (@pm[:pnpm] ||= if rootpath(pnpmlock, ascend: dependroot).exist?
1479
1485
  pnpmtype
1480
1486
  elsif (ver = read_package || read_install)
1481
1487
  ver.start_with?('pnpm') ? pnpmtype : 0
@@ -1584,7 +1590,7 @@ module Squared
1584
1590
  require 'yaml'
1585
1591
  doc = YAML.load_file(rc)
1586
1592
  doc.nodeLinker == 'node-modules' ? 2 : 3
1587
- elsif exist && !exist?('yarn.lock')
1593
+ elsif exist && !exist?(yarnlock)
1588
1594
  0
1589
1595
  else
1590
1596
  1
@@ -1596,6 +1602,10 @@ module Squared
1596
1602
  3
1597
1603
  end
1598
1604
 
1605
+ def yarnlock
1606
+ 'yarn.lock'
1607
+ end
1608
+
1599
1609
  def pnpmtype(exist: false)
1600
1610
  require 'yaml'
1601
1611
  doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependroot))
@@ -1610,13 +1620,21 @@ module Squared
1610
1620
  end
1611
1621
  rescue => e
1612
1622
  if exist
1613
- %w[pnpm-lock.yaml pnpm-workspace.yaml].any? { |val| exist?(val) } ? 4 : 0
1623
+ %W[#{pnpmlock} pnpm-workspace.yaml].any? { |val| exist?(val) } ? 4 : 0
1614
1624
  else
1615
1625
  log.debug e
1616
1626
  4
1617
1627
  end
1618
1628
  end
1619
1629
 
1630
+ def pnpmlock
1631
+ 'pnpm-lock.yaml'
1632
+ end
1633
+
1634
+ def pnpmopts(*args)
1635
+ OPT_PNPM[:common] + args.flat_map { |name| OPT_PNPM.fetch(name, []) }
1636
+ end
1637
+
1620
1638
  def remove_modules(prefix: dependbin)
1621
1639
  modules = basepath!('node_modules', type: 'd')
1622
1640
  return false unless modules && confirm_basic('Remove?', modules, prefix: prefix)
@@ -1698,16 +1716,16 @@ module Squared
1698
1716
  ].concat(args)
1699
1717
  end
1700
1718
 
1701
- def npmopts(*args)
1702
- OPT_NPM[:common] + args.flat_map { |name| OPT_NPM.fetch(name, []) }
1719
+ def npmlock
1720
+ 'package-lock.json'
1703
1721
  end
1704
1722
 
1705
- def pnpmopts(*args)
1706
- OPT_PNPM[:common] + args.flat_map { |name| OPT_PNPM.fetch(name, []) }
1723
+ def npmopts(*args)
1724
+ OPT_NPM[:common] + args.flat_map { |name| OPT_NPM.fetch(name, []) }
1707
1725
  end
1708
1726
 
1709
1727
  def lockfile(delete = false)
1710
- ret = basepath(yarn? ? 'yarn.lock' : pnpm? ? 'pnpm-lock.yaml' : 'package-lock.json')
1728
+ ret = basepath(yarn? ? yarnlock : pnpm? ? pnpmlock : npmlock)
1711
1729
  if ret.exist?
1712
1730
  if delete
1713
1731
  ret.delete
@@ -19,10 +19,10 @@ module Squared
19
19
  setuptools=b try-first-with=q].freeze
20
20
  }.freeze
21
21
  OPT_PIP = {
22
- common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input require-virtualenv
23
- q|quiet=+ v|verbose=+ cache-dir=p cert=p client-cert=p exists-action=b keyring-provider=b log=p
24
- proxy=q python=q resume-retries=i retries=i timeout=i trusted-host=b use-deprecated=b
25
- use-feature=b].freeze,
22
+ common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input no-proxy-env
23
+ require-virtualenv q|quiet=+ v|verbose=+ cache-dir=p cert=p client-cert=p exists-action=b
24
+ keyring-provider=b log=p proxy=q python=q resume-retries=i retries=i timeout=i trusted-host=b
25
+ use-deprecated=b use-feature=b].freeze,
26
26
  cache: %w[format=b].freeze,
27
27
  completion: %w[b|bash f|fish p|powershell z|zsh].freeze,
28
28
  config: %w[global user site editor=p].freeze,
@@ -35,12 +35,12 @@ module Squared
35
35
  no-warn-conflicts no-warn-script-location U|upgrade user prefix=p report=p root=p
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
- no-binary=q only-binary=q only-final=b].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,
38
+ no-binary=q only-binary=q only-final=b refresh-package=q uploaded-prior-to=q].freeze,
39
+ install_b: %w[check-build-dependencies no-build-isolation no-clean no-deps no-require-hashes only-deps
40
+ require-hashes use-pep517 build-constraint=p c|constraint=p group=q progress-bar=b
41
+ r|requirement=p requirements-from-script=p src=p].freeze,
42
42
  install_c: %w[C|config-settings=q e|editable=v].freeze,
43
- install_d: %w[ignore-requires-python uploaded-prior-to=q].freeze,
43
+ install_d: %w[ignore-requires-python].freeze,
44
44
  hash: %w[a|algorithm].freeze,
45
45
  list: %w[e|editable exclude-editable include-editable l|local not-required o|outdated u|uptodate user
46
46
  exclude=b format=b path=p].freeze,
@@ -749,8 +749,8 @@ module Squared
749
749
  def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
750
750
  op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
751
751
  session('python', path: !venv?),
752
- project: self, strict: strict?, multiple: [/^-c/], single: singleopt(:python),
753
- args: true, stdin: true)
752
+ project: self, strict: strict?, auto: %w[help V|version],
753
+ multiple: [/^-c/], single: singleopt(:python), args: true, stdin: true)
754
754
  op.concat(args)
755
755
  if op.include?('-')
756
756
  op.exist?(add: true)
@@ -763,8 +763,8 @@ module Squared
763
763
  op.append(escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
764
764
  end
765
765
  end
766
- print_run(op, banner, **kwargs)
767
- run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :python)
766
+ print_run(op, banner, **kwargs) unless op.stdout
767
+ run(sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from: :python)
768
768
  end
769
769
 
770
770
  def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -846,7 +846,7 @@ module Squared
846
846
  op.clear
847
847
  end
848
848
  print_run(op, banner, **kwargs)
849
- run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: symjoin('pip', flag))
849
+ run(sync: sync, banner: banner, exception: exception?(**kwargs), from: symjoin('pip', flag))
850
850
  .then { |val| ret || val }
851
851
  end
852
852
 
@@ -1122,12 +1122,12 @@ module Squared
1122
1122
  def singleopt(flag = nil)
1123
1123
  case flag
1124
1124
  when :python
1125
- /\A(?:v+|q+|b+|V+|O+)\z/
1125
+ /\A(v+|q+|b+|V+|O+)\z/
1126
1126
  when :pdm, :poetry
1127
1127
  /\Av+\z/
1128
1128
  when :twine, :meson then nil
1129
1129
  else
1130
- /\A(?:v+|q+)\z/
1130
+ /\A(v+|q+)\z/
1131
1131
  end
1132
1132
  end
1133
1133
 
@@ -1145,19 +1145,18 @@ module Squared
1145
1145
  def pipopts(flag)
1146
1146
  ret = OPT_PIP.fetch(flag, []) + OPT_PIP[:common]
1147
1147
  if pip_install?(flag)
1148
- ret.concat(OPT_PIP[:install_a])
1148
+ ret.concat(OPT_PIP[:install_a], OPT_PIP[:install_d])
1149
1149
  ret.concat(OPT_PIP[:install_b]) unless flag == :index
1150
- ret.concat(OPT_PIP[:install_d])
1151
1150
  case flag
1152
1151
  when :install
1153
- ret.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
1152
+ ret.concat(OPT_PIP[:install_c], OPT_PIP[:debug])
1154
1153
  when :lock, :wheel
1155
1154
  ret.concat(OPT_PIP[:install_c])
1156
1155
  when :download, :index
1157
1156
  ret.concat(OPT_PIP[:debug])
1158
1157
  end
1159
1158
  elsif flag == :list
1160
- ret.concat(OPT_PIP[:install_a])
1159
+ ret.concat(OPT_PIP[:install_a], OPT_PIP[:install_d])
1161
1160
  end
1162
1161
  ret
1163
1162
  end
@@ -21,24 +21,25 @@ module Squared
21
21
  nomultiline noprompt noscript nosingleline noverbose regexp-completor sample-book-mode script
22
22
  simple-prompt single-irb singleline tracer truncate-echo-on-assignment type-completor verbose
23
23
  back-trace-limit=i context-mode=i prompt=b prompt-mode=b].freeze,
24
- rdbg: %w[no-color no-rc no-sigint-hook c|command n|nonstop stop-at-load cookie=q e=q host=q x|init-script=p
24
+ rdbg: %w[e=q no-color no-rc no-sigint-hook c|command n|nonstop stop-at-load cookie=q host=q x|init-script=p
25
25
  O|open=q? port=i port-range=b session-name=q sock-path=q util=q].freeze,
26
26
  rbs: %w[I=pm r=bm no-collection no-stdlib collection=p log-level=b log-output=p repo=p].freeze,
27
- rubocop: %w[D P r=bm auto-gen-config a|autocorrect A|autocorrect-all d|debug disable-pending-cops
28
- display-only-correctable display-only-fail-level-offenses display-only-failed
29
- display-only-safe-correctable S|display-style-guide display-time disable-uncorrectable editor-mode
30
- enable-pending-cops E|extra-details F|fail-fast force-default-config force-exclusion x|fix-layout
31
- ignore-disable-comments ignore-parent-exclusion ignore-unrecognized-cops init l|lint
32
- list-enabled-cops-for=p L|list-target-files lsp memory no-detach only-guide-cops
33
- only-recognized-file-types no-exclude-limit profile raise-cop-error regenerate-todo
34
- restart-server safe server-status start-server stderr stop-server C|cache=b cache-root=p config=p
35
- exclude-limit=i fail-level=b f|format=b except=q only=q o|out=p plugin=p require=p show-cops=q
36
- show-docs-url=q s|stdin=p].freeze,
27
+ rubocop: %w[D P r=bm auto-gen-config a|autocorrect A|autocorrect-all d|debug diff disable-all-cops
28
+ disable-pending-cops display-only-correctable display-only-fail-level-offenses display-only-failed
29
+ display-only-safe-correctable S|display-style-guide display-suppressed display-time
30
+ disable-uncorrectable editor-mode enable-pending-cops E|extra-details F|fail-fast
31
+ force-default-config force-exclusion x|fix-layout ignore-disable-comments ignore-parent-exclusion
32
+ ignore-unrecognized-cops init l|lint L|list-target-files lsp mcp memory no-detach no-exclude-limit
33
+ only-guide-cops only-recognized-file-types profile raise-cop-error regenerate-todo
34
+ report-unused-todo-entries restart-server safe server-status start-server stderr stop-server
35
+ verbose-version C|cache=b cache-root=p changed=b config=p exclude-limit=i fail-level=b f|format=b
36
+ except=q list-enabled-cops-for=p only=q o|out=p plugin=p require=p show-cops=q show-docs-url=q
37
+ s|stdin=p].freeze,
37
38
  pry: %w[f e=q I=pm no-color no-history no-multiline no-pager no-plugins simple-prompt c|context=q
38
39
  d|disable-plugin=q gem=b r|require=bm s|select-plugin=q].freeze,
39
40
  no: {
40
41
  rubocop: %w[auto-gen-enforced-style auto-gen-only-exclude auto-gen-timestamp color display-cop-names
41
- offense-counts parallel server].freeze
42
+ offense-counts parallel preview server].freeze
42
43
  }
43
44
  }.freeze
44
45
  OPT_BUNDLE = {
@@ -226,9 +227,10 @@ module Squared
226
227
  serve_set kwargs[:serve]
227
228
  gemfile_set kwargs[:gemspec]
228
229
  self.autodetect = autodetect
229
- @bundle = { exec: exec.is_a?(String) ? basepath!(exec) : false }
230
+ @bundle = { exec: exec.is_a?(String) ? basepath!(exec) : exec }
230
231
  @steepfile = basepath! steep if steep
231
- @rubocopfile = Pathname.new(rubocop).realpath rescue basepath!(Dir.home, '.rubocop.yml') if rubocop
232
+ rubocop = rootpath('.rubocop.yml', ascend: Dir.home) if rubocop == true
233
+ @rubocopfile = basepath! rubocop if rubocop
232
234
  @rubygems = kwargs.fetch(:rubygems, 0)
233
235
  return unless rakefile && @output[0].nil? && @copy.nil? && !version && !self.autodetect
234
236
 
@@ -1019,13 +1021,17 @@ module Squared
1019
1021
  end
1020
1022
 
1021
1023
  def ruby(*args, sync: true, banner: verbose?, with: nil, pass: PASS_RUBY[:ruby], **kwargs)
1022
- if args.first.is_a?(Symbol)
1023
- flag = args.shift
1024
- from = symjoin 'ruby', flag
1025
- end
1026
- opts = session_opts(with, args: args, kwargs: kwargs, pass: pass)
1027
- op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, strict: strict?,
1028
- multiple: [/^-e/], args: true, stdin: true)
1024
+ from = if args.first.is_a?(Symbol)
1025
+ flag = args.shift
1026
+ symjoin 'ruby', flag
1027
+ else
1028
+ :ruby
1029
+ end
1030
+ op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass),
1031
+ OPT_RUBY[:ruby],
1032
+ ruby_session,
1033
+ project: self, strict: strict?, auto: %w[help version],
1034
+ multiple: [/^-e/], args: true, stdin: true)
1029
1035
  if kwargs[:command]
1030
1036
  op << quote_option('e', kwargs[:command])
1031
1037
  elsif kwargs[:file]
@@ -1046,8 +1052,8 @@ module Squared
1046
1052
  op.append(delim: true, escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
1047
1053
  end
1048
1054
  end
1049
- print_run(op, banner, **kwargs) unless flag
1050
- run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: from || :ruby)
1055
+ print_run(op, banner, **kwargs) unless flag || op.stdout
1056
+ run(sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from: from)
1051
1057
  end
1052
1058
 
1053
1059
  def gem(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -1307,7 +1313,7 @@ module Squared
1307
1313
  end
1308
1314
  if dryrun? || kwargs[:filter]&.fetch(:dryrun, nil)
1309
1315
  print_item "> #{op}"
1310
- exit 0
1316
+ exit
1311
1317
  elsif !with && banner
1312
1318
  return run(from: from, interactive: ['Push', 'N', target || gemname])
1313
1319
  end
@@ -1430,7 +1436,7 @@ module Squared
1430
1436
  op.clear(errors: true) if gems
1431
1437
  print_run(op, banner, **kwargs)
1432
1438
  run(banner: banner && %w[q silent quiet no-verbose].none? { |s| op.include?(shell_option(s)) },
1433
- exception: kwargs.fetch(:exception, exception?), from: from)
1439
+ exception: exception?(**kwargs), from: from)
1434
1440
  end
1435
1441
 
1436
1442
  def bundle(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -1567,7 +1573,7 @@ module Squared
1567
1573
  op.clear
1568
1574
  end
1569
1575
  print_run(op, banner, **kwargs)
1570
- ret = run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?),
1576
+ ret = run(sync: sync, banner: banner, exception: exception?(**kwargs),
1571
1577
  from: symjoin('bundle', flag))
1572
1578
  success?(ret, banner, output)
1573
1579
  end
@@ -1580,7 +1586,7 @@ module Squared
1580
1586
  op.append(escape: true)
1581
1587
  print_run(op, banner, **kwargs)
1582
1588
  var = { 'BANNER' => '0' } unless banner
1583
- run(op, var, sync: sync, banner: false, exception: kwargs.fetch(:exception, exception?), from: :rake)
1589
+ run(op, var, sync: sync, banner: false, exception: exception?(**kwargs), from: :rake)
1584
1590
  end
1585
1591
 
1586
1592
  def irb(*args, banner: verbose?, with: nil, pass: PASS_RUBY[:irb], **kwargs)
@@ -1608,7 +1614,7 @@ module Squared
1608
1614
  op.concat(args)
1609
1615
  op.append(quote: false, delim: true)
1610
1616
  print_run(op, banner, **kwargs)
1611
- run(banner: false, exception: kwargs.fetch(:exception, exception?), from: :rdbg)
1617
+ run(banner: false, exception: exception?(**kwargs), from: :rdbg)
1612
1618
  end
1613
1619
 
1614
1620
  def rbs(flag, *args, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -1657,7 +1663,7 @@ module Squared
1657
1663
  op.clear
1658
1664
  .append(*args)
1659
1665
  print_run(op, banner, **kwargs)
1660
- run(banner: false, exception: kwargs.fetch(:exception, exception?), from: symjoin('rbs', flag))
1666
+ run(banner: false, exception: exception?(**kwargs), from: symjoin('rbs', flag))
1661
1667
  end
1662
1668
  end
1663
1669
 
@@ -1680,7 +1686,7 @@ module Squared
1680
1686
  op.append(delim: true)
1681
1687
  .clear(errors: true)
1682
1688
  print_run(op, banner, **kwargs)
1683
- run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :rubocop)
1689
+ run(sync: sync, banner: banner, exception: exception?(**kwargs), from: :rubocop)
1684
1690
  end
1685
1691
 
1686
1692
  def serve(root, *, bind: nil, port: 3000, **kwargs)
@@ -1871,7 +1877,7 @@ module Squared
1871
1877
  op.concat(args)
1872
1878
  op.append(delim: delim)
1873
1879
  print_run(op, banner, **kwargs)
1874
- run(banner: false, exception: kwargs.fetch(:exception, exception?), from: from)
1880
+ run(banner: false, exception: exception?(**kwargs), from: from)
1875
1881
  end
1876
1882
 
1877
1883
  def ruby_session(*cmd, **kwargs)
@@ -220,6 +220,7 @@ module Squared
220
220
  end
221
221
 
222
222
  attr_reader :target, :extras, :found, :errors, :values, :project, :path, :sep
223
+ attr_accessor :stdout
223
224
 
224
225
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
225
226
  :merge, :compact, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
@@ -242,14 +243,16 @@ module Squared
242
243
  @sep = sep
243
244
  @errors = []
244
245
  @found = []
246
+ @stdout = false
245
247
  parse(list, opts, **kwargs, &blk)
246
248
  end
247
249
 
248
250
  def parse(list, opts = extras, no: nil, single: nil, args: false, multiple: nil, first: nil, underscore: nil,
249
- explicit: false, bool: %w[true false], stdin: false, &blk)
251
+ explicit: false, bool: %w[true false], auto: [], stdin: false, &blk)
250
252
  @extras = []
251
253
  @values = []
252
254
  bare = []
255
+ auto = auto.flat_map { |val| val.split('|', 2) }
253
256
  e = []
254
257
  b = []
255
258
  m = []
@@ -351,6 +354,7 @@ module Squared
351
354
  tr = ->(a) { a.map { |val| val.tr('-', '_') } }
352
355
  @values.concat(tr.call(@values))
353
356
  bare.concat(tr.call(bare))
357
+ auto.concat(tr.call(auto))
354
358
  e.concat(tr.call(e))
355
359
  b.concat(tr.call(b))
356
360
  m.concat(tr.call(m))
@@ -364,6 +368,7 @@ module Squared
364
368
  ml.concat(tr.call(ml))
365
369
  no.concat(tr.call(no))
366
370
  end
371
+ bare.concat(auto)
367
372
  if target.is_a?(JoinSet)
368
373
  target.multiple = multiple if multiple
369
374
  target.multiple = ml.map { |val| val.size == 1 ? "-#{val}" : "--#{val}" }
@@ -396,6 +401,10 @@ module Squared
396
401
  add "#{sw[opt]}#{opt}"
397
402
  else
398
403
  add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
404
+ if auto.include?(opt)
405
+ @stdout = true
406
+ break
407
+ end
399
408
  end
400
409
  elsif opt.start_with?(/no[-_]/) && no.include?(s = opt[3..])
401
410
  add "--no-#{s}"
@@ -822,6 +831,10 @@ module Squared
822
831
  end
823
832
  end
824
833
 
834
+ def style?(*args)
835
+ !stdout && args.none?(&:!)
836
+ end
837
+
825
838
  def uniq!(list)
826
839
  list = uniq list
827
840
  return if list.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.9.0.pre1
4
+ version: 0.9.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  - !ruby/object:Gem::Version
143
143
  version: '0'
144
144
  requirements: []
145
- rubygems_version: 4.0.21
145
+ rubygems_version: 4.0.20
146
146
  specification_version: 4
147
147
  summary: Rake task generator for managing multi-language workspaces.
148
148
  test_files: []