squared 0.4.11 → 0.4.13
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 +76 -0
- data/README.md +3 -3
- data/README.ruby.md +68 -11
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/format.rb +8 -5
- data/lib/squared/common/shell.rb +14 -14
- data/lib/squared/common/system.rb +2 -2
- data/lib/squared/common/utils.rb +4 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +154 -5
- data/lib/squared/workspace/project/base.rb +327 -161
- data/lib/squared/workspace/project/docker.rb +87 -47
- data/lib/squared/workspace/project/git.rb +62 -52
- data/lib/squared/workspace/project/node.rb +111 -59
- data/lib/squared/workspace/project/python.rb +143 -104
- data/lib/squared/workspace/project/ruby.rb +33 -22
- data/lib/squared/workspace/project/support/class.rb +6 -6
- data/lib/squared/workspace/project.rb +2 -7
- data/lib/squared/workspace/series.rb +34 -0
- data/lib/squared/workspace/support/data.rb +10 -0
- data/lib/squared/workspace/support.rb +3 -0
- data/lib/squared/workspace.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bc10e49a42c1eda78b4ff20f734efffd74eda16bc8dae742d2a0f29c0f34851
|
4
|
+
data.tar.gz: 64b5e88317ba5208cc7824f40b9a4ff810a63197bc0b27813906a2293bbe1388
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f34a4d13854343d0713e34bf964feda5206f1c9a60ec2781fca611e74f7257753e01a895e081663b0c2d154a4c4834c39fa478e4665c58982eea053b53fd9529
|
7
|
+
data.tar.gz: ff549d38162731add0bbb6dd8bd7566f2200d6006f92c268aa0af4271e4f6a60a5a407b6a3a48fbeeee035c0ede41c135f760eb907582ede90020a1c61c7d890
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,76 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.4.13] - 2025-06-16
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Docker command image action tag was implemented.
|
8
|
+
- Docker command image action save was implemented.
|
9
|
+
- Docker command container action create was implemented.
|
10
|
+
- Node command exec with NPM and PNPM were implemented.
|
11
|
+
- Ruby command exec and config are interactive.
|
12
|
+
- Python command exec using Kernel.exec was implemented.
|
13
|
+
- Theme color "latest" for semver was created.
|
14
|
+
- Project can be sorted by graph using comparison operator.
|
15
|
+
- Project base command prereqs was created.
|
16
|
+
- Project setter methods for private variables with validation.
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- Mismatched shell quoted options are fixed rather than wrapped.
|
21
|
+
- Python command venv action run was renamed exec.
|
22
|
+
- Ruby command file can accept a glob file pattern.
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
|
26
|
+
- Shell option quote detection uses Regexp conditionals.
|
27
|
+
- Docker property registry did not detect nil values.
|
28
|
+
- Gem command exec did not include gem option flag.
|
29
|
+
- Project method variable_set did not call block.
|
30
|
+
- Project output divider was not printed when not verbose.
|
31
|
+
|
32
|
+
## [0.4.12] - 2025-05-18
|
33
|
+
|
34
|
+
### Added
|
35
|
+
|
36
|
+
- Git command stash with actions using index are interactive.
|
37
|
+
- Project tasks can be pipelined in separate thread groups.
|
38
|
+
- Global tasks can be pipelined with project tasks.
|
39
|
+
- Python venv module supports initialization options.
|
40
|
+
|
41
|
+
### Changed
|
42
|
+
|
43
|
+
- Node command run parses recognized options per package manager.
|
44
|
+
- Project unpack uses merge with multiple headers.
|
45
|
+
- Invalid log directory does not abort program.
|
46
|
+
- Project accessor line_width was replaced with Rake equivalent.
|
47
|
+
|
48
|
+
### Fixed
|
49
|
+
|
50
|
+
- Git pull option multiple was not detected.
|
51
|
+
- Git output used undefined method when displaying results.
|
52
|
+
- Workspace did not add prefix to duplicate project names.
|
53
|
+
|
54
|
+
## [0.3.11] - 2025-05-15
|
55
|
+
|
56
|
+
- See `0.2.11`.
|
57
|
+
|
58
|
+
## [0.2.11] - 2025-05-15
|
59
|
+
|
60
|
+
### Fixed
|
61
|
+
|
62
|
+
- Disabled batch and alias tasks were not hidden.
|
63
|
+
- Workspace git did not parse multiple download URIs.
|
64
|
+
|
65
|
+
## [0.1.8] - 2025-05-15
|
66
|
+
|
67
|
+
### Fixed
|
68
|
+
|
69
|
+
- Disabled batch and alias tasks were not hidden.
|
70
|
+
- Log messages were written to terminal twice when emphasized.
|
71
|
+
- Node outdated interactive for major would sometimes deactivate.
|
72
|
+
- Node outdated interactive for major was mislabeled as minor.
|
73
|
+
|
3
74
|
## [0.4.11] - 2025-05-09
|
4
75
|
|
5
76
|
### Added
|
@@ -665,6 +736,8 @@
|
|
665
736
|
|
666
737
|
- Changelog was created.
|
667
738
|
|
739
|
+
[0.4.13]: https://github.com/anpham6/squared/releases/tag/v0.4.13-ruby
|
740
|
+
[0.4.12]: https://github.com/anpham6/squared/releases/tag/v0.4.12-ruby
|
668
741
|
[0.4.11]: https://github.com/anpham6/squared/releases/tag/v0.4.11-ruby
|
669
742
|
[0.4.10]: https://github.com/anpham6/squared/releases/tag/v0.4.10-ruby
|
670
743
|
[0.4.9]: https://github.com/anpham6/squared/releases/tag/v0.4.9-ruby
|
@@ -677,6 +750,7 @@
|
|
677
750
|
[0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
|
678
751
|
[0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
|
679
752
|
[0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
|
753
|
+
[0.3.11]: https://github.com/anpham6/squared/releases/tag/v0.3.11-ruby
|
680
754
|
[0.3.10]: https://github.com/anpham6/squared/releases/tag/v0.3.10-ruby
|
681
755
|
[0.3.9]: https://github.com/anpham6/squared/releases/tag/v0.3.9-ruby
|
682
756
|
[0.3.8]: https://github.com/anpham6/squared/releases/tag/v0.3.8-ruby
|
@@ -688,6 +762,7 @@
|
|
688
762
|
[0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
|
689
763
|
[0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
|
690
764
|
[0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
|
765
|
+
[0.2.11]: https://github.com/anpham6/squared/releases/tag/v0.2.11-ruby
|
691
766
|
[0.2.10]: https://github.com/anpham6/squared/releases/tag/v0.2.10-ruby
|
692
767
|
[0.2.9]: https://github.com/anpham6/squared/releases/tag/v0.2.9-ruby
|
693
768
|
[0.2.8]: https://github.com/anpham6/squared/releases/tag/v0.2.8-ruby
|
@@ -699,6 +774,7 @@
|
|
699
774
|
[0.2.2]: https://github.com/anpham6/squared/releases/tag/v0.2.2-ruby
|
700
775
|
[0.2.1]: https://github.com/anpham6/squared/releases/tag/v0.2.1-ruby
|
701
776
|
[0.2.0]: https://github.com/anpham6/squared/releases/tag/v0.2.0-ruby
|
777
|
+
[0.1.8]: https://github.com/anpham6/squared/releases/tag/v0.1.8-ruby
|
702
778
|
[0.1.7]: https://github.com/anpham6/squared/releases/tag/v0.1.7-ruby
|
703
779
|
[0.1.6]: https://github.com/anpham6/squared/releases/tag/v0.1.6-ruby
|
704
780
|
[0.1.5]: https://github.com/anpham6/squared/releases/tag/v0.1.5-ruby
|
data/README.md
CHANGED
@@ -140,13 +140,13 @@ rake clone # node + docs
|
|
140
140
|
# PIPE_FAIL={0,1}
|
141
141
|
# PORT=3000
|
142
142
|
docker build -t squared --build-arg MANIFEST=prod --build-arg NODE_ENV=production .
|
143
|
-
docker build -t node --build-arg NODE_TAG=22 --build-arg NODE_INSTALL=pnpm -f Dockerfile
|
143
|
+
docker build -t node --build-arg NODE_TAG=22 --build-arg NODE_INSTALL=pnpm -f slim.Dockerfile .
|
144
144
|
NODE=22 docker buildx bake node
|
145
145
|
# OR
|
146
|
-
docker build -t ruby --build-arg RUBY_TAG=3.4.0 --build-arg NODE_VERSION=22 --build-arg PIPE_FAIL=0 -f Dockerfile
|
146
|
+
docker build -t ruby --build-arg RUBY_TAG=3.4.0 --build-arg NODE_VERSION=22 --build-arg PIPE_FAIL=0 -f ruby.Dockerfile .
|
147
147
|
RUBY=3.4.0 docker buildx bake ruby
|
148
148
|
# OR
|
149
|
-
docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=20 -f Dockerfile
|
149
|
+
docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=20 -f nginx.Dockerfile .
|
150
150
|
NGINX=1.27 docker buildx bake nginx
|
151
151
|
|
152
152
|
# Express
|
data/README.ruby.md
CHANGED
@@ -234,17 +234,74 @@ Workspace::Application
|
|
234
234
|
.build(parallel: ["clone"]) # rake clone + rake clone:sync
|
235
235
|
```
|
236
236
|
|
237
|
-
###
|
237
|
+
### Build
|
238
|
+
|
239
|
+
#### Chain
|
240
|
+
|
241
|
+
There has to be at least one project which uses the ``step`` attribute. Other placement attributes are ignored.
|
242
|
+
|
243
|
+
**NOTE**: Projects can only reference non-global namespaced tasks. (e.g. with ":")
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
Workspace::Application
|
247
|
+
.new
|
248
|
+
.with(:node) do
|
249
|
+
add("e-mc", "emc") do
|
250
|
+
chain "all", "clean", step: 1 # Required
|
251
|
+
chain "all", "build", step: 2
|
252
|
+
end
|
253
|
+
add("pi-r", "pir") do
|
254
|
+
chain "all", "build", after: "emc:build" # step: 3
|
255
|
+
end
|
256
|
+
add("pi-r2", "pir2") do
|
257
|
+
chain "all", "build", before: "squared" # step: 3
|
258
|
+
end
|
259
|
+
add("squared-express", "express") do
|
260
|
+
chain "all", "clean", with: "emc" # step: 1
|
261
|
+
chain "all", "build", with: "pir" # step: 3
|
262
|
+
end
|
263
|
+
add("squared") do
|
264
|
+
revbuild(include: %w[src/ framework/ types/]) # Git revision build command (optional)
|
265
|
+
chain "all", "revbuild", after: "express:build" # step: 4
|
266
|
+
chain "publish", "bump:patch", "publish:latest", step: 0, sync: true # rake publish -> squared:bump:patch -> squared:publish:latest
|
267
|
+
end
|
268
|
+
end
|
269
|
+
.with(:python) do
|
270
|
+
doc("make html")
|
271
|
+
add("android-docs") do
|
272
|
+
chain "all", "doc", with: "squared", after: "squared" # step: 4
|
273
|
+
end
|
274
|
+
add("chrome-docs") do
|
275
|
+
chain "all", "doc", with: "squared", before: "squared:revbuild" # Same
|
276
|
+
end
|
277
|
+
end
|
278
|
+
.chain "all", "status", with: "squared", after: "android-docs" # Global tasks (e.g. without ":")
|
279
|
+
.build
|
280
|
+
```
|
281
|
+
|
282
|
+
```sh
|
283
|
+
rake all # all[1-3-4]
|
284
|
+
rake all:print
|
285
|
+
```
|
286
|
+
|
287
|
+
Threaded is the default when there are two or more tasks. Using ``with`` and either **before** or **after** will create a synchronous group.
|
288
|
+
|
289
|
+
* Step 1: emc:clean + express:clean (thread)
|
290
|
+
* Step 2: emc:build (sync)
|
291
|
+
* Step 3: pir:build + express:build + pir2:build (thread)
|
292
|
+
* Step 4: chrome-docs:doc + squared:revbuild + android-docs:doc + status (sync)
|
293
|
+
|
294
|
+
#### Graph
|
238
295
|
|
239
296
|
```ruby
|
240
297
|
Workspace::Application
|
241
298
|
.new(main: "squared")
|
242
|
-
.graph(["depend"], ref: :git)
|
299
|
+
.graph(["depend"], ref: :git) # Optional
|
243
300
|
.with(:python) do
|
244
301
|
doc(windows? ? ".\make.bat html" : "make html") # rake android-docs:doc | rake doc:python
|
245
302
|
add("android-docs", "android", venv: "/home/user/.venv") # rake android-docs:depend
|
246
|
-
add("chrome-docs", "chrome", graph: "android", venv:
|
247
|
-
variable_set :dependindex,
|
303
|
+
add("chrome-docs", "chrome", graph: "android", venv: %w[.venv --clear]) do # /workspaces/chrome-docs/.venv
|
304
|
+
variable_set :dependindex, 1 # Use Poetry for dependencies (optional)
|
248
305
|
end
|
249
306
|
end
|
250
307
|
.with(:node) do
|
@@ -344,18 +401,14 @@ rake squared:graph:run[express,pir] # emc + pir + express + squared
|
|
344
401
|
rake squared:graph:run[node,-emc] # pir + express + squared
|
345
402
|
```
|
346
403
|
|
347
|
-
###
|
404
|
+
### Tasks
|
348
405
|
|
349
406
|
```ruby
|
350
407
|
Workspace::Series.batch(:ruby, :node, {
|
351
408
|
stage: %i[graph test],
|
352
409
|
reset: %i[stash pull]
|
353
410
|
})
|
354
|
-
```
|
355
411
|
|
356
|
-
### Rename
|
357
|
-
|
358
|
-
```ruby
|
359
412
|
Workspace::Series.rename("depend", "install")
|
360
413
|
```
|
361
414
|
|
@@ -423,9 +476,11 @@ Non-task:
|
|
423
476
|
* active
|
424
477
|
* inline
|
425
478
|
* subject
|
479
|
+
* border
|
426
480
|
* warn
|
427
481
|
* caution
|
428
482
|
* current
|
483
|
+
* latest
|
429
484
|
* extra
|
430
485
|
* major
|
431
486
|
* red
|
@@ -541,6 +596,9 @@ BANNER_${NAME}=0 #
|
|
541
596
|
|
542
597
|
REVBUILD_FORCE=1 # Rebuild all targets
|
543
598
|
REVBUILD_FORCE_${NAME}=1 # Rebuild project
|
599
|
+
|
600
|
+
PREREQS_${NAME}=build,copy # Class method name to invoke
|
601
|
+
PREREQS_${REF}=depend # e.g. Node
|
544
602
|
```
|
545
603
|
|
546
604
|
### Graph
|
@@ -561,7 +619,6 @@ LOG_AUTO # year,y,month,m,day,d,1
|
|
561
619
|
# Optional
|
562
620
|
LOG_DIR # exist?
|
563
621
|
LOG_LEVEL # See gem "logger"
|
564
|
-
LOG_COLUMNS # terminal width (default: 80)
|
565
622
|
```
|
566
623
|
|
567
624
|
### Git
|
@@ -584,7 +641,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
|
|
584
641
|
| checkout | track | COUNT=n |
|
585
642
|
| checkout | global path | HEAD=s PATHSPEC=s |
|
586
643
|
| checkout | * | FORCE MERGE |
|
587
|
-
| clone | * | DEPTH=n ORIGIN=s BRANCH=s LOCAL=0,1
|
644
|
+
| clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s LOCAL=0,1 |
|
588
645
|
| commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
|
589
646
|
| diff | -between -contain | MERGE_BASE |
|
590
647
|
| diff | head branch | INDEX=n |
|
data/lib/squared/common/base.rb
CHANGED
@@ -167,7 +167,7 @@ module Squared
|
|
167
167
|
color ? sub_style(ret, *styles) : ret
|
168
168
|
end
|
169
169
|
|
170
|
-
def log_message(level, *args, subject: nil, hint: nil,
|
170
|
+
def log_message(level, *args, subject: nil, hint: nil, append: true, pass: false, color: ARG[:COLOR])
|
171
171
|
args = args.map(&:to_s)
|
172
172
|
if level.is_a?(::Numeric)
|
173
173
|
if append && respond_to?(:log)
|
@@ -176,10 +176,10 @@ module Squared
|
|
176
176
|
end
|
177
177
|
return false if !pass && level < ARG[:LEVEL]
|
178
178
|
end
|
179
|
-
if args.size > 1 && !hint
|
179
|
+
if (args.size > 1 && !hint) || hint == false
|
180
180
|
title = log_title(level, color: false)
|
181
|
-
sub =
|
182
|
-
emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
|
181
|
+
sub = [pat: /\A(#{Regexp.escape(title)})(.*)\z/m, styles: __get__(:theme)[:logger][log_sym(level)]] if color
|
182
|
+
emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub, pipe: -1)
|
183
183
|
else
|
184
184
|
msg = [log_title(level, color: color)]
|
185
185
|
msg << (color ? sub_style(subject, styles: (@theme && @theme[:subject]) || :bold) : subject) if subject
|
@@ -211,7 +211,8 @@ module Squared
|
|
211
211
|
(empty ? args.reject { |val| val.nil? || val.empty? } : args).join(space) + (hint ? " (#{hint})" : '')
|
212
212
|
end
|
213
213
|
|
214
|
-
def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil,
|
214
|
+
def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
|
215
|
+
border: @theme && @theme[:border])
|
215
216
|
n = 0
|
216
217
|
max = ->(v) { n = [n, v.max_by(&:size).size].max }
|
217
218
|
set = lambda do |v|
|
@@ -271,6 +272,8 @@ module Squared
|
|
271
272
|
yield out
|
272
273
|
elsif pipe
|
273
274
|
case pipe
|
275
|
+
when -1
|
276
|
+
return out
|
274
277
|
when 0
|
275
278
|
pipe = $stdin
|
276
279
|
when 2
|
data/lib/squared/common/shell.rb
CHANGED
@@ -9,23 +9,23 @@ module Squared
|
|
9
9
|
module_function
|
10
10
|
|
11
11
|
def shell_escape(val, quote: false, force: false, double: false, option: false, override: false)
|
12
|
-
if (r = /\A(--?)([^= ]+)((=|\s+)(["'])?(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
r[2] = $2
|
19
|
-
override = true
|
20
|
-
end
|
21
|
-
r[1] + r[2] + r[4] + shell_quote(opt, double: double, force: force, override: override)
|
12
|
+
if (r = /\A(--?)([^= ]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
|
13
|
+
if (data = r[2].match(/\A(["'])(.+)\1\z/))
|
14
|
+
double = data[1] == '"'
|
15
|
+
override = true
|
16
|
+
elsif !r[3] || r[6]
|
17
|
+
return val
|
22
18
|
end
|
23
|
-
if r[
|
24
|
-
r[
|
19
|
+
if r[7].match?(/\A["']/)
|
20
|
+
opt = "#{r[7]}#{r[7][0]}"
|
21
|
+
elsif r[7].match?(/["']\z/)
|
22
|
+
opt = "#{r[7][-1]}#{r[7]}"
|
25
23
|
else
|
26
|
-
|
27
|
-
|
24
|
+
return val unless r[7].match?(/\s/)
|
25
|
+
|
26
|
+
opt = r[7]
|
28
27
|
end
|
28
|
+
r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, double: double, force: force, override: override)
|
29
29
|
elsif option && val =~ /\A([^=]+)=(.+)\z/m
|
30
30
|
return val if $2.match?(/\A(["']).+\1\z/m)
|
31
31
|
|
@@ -11,12 +11,12 @@ module Squared
|
|
11
11
|
def shell(*args, **kwargs)
|
12
12
|
if RUBY_VERSION < '2.6'
|
13
13
|
exception = kwargs.delete(:exception)
|
14
|
-
ret = system(*args, **kwargs)
|
14
|
+
ret = Kernel.system(*args, **kwargs)
|
15
15
|
return ret if ret || !exception
|
16
16
|
|
17
17
|
raise $?.to_s
|
18
18
|
else
|
19
|
-
system(*args, **kwargs)
|
19
|
+
Kernel.system(*args, **kwargs)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
data/lib/squared/common/utils.rb
CHANGED
@@ -47,9 +47,7 @@ module Squared
|
|
47
47
|
|
48
48
|
def task_invoked?(*args)
|
49
49
|
Rake::Task.tasks.any? do |obj|
|
50
|
-
|
51
|
-
|
52
|
-
args.any? { |val| val.is_a?(::Regexp) ? obj.name.match?(val) : val == obj.name }
|
50
|
+
obj.already_invoked && args.any? { |val| val.is_a?(::Regexp) ? obj.name.match?(val) : val == obj.name }
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
@@ -157,15 +155,13 @@ module Squared
|
|
157
155
|
when ::Numeric
|
158
156
|
return key if key.between?(0, 2)
|
159
157
|
end
|
158
|
+
return default unless default.is_a?(::String)
|
159
|
+
|
160
160
|
begin
|
161
|
-
|
162
|
-
default = (root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
|
163
|
-
end
|
161
|
+
(root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
|
164
162
|
rescue StandardError => e
|
165
163
|
warn e
|
166
164
|
1
|
167
|
-
else
|
168
|
-
default
|
169
165
|
end
|
170
166
|
end
|
171
167
|
|
data/lib/squared/version.rb
CHANGED
@@ -106,6 +106,7 @@ module Squared
|
|
106
106
|
else
|
107
107
|
@theme = {}
|
108
108
|
end
|
109
|
+
@chain = {}
|
109
110
|
@script = {
|
110
111
|
group: {},
|
111
112
|
ref: {},
|
@@ -132,8 +133,9 @@ module Squared
|
|
132
133
|
def initialize_session
|
133
134
|
return unless @pipe.is_a?(Pathname)
|
134
135
|
|
135
|
-
|
136
|
-
|
136
|
+
msg = "Session started on #{Time.now} by #{@main}"
|
137
|
+
bord = '#' * s.size
|
138
|
+
puts bord, msg, bord
|
137
139
|
end
|
138
140
|
|
139
141
|
def build(parallel: [], pass: nil, **kwargs)
|
@@ -165,6 +167,8 @@ module Squared
|
|
165
167
|
__build__(**kwargs)
|
166
168
|
|
167
169
|
yield self if block_given?
|
170
|
+
|
171
|
+
__chain__(**kwargs)
|
168
172
|
@closed = true
|
169
173
|
self
|
170
174
|
end
|
@@ -197,6 +201,34 @@ module Squared
|
|
197
201
|
script_command :run, script, group, ref, on, &blk
|
198
202
|
end
|
199
203
|
|
204
|
+
def chain(task, *action, project: nil, step: 0, with: nil, before: nil, after: nil, sync: false,
|
205
|
+
group: @group, ref: @ref)
|
206
|
+
keys = if project
|
207
|
+
action.map! { |val| task_join(project.name, val) }
|
208
|
+
nil
|
209
|
+
elsif (target = group || ref)
|
210
|
+
action.map! { |val| task_name(task_join(val, target)) }
|
211
|
+
nil
|
212
|
+
else
|
213
|
+
action.map! { |val| task_name(val) }
|
214
|
+
prefix ? nil : @project.keys
|
215
|
+
end
|
216
|
+
ns = lambda do |val|
|
217
|
+
next if (ret = as_a(val, :to_s, flat: true)).empty?
|
218
|
+
|
219
|
+
ret.map! do |arg|
|
220
|
+
if arg.include?(':') || (keys && !keys.include?(arg))
|
221
|
+
task_name(arg)
|
222
|
+
else
|
223
|
+
/\A#{Regexp.escape(task_name(arg))}:/
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
data = Support::ChainData.new(action, step, ns.call(with), ns.call(before), ns.call(after), sync)
|
228
|
+
(@chain[task_name(task.to_s)] ||= []) << data
|
229
|
+
self
|
230
|
+
end
|
231
|
+
|
200
232
|
def script(script, group: @group, ref: @ref, on: nil)
|
201
233
|
script_command :script, script, group, ref, on
|
202
234
|
end
|
@@ -305,13 +337,14 @@ module Squared
|
|
305
337
|
index = 0
|
306
338
|
while @project[name]
|
307
339
|
index += 1
|
308
|
-
name = "#{project}-#{index}"
|
340
|
+
name = task_name "#{project}-#{index}"
|
309
341
|
end
|
310
342
|
proj = ((if !ref.is_a?(Class)
|
311
343
|
Application.find(ref, path: path)
|
312
344
|
elsif ref < Project::Base
|
313
345
|
ref
|
314
346
|
end) || @kind[name]&.last || Project::Base).new(self, path, name, **kwargs)
|
347
|
+
proj.__send__(:index_set, @project.size)
|
315
348
|
@project[name] = proj
|
316
349
|
__get__(:project)[name] = proj unless kwargs[:private]
|
317
350
|
proj.instance_eval(&blk) if block_given?
|
@@ -506,7 +539,7 @@ module Squared
|
|
506
539
|
def format_desc(val, opts = nil, arg: 'opts*', before: nil, after: nil, out: false)
|
507
540
|
return unless TASK_METADATA || out
|
508
541
|
|
509
|
-
val = val.
|
542
|
+
val = val.split(':') if val.is_a?(String)
|
510
543
|
if before || after || opts
|
511
544
|
pos = []
|
512
545
|
pos << (before.is_a?(Array) ? before.join(',') : before) if before
|
@@ -651,13 +684,129 @@ module Squared
|
|
651
684
|
task Rake.application.default_task_name => out
|
652
685
|
end
|
653
686
|
|
687
|
+
def __chain__(*)
|
688
|
+
@chain.each do |key, group|
|
689
|
+
level = []
|
690
|
+
sync = []
|
691
|
+
failed = []
|
692
|
+
i = 0
|
693
|
+
pass = nil
|
694
|
+
until (i > 0 && !group.compact! && !pass) || group.empty?
|
695
|
+
group.each_with_index do |data, j|
|
696
|
+
if i == 0
|
697
|
+
action, reject = data.action.partition { |val| task_defined?(val) }
|
698
|
+
failed.concat(reject)
|
699
|
+
next group[j] = nil if action.empty?
|
700
|
+
|
701
|
+
step = data.step
|
702
|
+
data.action = action
|
703
|
+
else
|
704
|
+
step = 0
|
705
|
+
catch :found do
|
706
|
+
has = ->(c, d) { c.any? { |e| e.is_a?(Regexp) ? d.match?(e) : d == e } }
|
707
|
+
w = data.with
|
708
|
+
a = data.after
|
709
|
+
b = data.before
|
710
|
+
level.each_with_index do |tasks, k|
|
711
|
+
with = lambda do |n|
|
712
|
+
tasks.insert(n, *data.action)
|
713
|
+
sync << tasks
|
714
|
+
data.action.clear
|
715
|
+
end
|
716
|
+
tasks&.each_with_index do |v1, l|
|
717
|
+
index = k if w && has.call(w, v1)
|
718
|
+
if a && has.call(a, v1)
|
719
|
+
if index
|
720
|
+
with.call(l + 1)
|
721
|
+
throw :found
|
722
|
+
else
|
723
|
+
index = k + 1
|
724
|
+
end
|
725
|
+
elsif b && has.call(b, v1)
|
726
|
+
if index
|
727
|
+
with.call(l)
|
728
|
+
throw :found
|
729
|
+
else
|
730
|
+
index = k - 1
|
731
|
+
end
|
732
|
+
elsif index
|
733
|
+
if a || b
|
734
|
+
tasks.each_with_index do |v2, m|
|
735
|
+
if a && has.call(a, v2)
|
736
|
+
with.call(m + 1)
|
737
|
+
throw :found
|
738
|
+
elsif b && has.call(b, v2)
|
739
|
+
with.call(m)
|
740
|
+
throw :found
|
741
|
+
end
|
742
|
+
end
|
743
|
+
if !pass
|
744
|
+
pass = [i, data]
|
745
|
+
elsif pass.include?(data)
|
746
|
+
if i == pass.first + 1
|
747
|
+
pass.delete(data)
|
748
|
+
pass = nil if pass.size == 1
|
749
|
+
end
|
750
|
+
else
|
751
|
+
pass << data
|
752
|
+
end
|
753
|
+
next
|
754
|
+
end
|
755
|
+
else
|
756
|
+
next
|
757
|
+
end
|
758
|
+
step = index == -1 ? -1 : index + 1
|
759
|
+
throw :found
|
760
|
+
end
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
764
|
+
if step == -1
|
765
|
+
level.unshift(data.action)
|
766
|
+
step = 0
|
767
|
+
elsif step > 0
|
768
|
+
(level[step -= 1] ||= []).concat(data.action)
|
769
|
+
elsif !data.action.empty?
|
770
|
+
next
|
771
|
+
end
|
772
|
+
sync << level[step] if data.sync
|
773
|
+
group[j] = nil
|
774
|
+
pass = nil
|
775
|
+
end
|
776
|
+
i += 1
|
777
|
+
end
|
778
|
+
level.compact!
|
779
|
+
sync.uniq!
|
780
|
+
series.chain(key, level, sync: sync)
|
781
|
+
next if task_defined?(key = task_join(key, 'print'))
|
782
|
+
|
783
|
+
format_desc key
|
784
|
+
task key do
|
785
|
+
unless failed.empty? && group.empty?
|
786
|
+
puts log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
|
787
|
+
subject: 'failed placement', hint: false, pass: true)
|
788
|
+
end
|
789
|
+
cols = level.flatten(1).map(&:size).max
|
790
|
+
level.each_with_index do |grp, n|
|
791
|
+
title = "Step #{n.succ}#{if !sync.include?(grp) || (grp.size == 1 && series.parallel.include?(grp.first))
|
792
|
+
''
|
793
|
+
else
|
794
|
+
' (sync)'
|
795
|
+
end}"
|
796
|
+
emphasize(grp, title: title, cols: [cols, title.size].max, border: theme[:border],
|
797
|
+
sub: [pat: /\A(Step \d+)(.*)\z/, styles: theme[:header]])
|
798
|
+
end
|
799
|
+
end
|
800
|
+
end
|
801
|
+
end
|
802
|
+
|
654
803
|
def puts(*args)
|
655
804
|
puts_oe(*args, pipe: pipe)
|
656
805
|
end
|
657
806
|
|
658
807
|
def script_command(task, val, group, ref, on, &blk)
|
659
808
|
if block_given?
|
660
|
-
val =
|
809
|
+
val = Support::RunData.new(val, blk)
|
661
810
|
elsif !val
|
662
811
|
return self
|
663
812
|
end
|