squared 0.9.0.pre1 → 0.9.0
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 +4 -4
- data/CHANGELOG.md +37 -1
- data/README.md +22 -12
- data/exe/sqd +22 -11
- data/lib/squared/common/prompt.rb +5 -3
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +43 -20
- data/lib/squared/workspace/project/base.rb +21 -5
- data/lib/squared/workspace/project/docker.rb +1 -1
- data/lib/squared/workspace/project/git.rb +29 -24
- data/lib/squared/workspace/project/node.rb +80 -64
- data/lib/squared/workspace/project/python.rb +41 -37
- data/lib/squared/workspace/project/ruby.rb +37 -31
- data/lib/squared/workspace/project/support/class.rb +10 -10
- data/lib/squared/workspace/project/support/optionpartition.rb +14 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41f1d82942dcd7279ec182d1fc0bdc8f90ccc2e476860c6ca70bc89286417598
|
|
4
|
+
data.tar.gz: e6b7773f70fd0d2867fe13bdae57324dd6c90048c8bea3b27937738edf4df78c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cc02b93ac5fbfd34e23ff87cda66a3665fca3490c942e7a5942edb9ba6540eb6b95e1c87d8273444ec4bbac6d56841b7b3213295ce9ee856c15383794ecac97a
|
|
7
|
+
data.tar.gz: ee1c5b726339754ee878ff97cd9994983cbc5ca4822d2ffa25170c2f3512414966f367dcc5c4f0f2bc1eb8156667b88fcffc294ccbab1468c57ef465bb387243
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## [0.9.0] - 2026-10-12
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
6
|
|
|
@@ -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,8 @@
|
|
|
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.
|
|
39
|
+
- Python program meson prefix options use local path resolution.
|
|
37
40
|
|
|
38
41
|
### Removed
|
|
39
42
|
|
|
@@ -42,6 +45,35 @@
|
|
|
42
45
|
- Docker private method charname was replaced with subdomainname.
|
|
43
46
|
- Git command show was relocated into command git action show.
|
|
44
47
|
|
|
48
|
+
## [0.8.6] - 2026-10-01
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- Pip command options were updated to 26.2.
|
|
53
|
+
- Application method assign for appending project instance methods was created.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- Bundle exec wrapper did not accept boolean values.
|
|
58
|
+
- RuboCop did not resolve config to project directory.
|
|
59
|
+
|
|
60
|
+
## [0.7.13] - 2026-09-25
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- OptionPartition did not parse quoted option values.
|
|
65
|
+
|
|
66
|
+
## [0.6.20] - 2026-09-25
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- Prompt choice optional selection can be bypassed with a single dash.
|
|
71
|
+
- OptionPartition can parse supplementary option flags for plain output.
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- Git interactive commit selection did not accept additional values.
|
|
76
|
+
|
|
45
77
|
## [0.8.5] - 2026-09-23
|
|
46
78
|
|
|
47
79
|
### Added
|
|
@@ -2166,12 +2198,15 @@
|
|
|
2166
2198
|
|
|
2167
2199
|
- Changelog was created.
|
|
2168
2200
|
|
|
2201
|
+
[0.9.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.9.0
|
|
2202
|
+
[0.8.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.6
|
|
2169
2203
|
[0.8.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.5
|
|
2170
2204
|
[0.8.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.4
|
|
2171
2205
|
[0.8.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.3
|
|
2172
2206
|
[0.8.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.2
|
|
2173
2207
|
[0.8.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.1
|
|
2174
2208
|
[0.8.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.0
|
|
2209
|
+
[0.7.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.13
|
|
2175
2210
|
[0.7.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.12
|
|
2176
2211
|
[0.7.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.11
|
|
2177
2212
|
[0.7.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.10
|
|
@@ -2185,6 +2220,7 @@
|
|
|
2185
2220
|
[0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
|
|
2186
2221
|
[0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
|
|
2187
2222
|
[0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
|
|
2223
|
+
[0.6.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.20
|
|
2188
2224
|
[0.6.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.19
|
|
2189
2225
|
[0.6.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.18
|
|
2190
2226
|
[0.6.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.17
|
data/README.md
CHANGED
|
@@ -43,11 +43,12 @@ Usage: sqd [options] [rake options] [global...] [:targets...] -- [rake targets..
|
|
|
43
43
|
|
|
44
44
|
-s, --[no-]strict Do not run commands with invalid arguments
|
|
45
45
|
--update Use update strategy for applicable commands
|
|
46
|
+
--parallel STR,PAT Run standard tasks with multi-task threads
|
|
46
47
|
-F, --force [STR,STR] Enable force through ENV by application
|
|
47
48
|
-y, --yes [STR,STR] Enable auto-approve through ENV by application
|
|
48
49
|
-d, --dry-run Run commands without any modifying actions
|
|
49
50
|
|
|
50
|
-
-S, --select PAGE:CHOICE
|
|
51
|
+
-S, --select PAGE[:CHOICE] Prompt menu selection pagination display (e.g. 15:75)
|
|
51
52
|
|
|
52
53
|
-p, --pipe 0|1|2 Set file descriptor for communication
|
|
53
54
|
-o, --pipe-out FILE Write command data stream to a file
|
|
@@ -132,13 +133,13 @@ Workspace::Application
|
|
|
132
133
|
apply :clean, ["build/sqd/"] # variable_set (alias)
|
|
133
134
|
end
|
|
134
135
|
.with(:docker, only: ["build", "compose"], hide: [:windows?]) do # When true hide entire group
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
add("squared", "docker", file: "Dockerfile", tag: "latest",
|
|
137
|
+
registry: "localhost:5000", username: "squared", # compose publish => { oci: "oci://docker.io" }
|
|
138
|
+
args: "--ssh=default",
|
|
139
|
+
context: ".", # Optional
|
|
140
|
+
client: { config: '/home/user/.docker', tls: true }, # global options
|
|
141
|
+
secrets: ["id=github,env=GITHUB_TOKEN"],
|
|
142
|
+
mounts: ["src=.,dst=/project,ro,bind-propagation=rshared"]) do
|
|
142
143
|
series(:clean) do # run | depend | doc | lint | test | copy | clean
|
|
143
144
|
File.read(basepath("docker-bake.hcl"))
|
|
144
145
|
.scan(/\btags\s+=\s+\["([^"]+)"\]/)
|
|
@@ -146,6 +147,15 @@ Workspace::Application
|
|
|
146
147
|
end
|
|
147
148
|
end
|
|
148
149
|
end
|
|
150
|
+
.assign(:ruby) do # Add or override instance methods
|
|
151
|
+
def vmname(bin: false)
|
|
152
|
+
bin ? ['rbenv', '/usr/bin/rbenv'] : 'rbenv'
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def copy?
|
|
156
|
+
false
|
|
157
|
+
end
|
|
158
|
+
end
|
|
149
159
|
.pass("pull", group: "default") { test? || doc? } # rake pathname:pull optparse:pull
|
|
150
160
|
.style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
|
|
151
161
|
.build(default: "build", parallel: ["pull", "fetch", "rebase", "archive", "clean", /^outdated:/], pass: ["publish"]) do |workspace|
|
|
@@ -388,10 +398,10 @@ Workspace::Application
|
|
|
388
398
|
run([nil, "build:dev", { "PATH" => "~/.bin" }, "--workspace", "--silent"]) # PATH="~/.bin" npm run build:dev --workspace -- --silent
|
|
389
399
|
# OR
|
|
390
400
|
run({
|
|
391
|
-
script: "build:dev",
|
|
392
|
-
env: { "PATH" => "~/.bin" },
|
|
393
|
-
opts: "--workspace",
|
|
394
|
-
args: "--silent"
|
|
401
|
+
script: "build:dev",
|
|
402
|
+
env: { "PATH" => "~/.bin" },
|
|
403
|
+
opts: "--workspace",
|
|
404
|
+
args: "--silent"
|
|
395
405
|
})
|
|
396
406
|
|
|
397
407
|
add("e-mc", "emc") do
|
data/exe/sqd
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
$:.unshift(File.expand_path('../lib', __dir__)) if File.exist?(File.expand_path('../squared.gemspec', __dir__))
|
|
5
|
-
|
|
6
4
|
require 'squared'
|
|
7
5
|
require 'rake'
|
|
8
6
|
require 'optparse'
|
|
@@ -103,6 +101,18 @@ class SqdParser < OptionParser
|
|
|
103
101
|
ARGV[index] = ''
|
|
104
102
|
end
|
|
105
103
|
end
|
|
104
|
+
if options[:parallel]
|
|
105
|
+
pattern, parallel = options[:parallel].partition do |val|
|
|
106
|
+
next false if val.match?(%r{^[\w~`!@#%&\-=:;"'<>/]+$})
|
|
107
|
+
|
|
108
|
+
Regexp.new(val)
|
|
109
|
+
rescue RegexpError
|
|
110
|
+
false
|
|
111
|
+
end
|
|
112
|
+
session = Squared::Common::ARG
|
|
113
|
+
session[:APP][:build_pattern] = pattern.map { |pat| Regexp.new(pat) } unless pattern.empty?
|
|
114
|
+
session[:APP][:build_parallel] = parallel unless parallel.empty?
|
|
115
|
+
end
|
|
106
116
|
ARGV.reject!(&:empty?)
|
|
107
117
|
Rake.application.run(global.concat(ARGV))
|
|
108
118
|
end
|
|
@@ -112,7 +122,7 @@ class SqdParser < OptionParser
|
|
|
112
122
|
end
|
|
113
123
|
|
|
114
124
|
def error_exit(*val, hint)
|
|
115
|
-
raise OptionParser::InvalidArgument, message(*val, hint: hint)
|
|
125
|
+
raise OptionParser::InvalidArgument, message(*val, hint: hint), caller(1)
|
|
116
126
|
end
|
|
117
127
|
end
|
|
118
128
|
|
|
@@ -134,7 +144,6 @@ SqdParser.new do |sqd|
|
|
|
134
144
|
end
|
|
135
145
|
sqd.on('-e', '--project-env KEY=STR', 'Provide command ENV variables for :targets (multiple)') do |val|
|
|
136
146
|
sqd.error_exit('missing value', "#{val}=") unless val.include?('=')
|
|
137
|
-
|
|
138
147
|
sqd.options[:'project-env'] << val
|
|
139
148
|
end
|
|
140
149
|
sqd.separator ''
|
|
@@ -145,6 +154,7 @@ SqdParser.new do |sqd|
|
|
|
145
154
|
sqd.on('--update', 'Use update strategy for applicable commands') do
|
|
146
155
|
ENV['UPDATE'] = 'true'
|
|
147
156
|
end
|
|
157
|
+
sqd.on('--parallel STR,PAT', Array, 'Run standard tasks with multi-task threads')
|
|
148
158
|
sqd.on('-F', '--force [STR,STR]', Array, 'Enable force through ENV by application') do |val|
|
|
149
159
|
sqd.parse_common(val, session: session, arg: :FORCE)
|
|
150
160
|
end
|
|
@@ -155,10 +165,9 @@ SqdParser.new do |sqd|
|
|
|
155
165
|
ENV['DRY_RUN'] = 'true'
|
|
156
166
|
end
|
|
157
167
|
sqd.separator ''
|
|
158
|
-
sqd.on('-S', '--select PAGE:CHOICE', 'Prompt menu selection pagination
|
|
168
|
+
sqd.on('-S', '--select PAGE[:CHOICE]', 'Prompt menu selection pagination display (e.g. 15:75)') do |val|
|
|
159
169
|
page, choice = val.split(/\D/, 2).map(&:to_i)
|
|
160
170
|
sqd.error_exit('not an integer', val) if choice.nil? ? page == 0 : choice == 0
|
|
161
|
-
|
|
162
171
|
session[:PAGE] = page if page > 0
|
|
163
172
|
session[:CHOICE] = choice if choice.to_i > 0
|
|
164
173
|
ENV['SELECT'] = "#{page}:#{choice}"
|
|
@@ -166,17 +175,14 @@ SqdParser.new do |sqd|
|
|
|
166
175
|
sqd.separator ''
|
|
167
176
|
sqd.on('-p', '--pipe 0|1|2', Integer, 'Set file descriptor for communication') do |val|
|
|
168
177
|
sqd.error_exit('out of range', val) unless val.between?(0, 2)
|
|
169
|
-
|
|
170
178
|
session[:PIPE] = val
|
|
171
179
|
end
|
|
172
180
|
sqd.on('-o', '--pipe-out FILE', 'Write command data stream to a file') do |val|
|
|
173
181
|
sqd.error_exit("missing an explicit \".#{File::SEPARATOR}\"", val) unless val.include?(File::SEPARATOR)
|
|
174
|
-
|
|
175
182
|
session[:OUT] = val
|
|
176
183
|
end
|
|
177
184
|
sqd.on('--fail 0..4', Integer, 'Set application exception level') do |val|
|
|
178
185
|
sqd.error_exit('out of range', val) unless val.between?(0, 4)
|
|
179
|
-
|
|
180
186
|
session[:FAIL] = val
|
|
181
187
|
end
|
|
182
188
|
%i[debug info warn error fatal].then do |state|
|
|
@@ -216,9 +222,14 @@ SqdParser.new do |sqd|
|
|
|
216
222
|
end
|
|
217
223
|
sqd.on('--version', 'Print the current version') do
|
|
218
224
|
puts Squared::VERSION
|
|
219
|
-
exit
|
|
225
|
+
exit
|
|
220
226
|
end
|
|
221
227
|
sqd.on('-h', '--help', 'Print the command line options') do
|
|
222
|
-
sqd.help_exit
|
|
228
|
+
if defined?(sqd.help_exit)
|
|
229
|
+
sqd.help_exit
|
|
230
|
+
else
|
|
231
|
+
puts sqd.help
|
|
232
|
+
exit
|
|
233
|
+
end
|
|
223
234
|
end
|
|
224
235
|
end.run
|
|
@@ -42,7 +42,7 @@ module Squared
|
|
|
42
42
|
end
|
|
43
43
|
rescue Interrupt
|
|
44
44
|
puts
|
|
45
|
-
exit
|
|
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
|
|
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
|
|
166
|
+
exit
|
|
165
167
|
else
|
|
166
168
|
[] if multiple
|
|
167
169
|
end
|
data/lib/squared/version.rb
CHANGED
|
@@ -163,9 +163,10 @@ module Squared
|
|
|
163
163
|
end
|
|
164
164
|
@pass.items.concat(kwargs[:pass].map { |val| val.is_a?(Regexp) ? val : val.to_s }) if kwargs[:pass]
|
|
165
165
|
@series = Application.register(self, @base.to_a, exclude: kwargs.fetch(:exclude, []))
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
app = ARG[:APP]
|
|
167
|
+
@series.ref_min = app[:series_ref_min] if app.key?(:series_ref_min)
|
|
168
|
+
kwargs[:pattern].concat(app[:build_pattern]) if app.key?(:build_pattern)
|
|
169
|
+
kwargs[:parallel].concat(app[:build_parallel]) if app.key?(:build_parallel)
|
|
169
170
|
self.closed = 'begin'
|
|
170
171
|
pb = @stage.key?('project:begin')
|
|
171
172
|
pe = @stage.key?('project:end')
|
|
@@ -406,7 +407,7 @@ module Squared
|
|
|
406
407
|
end
|
|
407
408
|
unless ref.is_a?(Symbol) && (proj = @base.find { |item| item.ref == ref })
|
|
408
409
|
proj = if !ref.is_a?(Class)
|
|
409
|
-
|
|
410
|
+
find_project(ref: ref, path: path)
|
|
410
411
|
elsif Application.extends(ref)
|
|
411
412
|
ref
|
|
412
413
|
end || @kind[name]&.last
|
|
@@ -454,6 +455,16 @@ module Squared
|
|
|
454
455
|
self
|
|
455
456
|
end
|
|
456
457
|
|
|
458
|
+
def assign(ref = @ref, &blk)
|
|
459
|
+
proj = ref && find_project(ref: ref)
|
|
460
|
+
if proj
|
|
461
|
+
proj.class_eval(&blk)
|
|
462
|
+
else
|
|
463
|
+
warn log_message(Logger::ERROR, 'class not found', subject: main, hint: ref)
|
|
464
|
+
end
|
|
465
|
+
self
|
|
466
|
+
end
|
|
467
|
+
|
|
457
468
|
def stage(val, first: false, &blk)
|
|
458
469
|
data = @stage[val]
|
|
459
470
|
if first == true
|
|
@@ -481,7 +492,7 @@ module Squared
|
|
|
481
492
|
obj = begin
|
|
482
493
|
JSON.parse(homepath(obj).read, { symbolize_names: true })
|
|
483
494
|
rescue => e
|
|
484
|
-
warn log_message(Logger::ERROR, e)
|
|
495
|
+
warn log_message(Logger::ERROR, e, subject: main)
|
|
485
496
|
end
|
|
486
497
|
end
|
|
487
498
|
apply_style(data || theme, obj, args, empty: empty) if obj && (!target || data)
|
|
@@ -642,16 +653,24 @@ module Squared
|
|
|
642
653
|
val = val.split(':') if val.is_a?(String)
|
|
643
654
|
if before || after || opts
|
|
644
655
|
pos = []
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
656
|
+
append = lambda do |data|
|
|
657
|
+
pos << case data
|
|
658
|
+
when Array
|
|
659
|
+
data.join(',')
|
|
660
|
+
when Hash
|
|
661
|
+
data.keys.join('|')
|
|
649
662
|
else
|
|
650
|
-
|
|
663
|
+
data
|
|
651
664
|
end
|
|
652
665
|
end
|
|
653
|
-
|
|
654
|
-
|
|
666
|
+
append.call(before)
|
|
667
|
+
pos << if opts.is_a?(Array)
|
|
668
|
+
arg ? "#{arg}=#{opts.join(',')}" : opts.join('|')
|
|
669
|
+
else
|
|
670
|
+
opts
|
|
671
|
+
end
|
|
672
|
+
append.call(after)
|
|
673
|
+
val << "#{val.pop}[#{pos.compact.join(',')}]"
|
|
655
674
|
end
|
|
656
675
|
out ? message(*val) : task_desc(*val)
|
|
657
676
|
end
|
|
@@ -707,12 +726,12 @@ module Squared
|
|
|
707
726
|
!@extensions.empty? || any? { |proj| proj.enabled?(base: false) }
|
|
708
727
|
end
|
|
709
728
|
|
|
710
|
-
def task_base?(
|
|
711
|
-
series.base?(
|
|
729
|
+
def task_base?(...)
|
|
730
|
+
series.base?(...)
|
|
712
731
|
end
|
|
713
732
|
|
|
714
|
-
def task_extend?(
|
|
715
|
-
series.extend?(
|
|
733
|
+
def task_extend?(...)
|
|
734
|
+
series.extend?(...)
|
|
716
735
|
end
|
|
717
736
|
|
|
718
737
|
def task_include?(obj, key, ref: nil)
|
|
@@ -748,12 +767,12 @@ module Squared
|
|
|
748
767
|
!!find(home)&.enabled?
|
|
749
768
|
end
|
|
750
769
|
|
|
751
|
-
def rootpath(
|
|
752
|
-
root.join(
|
|
770
|
+
def rootpath(...)
|
|
771
|
+
root.join(...)
|
|
753
772
|
end
|
|
754
773
|
|
|
755
|
-
def homepath(
|
|
756
|
-
home.join(
|
|
774
|
+
def homepath(...)
|
|
775
|
+
home.join(...)
|
|
757
776
|
end
|
|
758
777
|
|
|
759
778
|
def pwd
|
|
@@ -1091,6 +1110,10 @@ module Squared
|
|
|
1091
1110
|
nil
|
|
1092
1111
|
end
|
|
1093
1112
|
|
|
1113
|
+
def find_project(ref:, path: nil)
|
|
1114
|
+
require_project(ref) || Application.find(ref: ref, path: path)
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1094
1117
|
def root?(path, pass: [])
|
|
1095
1118
|
return false unless path.directory?
|
|
1096
1119
|
|
|
@@ -1139,8 +1139,8 @@ module Squared
|
|
|
1139
1139
|
@ref.reverse_each(&blk)
|
|
1140
1140
|
end
|
|
1141
1141
|
|
|
1142
|
-
def basepath(
|
|
1143
|
-
path.join(
|
|
1142
|
+
def basepath(...)
|
|
1143
|
+
path.join(...)
|
|
1144
1144
|
end
|
|
1145
1145
|
|
|
1146
1146
|
def basepath!(*args, type: nil)
|
|
@@ -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
|
-
|
|
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:
|
|
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
|
|
|
@@ -182,7 +182,7 @@ module Squared
|
|
|
182
182
|
if flags.nil?
|
|
183
183
|
case action
|
|
184
184
|
when 'ls'
|
|
185
|
-
format_desc(action, nil,
|
|
185
|
+
format_desc(action, nil, 'a/ll?,s/tandard?,range*', before: VAL_DOCKER[:ls])
|
|
186
186
|
task action, [:command] do |_, args|
|
|
187
187
|
command = param_guard(action, 'command', args: args, key: :command)
|
|
188
188
|
args = args.extras
|
|
@@ -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:
|
|
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
|
-
|
|
667
|
-
|
|
668
|
-
diff(flag, refs:
|
|
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
|
-
|
|
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,14 +1071,13 @@ 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:
|
|
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])
|
|
1078
1078
|
end
|
|
1079
1079
|
else
|
|
1080
|
-
format_desc
|
|
1080
|
+
format_desc(action, flag, 'opts*', before: OPT_GIT[:remote])
|
|
1081
1081
|
task flag, [:command] do |_, args|
|
|
1082
1082
|
command = param_guard(action, flag, args: args, key: :command)
|
|
1083
1083
|
cmd, opts = git_session('remote', opts: args.extras)
|
|
@@ -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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 ||=
|
|
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
|
|
@@ -1840,7 +1840,7 @@ module Squared
|
|
|
1840
1840
|
if adding.empty? && !cached.empty? && banner?
|
|
1841
1841
|
puts(cached.lines(chomp: true).map { |val| "cached #{shell_quote(val)}" })
|
|
1842
1842
|
end
|
|
1843
|
-
ENV['COMMIT_PUSH'] =
|
|
1843
|
+
ENV['COMMIT_PUSH'] = git_value 'rev-parse --verify HEAD' if source(co) && source(pu) && !dryrun?
|
|
1844
1844
|
else
|
|
1845
1845
|
if banner?
|
|
1846
1846
|
puts 'Nothing to commit'
|
|
@@ -1946,7 +1946,8 @@ module Squared
|
|
|
1946
1946
|
list_result(ret, 'branches', banner: banner, from: from)
|
|
1947
1947
|
return
|
|
1948
1948
|
else
|
|
1949
|
-
|
|
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
|
|
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|
|