squared 0.4.9 → 0.4.10
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 +23 -0
- data/README.md +15 -17
- data/README.ruby.md +12 -6
- data/lib/squared/common/prompt.rb +32 -11
- data/lib/squared/common/system.rb +4 -4
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +2 -2
- data/lib/squared/workspace/project/base.rb +7 -7
- data/lib/squared/workspace/project/docker.rb +73 -42
- data/lib/squared/workspace/project/git.rb +82 -56
- data/lib/squared/workspace/project/node.rb +27 -25
- data/lib/squared/workspace/project/python.rb +1 -1
- data/lib/squared/workspace/project/ruby.rb +12 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba613d7ba02a664fb4581573f6ee04d705f6bb2d1cb165c30c49d97eb259cbec
|
4
|
+
data.tar.gz: 764888100c6a6560478e99ed1451f1593a86e120799e25400708d81be934102c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cf6f1f10babf7bfbbe665fe5fc97527cf1df4093a3e6b8b906a4bf8cf87f538c601faee86f40decb79455de340e1d8f510fb45d0acc17694cd97a4051010539
|
7
|
+
data.tar.gz: 2b537c2c6a30a17191f32eb1012b225bc29fff9e9102b663a6dcf3ffd05465f4e8a0790f4cbdd6c63b21bd64c762e85dff1d22b4eb35053702a6692e92c994cc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.4.10] - 2025-05-08
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Git command pull and fetch action remote is interactive.
|
8
|
+
- Ruby command script uses multiline input when available.
|
9
|
+
- Ruby command file is interactive.
|
10
|
+
- Node command publish can accept access option levels.
|
11
|
+
- Docker command image action rm when called empty is interactive.
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- Disabled batch and alias tasks were not hidden.
|
16
|
+
- Docker tags from ENV were appended twice.
|
17
|
+
- Git events were not always registered.
|
18
|
+
- Git revbuild did not write lock data file with parallel tasks.
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- Choice selection default was set to no timeout.
|
23
|
+
- Git command add can accept a file search pattern.
|
24
|
+
|
3
25
|
## [0.4.9] - 2025-04-27
|
4
26
|
|
5
27
|
### Added
|
@@ -633,6 +655,7 @@
|
|
633
655
|
|
634
656
|
- Changelog was created.
|
635
657
|
|
658
|
+
[0.4.10]: https://github.com/anpham6/squared/releases/tag/v0.4.10-ruby
|
636
659
|
[0.4.9]: https://github.com/anpham6/squared/releases/tag/v0.4.9-ruby
|
637
660
|
[0.4.8]: https://github.com/anpham6/squared/releases/tag/v0.4.8-ruby
|
638
661
|
[0.4.7]: https://github.com/anpham6/squared/releases/tag/v0.4.7-ruby
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# squared 5.
|
1
|
+
# squared 5.5
|
2
2
|
|
3
3
|
## Documentation
|
4
4
|
|
@@ -15,10 +15,11 @@
|
|
15
15
|
* [squared-express](https://github.com/anpham6/squared-express#readme)
|
16
16
|
* [E-mc](https://github.com/anpham6/e-mc#readme)
|
17
17
|
* [Pi-r](https://github.com/anpham6/pi-r#readme)
|
18
|
+
* [Pi-r2](https://github.com/anpham6/pi-r2#readme)
|
18
19
|
|
19
20
|
## Installation
|
20
21
|
|
21
|
-
* NodeJS
|
22
|
+
* NodeJS 18
|
22
23
|
|
23
24
|
### NPX
|
24
25
|
|
@@ -131,26 +132,22 @@ rake clone # node + docs
|
|
131
132
|
|
132
133
|
```sh
|
133
134
|
# NODE_TAG=latest
|
134
|
-
# RUBY_VERSION=2.4.0-3.
|
135
|
-
# MANIFEST=nightly,
|
135
|
+
# RUBY_VERSION=2.4.0-3.4.0
|
136
|
+
# MANIFEST=nightly,prod,latest,android
|
136
137
|
# BUILD={dev,prod}
|
137
138
|
# DEV={0,1,local}
|
138
139
|
# DOCS=any
|
139
140
|
# PIPE_FAIL={0,1}
|
140
141
|
# PORT=3000
|
141
|
-
docker build -t squared --build-arg MANIFEST=prod --build-arg
|
142
|
-
docker build -t node --build-arg NODE_TAG=
|
143
|
-
docker buildx bake node
|
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.slim .
|
144
|
+
NODE=22 docker buildx bake node
|
144
145
|
# OR
|
145
|
-
|
146
|
-
|
147
|
-
docker build -t ruby --build-arg RUBY_TAG=3.0.0 --build-arg NODE_VERSION=20.x --build-arg PIPE_FAIL=0 -f Dockerfile.ruby .
|
148
|
-
docker buildx bake ruby
|
146
|
+
docker build -t ruby --build-arg RUBY_TAG=3.4.0 --build-arg NODE_VERSION=22 --build-arg PIPE_FAIL=0 -f Dockerfile.ruby .
|
147
|
+
RUBY=3.4.0 docker buildx bake ruby
|
149
148
|
# OR
|
150
|
-
|
151
|
-
|
152
|
-
docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=18.x -f Dockerfile.nginx .
|
153
|
-
docker buildx bake nginx
|
149
|
+
docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=20 -f Dockerfile.nginx .
|
150
|
+
NGINX=1.27 docker buildx bake nginx
|
154
151
|
|
155
152
|
# Express
|
156
153
|
docker run -it --name express --rm -p 3000:3000 \
|
@@ -521,6 +518,7 @@ squared.settings = {
|
|
521
518
|
],
|
522
519
|
compressImages: false, // TinyPNG API Key <https://tinypng.com/developers>
|
523
520
|
compressImages: "****************", // API key
|
521
|
+
compressImages: [{ plugin: "imagemin-pngquant", format: "png", options: { quality: [0.6, 0.8] } }], // v5.5
|
524
522
|
convertImages: "", // png | jpeg | webp | gif | bmp
|
525
523
|
showAttributes: true,
|
526
524
|
showAttributes: {
|
@@ -541,7 +539,7 @@ squared.settings = {
|
|
541
539
|
showErrorMessages: false,
|
542
540
|
convertPixels: "dp", // "sp" | "pt" | "in" | "mm"
|
543
541
|
convertLineHeight: "sp", // "dp" | "pt" | "in" | "mm"
|
544
|
-
convertEntities: ["numeric"],
|
542
|
+
convertEntities: ["numeric"],
|
545
543
|
convertEntities: ["codepoints", {/* JSON (last) */}], // https://html.spec.whatwg.org/entities.json
|
546
544
|
insertSpaces: 4,
|
547
545
|
outputDocumentHandler: "android",
|
@@ -1361,4 +1359,4 @@ NOTE: Defining an element "**id**" will prevent it from being removed during the
|
|
1361
1359
|
|
1362
1360
|
## LICENSE
|
1363
1361
|
|
1364
|
-
BSD 3-Clause
|
1362
|
+
BSD 3-Clause
|
data/README.ruby.md
CHANGED
@@ -98,6 +98,9 @@ Workspace::Application
|
|
98
98
|
with(exclude: [:base]) { add("publish/*", "packages") } # rake packages:sqd-serve:build
|
99
99
|
# OR
|
100
100
|
add(["publish/sqd-cli", "publish/sqd-serve"], true, exclude: [:base]) # rake squared:sqd-serve:build
|
101
|
+
|
102
|
+
# Git
|
103
|
+
revbuild(include: %w[src/ framework/ types/]) # Synchronous is recommended
|
101
104
|
end
|
102
105
|
.add("squared/sqd", exclude: :git, pass: [:node, "checkout", "bump"]) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
|
103
106
|
variable_set :script, "build:sqd" # Override detection
|
@@ -116,9 +119,9 @@ Workspace::Application
|
|
116
119
|
end
|
117
120
|
end
|
118
121
|
end
|
119
|
-
.pass("pull", group: "default") { test? || doc? } # pathname:pull | optparse:pull
|
122
|
+
.pass("pull", group: "default") { test? || doc? } # rake pathname:pull | rake optparse:pull
|
120
123
|
.style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
|
121
|
-
.build(default: "build", parallel: ["pull", "fetch", "rebase", "archive", "
|
124
|
+
.build(default: "build", parallel: ["pull", "fetch", "rebase", "archive", "clean", /^outdated:/], pass: ["publish"]) do |workspace|
|
122
125
|
workspace
|
123
126
|
.enable_aixterm
|
124
127
|
.style({
|
@@ -194,9 +197,9 @@ Workspace::Application
|
|
194
197
|
"pir": { # rake pir:clone
|
195
198
|
uri: "https://github.com/anpham6/pi-r", #
|
196
199
|
options: { #
|
197
|
-
"origin": "github", # --origin=
|
200
|
+
"origin": "github", # --origin=github
|
198
201
|
"recurse-submodules": false, # --no-recurse-submodules
|
199
|
-
"shallow-exclude": ["v0.0.1", "v0.0.2"] # --shallow-exclude=
|
202
|
+
"shallow-exclude": ["v0.0.1", "v0.0.2"] # --shallow-exclude=v0.0.1 --shallow-exclude=v0.0.2
|
200
203
|
}
|
201
204
|
}
|
202
205
|
)
|
@@ -238,7 +241,7 @@ Workspace::Application
|
|
238
241
|
.new(main: "squared")
|
239
242
|
.graph(["depend"], ref: :git) # Optional
|
240
243
|
.with(:python) do
|
241
|
-
doc(windows? ?
|
244
|
+
doc(windows? ? ".\make.bat html" : "make html") # rake android-docs:doc | rake doc:python
|
242
245
|
add("android-docs", "android", venv: "/home/user/.venv") # rake android-docs:depend
|
243
246
|
add("chrome-docs", "chrome", graph: "android", venv: ".venv") do # /workspaces/chrome-docs/.venv
|
244
247
|
variable_set :dependindex, 2 # Use Poetry for dependencies (optional)
|
@@ -490,7 +493,7 @@ rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- 'l
|
|
490
493
|
All project binary programs can have their executable path set to a non-global alias.
|
491
494
|
|
492
495
|
```ruby
|
493
|
-
Common::PATH.
|
496
|
+
Common::PATH.update({
|
494
497
|
GIT: "/usr/bin/git", # PATH_GIT=/usr/bin/git
|
495
498
|
TAR: "/opt/archivers/tar", # PATH_TAR=/opt/archivers/tar
|
496
499
|
UNZIP: "/opt/archivers/unzip",
|
@@ -593,6 +596,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
|
|
593
596
|
| log | * | PATHSPEC=s |
|
594
597
|
| pull | rebase | AUTOSTASH |
|
595
598
|
| pull | remote | REFSPEC=s |
|
599
|
+
| pull | -remote | ALL |
|
596
600
|
| pull | * | REBASE=0,1 FORCE RECURSE_SUBMODULES=0,1,s |
|
597
601
|
| rebase | branch | HEAD=s |
|
598
602
|
| rebase | onto | INTERACTIVE I HEAD=s |
|
@@ -621,6 +625,7 @@ DOCKER_OPTIONS_${NAME}=v,no-cache=false # project only (override)
|
|
621
625
|
DOCKER_TAG=latest # all
|
622
626
|
DOCKER_TAG_${NAME}=v0.1.0 # project only (override)
|
623
627
|
DOCKER_ALL=1 # list every image/container
|
628
|
+
DOCKER_Y=1 # confirm all
|
624
629
|
```
|
625
630
|
|
626
631
|
| Command | Flag | ENV |
|
@@ -629,6 +634,7 @@ DOCKER_ALL=1 # list every image/container
|
|
629
634
|
| buildx | bake | SERVICE=s |
|
630
635
|
| compose | build | TARGET=s |
|
631
636
|
| container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
|
637
|
+
| image | rm | Y=0,1 |
|
632
638
|
| image | push | TAG=s REGISTRY=s |
|
633
639
|
|
634
640
|
### Repo
|
@@ -8,8 +8,8 @@ module Squared
|
|
8
8
|
def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 30)
|
9
9
|
require 'readline'
|
10
10
|
require 'timeout'
|
11
|
-
agree = /^#{agree}$/i if agree.is_a?(::String)
|
12
|
-
cancel = /^#{cancel}$/i if cancel.is_a?(::String)
|
11
|
+
agree = /^#{Regexp.escape(agree)}$/i if agree.is_a?(::String)
|
12
|
+
cancel = /^#{Regexp.escape(cancel)}$/i if cancel.is_a?(::String)
|
13
13
|
Timeout.timeout(timeout) do
|
14
14
|
begin
|
15
15
|
while (ch = Readline.readline(msg))
|
@@ -32,24 +32,28 @@ module Squared
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def choice(msg, list = nil, min: 1, max: 1, multiple: false,
|
35
|
+
def choice(msg, list = nil, min: 1, max: 1, multiple: false, force: true, grep: nil, auto: true,
|
36
|
+
attempts: 5, timeout: 0)
|
36
37
|
require 'readline'
|
37
38
|
require 'timeout'
|
38
39
|
if list
|
40
|
+
grep &&= (grep.is_a?(::Enumerable) ? grep : [grep]).map { |val| Regexp.new(val) }
|
39
41
|
items = []
|
40
|
-
list.
|
41
|
-
|
42
|
+
list.each do |val|
|
43
|
+
next if grep&.none? { |pat| pat.match?(line) }
|
44
|
+
|
42
45
|
items << val.chomp
|
46
|
+
puts "#{items.size.to_s.rjust(2)}. #{val}"
|
43
47
|
end
|
44
48
|
max = items.size
|
49
|
+
raise_error 'empty selection list' if max == 0
|
50
|
+
min = [min, max].min
|
45
51
|
if auto
|
46
52
|
msg = "#{msg}: [1-#{max}#{if multiple
|
47
53
|
"|,#{multiple.is_a?(Numeric) ? "{#{multiple}}" : ''}"
|
48
54
|
end}] "
|
49
55
|
end
|
50
56
|
end
|
51
|
-
return unless max >= min
|
52
|
-
|
53
57
|
valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max) }
|
54
58
|
Timeout.timeout(timeout) do
|
55
59
|
begin
|
@@ -82,16 +86,33 @@ module Squared
|
|
82
86
|
end
|
83
87
|
end
|
84
88
|
|
85
|
-
def readline(msg, history = false, force: nil)
|
89
|
+
def readline(msg, history = false, force: nil, multiline: nil, &blk)
|
86
90
|
require 'readline'
|
91
|
+
multiline = if multiline && Readline.respond_to?(:readmultiline)
|
92
|
+
multiline.is_a?(::Enumerable) || block_given? ? multiline : [multiline.to_s]
|
93
|
+
end
|
94
|
+
prompt = lambda do
|
95
|
+
if !multiline
|
96
|
+
Readline.readline(msg, history)
|
97
|
+
elsif block_given?
|
98
|
+
Readline.readmultiline(msg, history, &blk)
|
99
|
+
else
|
100
|
+
Readline.readmultiline(msg, history) { |line| multiline.any? { |val| line.split.last.end_with?(val) } }
|
101
|
+
end
|
102
|
+
end
|
87
103
|
case force
|
88
104
|
when ::TrueClass, ::FalseClass
|
89
|
-
msg = "#{msg}
|
90
|
-
|
105
|
+
msg = "#{msg} %s " % if multiline
|
106
|
+
multiline.is_a?(::Enumerable) ? "{#{multiline.join('|')}}" : multiline
|
107
|
+
else
|
108
|
+
"(#{force ? 'required' : 'optional'}):"
|
109
|
+
end
|
110
|
+
ret = (prompt.call || '').strip
|
111
|
+
multiline.each { |val| break if ret.delete_suffix!(val) } if multiline.is_a?(::Enumerable)
|
91
112
|
raise_error 'user cancelled' if force && ret.empty?
|
92
113
|
ret
|
93
114
|
else
|
94
|
-
|
115
|
+
prompt.call
|
95
116
|
end
|
96
117
|
end
|
97
118
|
end
|
@@ -29,10 +29,10 @@ module Squared
|
|
29
29
|
dest.mkpath if create
|
30
30
|
if pass
|
31
31
|
exclude = []
|
32
|
-
pass = [pass] unless pass.is_a?(::
|
32
|
+
pass = [pass] unless pass.is_a?(::Enumerable)
|
33
33
|
pass.each { |val| exclude.concat(Dir.glob(src + val)) }
|
34
34
|
end
|
35
|
-
(glob.is_a?(::
|
35
|
+
(glob.is_a?(::Enumerable) ? glob : [glob]).each do |val|
|
36
36
|
Dir.glob(src + val) do |path|
|
37
37
|
next if exclude&.include?(path) || (path = Pathname.new(path)).directory?
|
38
38
|
|
@@ -79,7 +79,7 @@ module Squared
|
|
79
79
|
def copy_guard(src, dest, link: nil, force: false, verbose: true)
|
80
80
|
unless force
|
81
81
|
if (path = Pathname.new(dest)).directory?
|
82
|
-
src = [src] unless src.is_a?(::
|
82
|
+
src = [src] unless src.is_a?(::Enumerable)
|
83
83
|
src = src.reject { |val| path.join(File.basename(val)).exist? }
|
84
84
|
return if src.empty?
|
85
85
|
elsif path.exist?
|
@@ -89,7 +89,7 @@ module Squared
|
|
89
89
|
case link
|
90
90
|
when 'hard', 1
|
91
91
|
FileUtils.ln(src, dest, force: force, verbose: verbose)
|
92
|
-
when TrueClass, 'soft', 0
|
92
|
+
when ::TrueClass, 'soft', 0
|
93
93
|
FileUtils.ln_s(src, dest, force: force, verbose: verbose)
|
94
94
|
else
|
95
95
|
FileUtils.cp(src, dest, verbose: verbose)
|
data/lib/squared/version.rb
CHANGED
@@ -463,7 +463,7 @@ module Squared
|
|
463
463
|
tasks << key if obj.has?(key, baseref)
|
464
464
|
elsif (batch = series.batch_get(key))
|
465
465
|
obj.allref.each do |ref|
|
466
|
-
next unless (data = batch[ref])
|
466
|
+
next unless obj.has?(key, ref) && (data = batch[ref])
|
467
467
|
|
468
468
|
data.each do |val|
|
469
469
|
if (items = task_resolve(obj, val)).empty?
|
@@ -482,7 +482,7 @@ module Squared
|
|
482
482
|
return [] if (base && !obj.ref?(baseref)) || !(data = series.alias_get(key))
|
483
483
|
|
484
484
|
obj.allref.each do |ref|
|
485
|
-
next unless (alt = data[ref])
|
485
|
+
next unless obj.has?(key, ref) && (alt = data[ref])
|
486
486
|
|
487
487
|
ret = task_resolve(obj, alt)
|
488
488
|
break unless ret.empty?
|
@@ -1505,11 +1505,11 @@ module Squared
|
|
1505
1505
|
confirm("Upgrade to #{a}? #{b + e} [#{c}] ", d)
|
1506
1506
|
end
|
1507
1507
|
|
1508
|
-
def choice_index(msg, list, values: nil,
|
1509
|
-
|
1508
|
+
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
|
1509
|
+
multiple: false, force: true, **kwargs)
|
1510
1510
|
puts if !series && @@print_order > 0
|
1511
1511
|
msg = "#{msg} (optional)" unless force
|
1512
|
-
unless (ret = choice(msg, list, multiple: multiple, force: force,
|
1512
|
+
unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) || !force
|
1513
1513
|
raise_error 'user cancelled'
|
1514
1514
|
end
|
1515
1515
|
if ret.nil? || ret.empty?
|
@@ -1855,14 +1855,14 @@ module Squared
|
|
1855
1855
|
end
|
1856
1856
|
|
1857
1857
|
def has_value?(data, val)
|
1858
|
-
return data.value?(val) if data.is_a?(
|
1859
|
-
return data.is_a?(
|
1858
|
+
return data.value?(val) if data.is_a?(Hash)
|
1859
|
+
return data.is_a?(Enumerable) && data.to_a.include?(val) if !val.is_a?(Enumerable) || val.is_a?(Hash)
|
1860
1860
|
|
1861
1861
|
val.to_a.any? do |obj|
|
1862
1862
|
case data
|
1863
|
-
when
|
1863
|
+
when Hash
|
1864
1864
|
data.value?(obj)
|
1865
|
-
when
|
1865
|
+
when Enumerable
|
1866
1866
|
data.to_a.include?(obj)
|
1867
1867
|
end
|
1868
1868
|
end
|
@@ -196,7 +196,12 @@ module Squared
|
|
196
196
|
when :list, :rm
|
197
197
|
format_desc(action, flag, flag == :rm ? 'id*,opts*' : 'opts*,args*')
|
198
198
|
task flag do |_, args|
|
199
|
-
|
199
|
+
args = args.to_a
|
200
|
+
if flag == :rm && args.empty?
|
201
|
+
choice_command :rm
|
202
|
+
else
|
203
|
+
image flag, args
|
204
|
+
end
|
200
205
|
end
|
201
206
|
end
|
202
207
|
when 'network'
|
@@ -271,7 +276,6 @@ module Squared
|
|
271
276
|
end
|
272
277
|
if (val = option('tag', ignore: false))
|
273
278
|
append_tag val
|
274
|
-
ret << basic_option('tag', tagname(val))
|
275
279
|
elsif !session_arg?('t', 'tag')
|
276
280
|
append_tag tag
|
277
281
|
end
|
@@ -331,7 +335,7 @@ module Squared
|
|
331
335
|
def container(flag, opts = [], id: nil)
|
332
336
|
cmd, opts = docker_session('container', flag, opts: opts)
|
333
337
|
list = OPT_DOCKER[:container].fetch(flag, [])
|
334
|
-
list
|
338
|
+
list += OPT_DOCKER[:container][:update] if flag == :run
|
335
339
|
op = OptionPartition.new(opts, list, cmd, project: self, args: flag == :run || flag == :exec)
|
336
340
|
from = :"container:#{flag}"
|
337
341
|
case flag
|
@@ -433,6 +437,8 @@ module Squared
|
|
433
437
|
def image(flag, opts = [], sync: true, id: nil, registry: nil)
|
434
438
|
cmd, opts = docker_session('image', flag, opts: opts)
|
435
439
|
op = OptionPartition.new(opts, OPT_DOCKER[:image][flag], cmd, project: self)
|
440
|
+
exception = @exception
|
441
|
+
banner = true
|
436
442
|
from = :"image:#{flag}"
|
437
443
|
case flag
|
438
444
|
when :list
|
@@ -455,6 +461,10 @@ module Squared
|
|
455
461
|
when :rm
|
456
462
|
if id
|
457
463
|
op << id
|
464
|
+
if option('y')
|
465
|
+
exception = false
|
466
|
+
banner = false
|
467
|
+
end
|
458
468
|
else
|
459
469
|
if op.empty?
|
460
470
|
list_image(flag, docker_output('image ls -a'), from: from) do |val|
|
@@ -476,9 +486,12 @@ module Squared
|
|
476
486
|
img = docker_output 'image', 'tag', id, uri
|
477
487
|
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
478
488
|
|
479
|
-
|
489
|
+
cmd = img
|
490
|
+
sync = false
|
491
|
+
exception = true
|
492
|
+
banner = false
|
480
493
|
end
|
481
|
-
run(sync: sync, from: from)
|
494
|
+
run(cmd, sync: sync, exception: exception, banner: banner, from: from)
|
482
495
|
end
|
483
496
|
|
484
497
|
def network(flag, opts = [], target: nil)
|
@@ -535,8 +548,12 @@ module Squared
|
|
535
548
|
case flag
|
536
549
|
when :run
|
537
550
|
unless session_arg?('name', target: target)
|
538
|
-
|
539
|
-
|
551
|
+
target << basic_option('name', dnsname("#{name}_%s" % if RUBY_VERSION >= '3.1'
|
552
|
+
require 'random/formatter'
|
553
|
+
Random.new.alphanumeric(6)
|
554
|
+
else
|
555
|
+
(0...6).map { rand(97..122).chr }.join
|
556
|
+
end))
|
540
557
|
end
|
541
558
|
when :exec
|
542
559
|
raise_error('no command args', hint: from) if list.empty?
|
@@ -583,6 +600,8 @@ module Squared
|
|
583
600
|
pwd_set do
|
584
601
|
found = false
|
585
602
|
index = 0
|
603
|
+
all = option('all', prefix: 'docker')
|
604
|
+
y = from == :'image:rm' && option('y', prefix: 'docker')
|
586
605
|
pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})(?:[_.,:-]|$)/
|
587
606
|
IO.popen(session_done(cmd << '--format=json')).each do |line|
|
588
607
|
data = JSON.parse(line)
|
@@ -596,41 +615,43 @@ module Squared
|
|
596
615
|
id
|
597
616
|
end)
|
598
617
|
ee = data['Image'] || rt || aa
|
599
|
-
next unless
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
618
|
+
next unless all || ee.match?(pat) || aa.match?(pat)
|
619
|
+
|
620
|
+
unless y
|
621
|
+
bb = index.succ.to_s
|
622
|
+
cc = bb.size + 1
|
623
|
+
a = sub_style(ee, styles: theme[:inline])
|
624
|
+
b = "Execute #{sub_style(flag, styles: theme[:active])} on #{a}#{ee == id ? '' : " (#{id})"}"
|
625
|
+
c, d = no ? ['y/N', 'N'] : ['Y/n', 'Y']
|
626
|
+
e = time_format(time_since(data['CreatedAt']), pass: ['ms'])
|
627
|
+
f = sub_style(ARG[:BORDER][0], styles: theme[:inline])
|
628
|
+
g = ' ' * (cc + 1)
|
629
|
+
h = "#{sub_style(bb.rjust(cc), styles: theme[:current])} #{f} "
|
630
|
+
puts unless index == 0
|
631
|
+
puts "#{h + sub_style(aa, styles: theme[:subject])} (created #{e} ago)"
|
632
|
+
cols = %w[Tag Status Ports]
|
633
|
+
cols << case flag
|
634
|
+
when :connect, :disconnect
|
635
|
+
'Networks'
|
636
|
+
else
|
637
|
+
'Size'
|
638
|
+
end
|
639
|
+
cols.each do |key|
|
640
|
+
next if (key == 'Tag' && !dd) || (key == 'Size' && data[key] == '0B')
|
621
641
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
642
|
+
puts "#{g + f} #{key}: #{as_a(data[key]).join(', ')}" unless data[key].to_s.empty?
|
643
|
+
end
|
644
|
+
w = 9 + flag.to_s.size + 4 + ee.size
|
645
|
+
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])
|
646
|
+
found = true
|
647
|
+
index += 1
|
648
|
+
next unless confirm("#{h + b}? [#{c}] ", d, timeout: 60)
|
629
649
|
|
630
|
-
|
650
|
+
puts if @@print_order == 0
|
651
|
+
end
|
631
652
|
yield id
|
632
653
|
end
|
633
|
-
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) unless found
|
654
|
+
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) unless found || y
|
634
655
|
end
|
635
656
|
rescue StandardError => e
|
636
657
|
log.error e
|
@@ -658,7 +679,7 @@ module Squared
|
|
658
679
|
|
659
680
|
def choice_command(flag)
|
660
681
|
msg, cmd, index = case flag
|
661
|
-
when :run
|
682
|
+
when :run, :rm
|
662
683
|
['Choose an image', 'images -a', 2]
|
663
684
|
when :exec
|
664
685
|
['Choose a container', 'ps -a', 0]
|
@@ -671,16 +692,26 @@ module Squared
|
|
671
692
|
puts log_message(Logger::INFO, 'none found', subject: name, hint: "docker #{cmd}")
|
672
693
|
else
|
673
694
|
puts " # #{header}"
|
695
|
+
multiple = false
|
696
|
+
parse = ->(val) { val.split(/\s+/)[index] }
|
674
697
|
case flag
|
675
698
|
when :run, :exec
|
676
699
|
values = [['Options', flag == :run], ['Arguments', flag == :exec]]
|
677
700
|
cmd = flag.to_s
|
701
|
+
when :rm
|
702
|
+
values = ['Options']
|
703
|
+
multiple = true
|
704
|
+
cmd = "image #{flag}"
|
678
705
|
else
|
679
|
-
values = [
|
706
|
+
values = ['Options', ['Container', true]]
|
680
707
|
cmd = "network #{flag}"
|
681
708
|
end
|
682
|
-
out, opts, args = choice_index(msg, lines, values: values)
|
683
|
-
ret = run docker_output(cmd, opts, '--', out.
|
709
|
+
out, opts, args = choice_index(msg, lines, multiple: multiple, values: values)
|
710
|
+
ret = run docker_output(cmd, opts, '--', *(if out.is_a?(Array)
|
711
|
+
out.map! { |val| parse.call(val) }
|
712
|
+
else
|
713
|
+
[parse.call(out)]
|
714
|
+
end), args)
|
684
715
|
print_success if success?(ret && cmd.start_with?('network'))
|
685
716
|
end
|
686
717
|
end
|
@@ -111,21 +111,30 @@ module Squared
|
|
111
111
|
time_format(epoch, clock: clock)
|
112
112
|
end
|
113
113
|
|
114
|
-
def rev_clear(name)
|
114
|
+
def rev_clear(name, sync: true)
|
115
115
|
if Dir.exist?(name) && (proj = find(name))
|
116
116
|
name = proj.name
|
117
117
|
end
|
118
|
-
rev_write if rev_entry(name, 'revision', val: '', create: false)
|
118
|
+
rev_write(sync: sync) if rev_entry(name, 'revision', val: '', create: false)
|
119
119
|
end
|
120
120
|
|
121
|
-
def rev_write(name = nil, data = nil, utc: nil)
|
121
|
+
def rev_write(name = nil, data = nil, sync: true, utc: nil)
|
122
122
|
return unless @revfile
|
123
123
|
|
124
124
|
if name
|
125
125
|
data&.each { |key, val| rev_entry(name, key, val: val) }
|
126
126
|
rev_timeutc(name, utc) if utc
|
127
127
|
end
|
128
|
-
|
128
|
+
sleep 0 while !sync && @revlock
|
129
|
+
begin
|
130
|
+
@revlock = true
|
131
|
+
File.write(@revfile, JSON.pretty_generate(@revdoc))
|
132
|
+
rescue StandardError => e
|
133
|
+
log&.debug e
|
134
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
135
|
+
ensure
|
136
|
+
@revlock = false
|
137
|
+
end
|
129
138
|
end
|
130
139
|
|
131
140
|
def git_clone?(path, name = nil)
|
@@ -355,8 +364,13 @@ module Squared
|
|
355
364
|
if flag == :remote
|
356
365
|
format_desc action, flag, 'remote,opts*'
|
357
366
|
task flag, [:remote] do |_, args|
|
358
|
-
remote =
|
359
|
-
|
367
|
+
if (remote = args.remote)
|
368
|
+
args = args.extras
|
369
|
+
else
|
370
|
+
remote = choice_remote
|
371
|
+
args = args.to_a.drop(1)
|
372
|
+
end
|
373
|
+
__send__(action, flag, args, remote: remote)
|
360
374
|
end
|
361
375
|
else
|
362
376
|
format_desc action, flag, 'opts*'
|
@@ -845,12 +859,10 @@ module Squared
|
|
845
859
|
args = args.to_a
|
846
860
|
if args.empty? || args.last == ':'
|
847
861
|
files = []
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
when 'A', 'M'
|
853
|
-
files << $3
|
862
|
+
status_data.each do |line|
|
863
|
+
case (flag == :staged ? line[2] : line[1])
|
864
|
+
when /[AMDRTC]/
|
865
|
+
files << line[0]
|
854
866
|
end
|
855
867
|
end
|
856
868
|
unless files.empty?
|
@@ -867,12 +879,11 @@ module Squared
|
|
867
879
|
end
|
868
880
|
when 'git'
|
869
881
|
before = case flag
|
870
|
-
when :
|
882
|
+
when :mv then 'source+,destination'
|
871
883
|
when :revert then 'commit+' end
|
872
884
|
format_desc(action, flag, 'opts*', before: before, after: case flag
|
873
|
-
when :add
|
874
|
-
|
875
|
-
end)
|
885
|
+
when :add then 'pathspec*|:pattern:*'
|
886
|
+
when :clean, :rm then 'pathspec*' end)
|
876
887
|
task flag do |_, args|
|
877
888
|
git flag, args.to_a
|
878
889
|
end
|
@@ -888,13 +899,13 @@ module Squared
|
|
888
899
|
super
|
889
900
|
end
|
890
901
|
|
891
|
-
def depend(*, **)
|
892
|
-
workspace.rev_clear(name)
|
902
|
+
def depend(*, sync: invoked_sync?('depend'), **)
|
903
|
+
workspace.rev_clear(name, sync: sync)
|
893
904
|
super
|
894
905
|
end
|
895
906
|
|
896
|
-
def clean(*, **)
|
897
|
-
workspace.rev_clear(name)
|
907
|
+
def clean(*, sync: invoked_sync?('clean'), **)
|
908
|
+
workspace.rev_clear(name, sync: sync)
|
898
909
|
super
|
899
910
|
end
|
900
911
|
|
@@ -915,7 +926,7 @@ module Squared
|
|
915
926
|
end
|
916
927
|
end
|
917
928
|
append_pull(opts, OPT_GIT[:pull] + OPT_GIT[:fetch][:pull],
|
918
|
-
no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag)
|
929
|
+
no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag, from: :pull)
|
919
930
|
source(sync: sync, sub: if verbose
|
920
931
|
[
|
921
932
|
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
|
@@ -957,11 +968,9 @@ module Squared
|
|
957
968
|
end
|
958
969
|
|
959
970
|
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
|
960
|
-
|
961
|
-
append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
|
962
|
-
flag: flag)
|
963
|
-
cmd << '--all' if !remote && !session_arg?('multiple') && option('all')
|
964
|
-
cmd << '--verbose' if verbose && !session_arg?('quiet')
|
971
|
+
opts = git_session('fetch', opts: opts).last
|
972
|
+
append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
|
973
|
+
remote: remote, flag: flag, from: :fetch)
|
965
974
|
source(sync: sync, **threadargs)
|
966
975
|
end
|
967
976
|
|
@@ -980,7 +989,7 @@ module Squared
|
|
980
989
|
opts[:origin] = val if (val = option('origin', ignore: false))
|
981
990
|
opts[:branch] = val if (val = option('branch', strict: true))
|
982
991
|
opts[:local] = val != '0' if (val = option('local', strict: true))
|
983
|
-
opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(:clone)
|
992
|
+
opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(from: :clone)
|
984
993
|
append_hash opts
|
985
994
|
cmd << '--quiet' unless verbose
|
986
995
|
append_value(data[0], path, delim: true)
|
@@ -1112,7 +1121,8 @@ module Squared
|
|
1112
1121
|
msg = sub_style('completed', styles: theme[:active])
|
1113
1122
|
puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
|
1114
1123
|
end
|
1115
|
-
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
|
1124
|
+
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
|
1125
|
+
sync: sync, utc: 'build')
|
1116
1126
|
end
|
1117
1127
|
|
1118
1128
|
def reset(flag, opts = [], refs: nil, ref: nil, mode: nil, commit: nil)
|
@@ -1600,17 +1610,25 @@ module Squared
|
|
1600
1610
|
append_commit(*op.extras)
|
1601
1611
|
end
|
1602
1612
|
when :add, :clean
|
1603
|
-
if flag == :add &&
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1613
|
+
if flag == :add && !op.arg?('pathspec-from-file')
|
1614
|
+
grep, list = op.extras.partition { |val| val.start_with?(':') && val.end_with?(':') }
|
1615
|
+
if list.empty? || !grep.empty?
|
1616
|
+
red = color(:red)
|
1617
|
+
grep.map! { |val| Regexp.new(val[1..-2]) }
|
1618
|
+
files = status_data.map! do |a, b|
|
1619
|
+
next unless grep.empty? || grep.any? { |pat| pat.match?(a) }
|
1620
|
+
|
1621
|
+
"#{sub_style(b, styles: red)} #{a}"
|
1622
|
+
end
|
1623
|
+
.compact
|
1624
|
+
unless files.empty?
|
1625
|
+
files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/,
|
1626
|
+
accept: 'Add?')
|
1627
|
+
end
|
1628
|
+
op.swap(list + files)
|
1610
1629
|
end
|
1611
|
-
files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/, accept: 'Add?')
|
1612
1630
|
end
|
1613
|
-
append_pathspec(
|
1631
|
+
append_pathspec(op.extras)
|
1614
1632
|
verbose = flag == :add && !op.arg?('verbose')
|
1615
1633
|
print_success if success?(source) && verbose
|
1616
1634
|
return
|
@@ -1619,7 +1637,7 @@ module Squared
|
|
1619
1637
|
raise_error 'no source/destination' unless refs.size > 1
|
1620
1638
|
op.merge(refs)
|
1621
1639
|
when :rm
|
1622
|
-
append_pathspec(op.extras, expect:
|
1640
|
+
append_pathspec(op.extras, expect: true)
|
1623
1641
|
end
|
1624
1642
|
source(sync: false, stderr: true)
|
1625
1643
|
end
|
@@ -1639,13 +1657,13 @@ module Squared
|
|
1639
1657
|
private
|
1640
1658
|
|
1641
1659
|
def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
|
1642
|
-
multiple: false,
|
1660
|
+
multiple: false, **kwargs)
|
1643
1661
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1644
1662
|
banner = nil if multiple && banner
|
1645
1663
|
if cmd.respond_to?(:done)
|
1646
1664
|
if io && banner == false
|
1647
1665
|
from = nil
|
1648
|
-
elsif !from && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z][a-z\-]
|
1666
|
+
elsif !from && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
|
1649
1667
|
from = :"git:#{from}"
|
1650
1668
|
end
|
1651
1669
|
banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
|
@@ -1677,7 +1695,7 @@ module Squared
|
|
1677
1695
|
require 'open3'
|
1678
1696
|
if stderr
|
1679
1697
|
Open3.popen3(cmd) do |_, out, err|
|
1680
|
-
n = write_lines(out, banner: banner,
|
1698
|
+
n = write_lines(out, banner: banner, pass: true, **kwargs)
|
1681
1699
|
if n == 0
|
1682
1700
|
n = write_lines(err, banner: banner)
|
1683
1701
|
print_success if success?(n == 0 && !banner.nil?)
|
@@ -1686,7 +1704,7 @@ module Squared
|
|
1686
1704
|
end
|
1687
1705
|
end
|
1688
1706
|
else
|
1689
|
-
Open3.popen2e(cmd) { |_, out| write_lines(out, banner: banner) }
|
1707
|
+
Open3.popen2e(cmd) { |_, out| write_lines(out, banner: banner, **kwargs) }
|
1690
1708
|
end
|
1691
1709
|
end
|
1692
1710
|
rescue StandardError => e
|
@@ -1703,13 +1721,8 @@ module Squared
|
|
1703
1721
|
end
|
1704
1722
|
|
1705
1723
|
def write_lines(data, banner: nil, loglevel: nil, grep: nil, sub: nil, pass: false, first: false)
|
1706
|
-
grep
|
1707
|
-
|
1708
|
-
|
1709
|
-
Regexp.new(val == '*' ? '.+' : val.to_s)
|
1710
|
-
end
|
1711
|
-
grep = nil if grep.empty?
|
1712
|
-
sub = nil if stdin?
|
1724
|
+
grep &&= as_a(grep).yield_self { |a| a.empty? || a.include?('*') ? nil : a.map { |val| Regexp.new(val) } }
|
1725
|
+
sub &&= stdin? ? nil : as_a(sub)
|
1713
1726
|
ret = 0
|
1714
1727
|
out = []
|
1715
1728
|
data.each do |line|
|
@@ -1739,7 +1752,7 @@ module Squared
|
|
1739
1752
|
styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
|
1740
1753
|
styles << :bold if styles.size <= 1
|
1741
1754
|
puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
|
1742
|
-
sub: { pat:
|
1755
|
+
sub: { pat: /^(\d+)(.+)$/, styles: styles })
|
1743
1756
|
else
|
1744
1757
|
puts empty_status("No #{type} were #{action}", 'grep', grep.is_a?(Array) ? case grep.size
|
1745
1758
|
when 0
|
@@ -1786,8 +1799,8 @@ module Squared
|
|
1786
1799
|
glob = kwargs.fetch(:include, [])
|
1787
1800
|
pass = kwargs.fetch(:exclude, [])
|
1788
1801
|
ret = {}
|
1789
|
-
|
1790
|
-
|
1802
|
+
status_data(*args).each do |line|
|
1803
|
+
file = line.first
|
1791
1804
|
next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1792
1805
|
next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1793
1806
|
|
@@ -1796,9 +1809,19 @@ module Squared
|
|
1796
1809
|
ret
|
1797
1810
|
end
|
1798
1811
|
|
1799
|
-
def
|
1812
|
+
def status_data(*args)
|
1813
|
+
ret = []
|
1814
|
+
git_spawn('status -z -uall', *args).split("\x0").each do |line|
|
1815
|
+
next unless line =~ /^(.)(.) (.+)$/
|
1816
|
+
|
1817
|
+
ret << [$3, $2, $1]
|
1818
|
+
end
|
1819
|
+
ret
|
1820
|
+
end
|
1821
|
+
|
1822
|
+
def append_pull(opts, list, target: @session, flag: nil, no: nil, remote: nil, from: nil)
|
1800
1823
|
target << '--force' if option('force', target: target)
|
1801
|
-
append_submodules(target: target)
|
1824
|
+
append_submodules(target: target, from: from)
|
1802
1825
|
return if !remote && opts.empty?
|
1803
1826
|
|
1804
1827
|
refspec = []
|
@@ -1823,6 +1846,7 @@ module Squared
|
|
1823
1846
|
op.errors << opt
|
1824
1847
|
end
|
1825
1848
|
end
|
1849
|
+
op << '--verbose' if (flag || from == :fetch) && verbose && !op.arg?('quiet')
|
1826
1850
|
if remote
|
1827
1851
|
op.append(remote, delim: true)
|
1828
1852
|
if (val = option('refspec', target: target, strict: true))
|
@@ -1834,6 +1858,8 @@ module Squared
|
|
1834
1858
|
elsif op.arg?('--multiple')
|
1835
1859
|
op.swap.merge(op.map! { |opt| shell_escape(opt, quote: true) })
|
1836
1860
|
return
|
1861
|
+
elsif option('all')
|
1862
|
+
cmd << '--all'
|
1837
1863
|
end
|
1838
1864
|
op.clear(errors: true, subject: flag.to_s) if flag
|
1839
1865
|
end
|
@@ -1874,7 +1900,7 @@ module Squared
|
|
1874
1900
|
append_first('head', 'tree-ish', 'object', target: target, flag: false, ignore: false)
|
1875
1901
|
end
|
1876
1902
|
|
1877
|
-
def append_submodules(
|
1903
|
+
def append_submodules(target: @session, from: nil)
|
1878
1904
|
return unless (val = option('recurse-submodules', target: target, ignore: false))
|
1879
1905
|
|
1880
1906
|
if from == :clone
|
@@ -1928,7 +1954,7 @@ module Squared
|
|
1928
1954
|
target.include?('--dry-run') || !option('dry-run', target: target).nil?
|
1929
1955
|
end
|
1930
1956
|
|
1931
|
-
def quiet?(target: @session)
|
1957
|
+
def quiet?(*, target: @session, **)
|
1932
1958
|
return false unless target
|
1933
1959
|
|
1934
1960
|
target.include?('--quiet') || (target.include?('-q') && stripext(target.first) == 'git')
|
@@ -191,22 +191,21 @@ module Squared
|
|
191
191
|
end
|
192
192
|
end
|
193
193
|
when 'publish'
|
194
|
-
format_desc(action, flag, 'otp?,dry-run
|
194
|
+
format_desc(action, flag, 'otp?,dry-run?,public|restricted?', before: flag == :tag ? 'tag' : nil)
|
195
195
|
task flag do |_, args|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
196
|
+
args = args.to_a
|
197
|
+
dryrun = true if args.delete('dry-run') || args.delete('true') || args.delete('d')
|
198
|
+
if args.delete('public') || args.delete('p')
|
199
|
+
access = 'public'
|
200
|
+
elsif args.delete('restricted') || args.delete('r')
|
201
|
+
access = 'restricted'
|
201
202
|
end
|
202
|
-
|
203
|
-
|
204
|
-
dryrun = true
|
205
|
-
otp = nil
|
203
|
+
if flag == :latest
|
204
|
+
otp = args.first
|
206
205
|
else
|
207
|
-
|
206
|
+
tag, otp = param_guard(action, flag, args: args)
|
208
207
|
end
|
209
|
-
publish(flag, otp: otp, tag: tag, dryrun: dryrun)
|
208
|
+
publish(flag, otp: otp, tag: tag, dryrun: dryrun, access: access)
|
210
209
|
end
|
211
210
|
end
|
212
211
|
end
|
@@ -217,7 +216,7 @@ module Squared
|
|
217
216
|
end
|
218
217
|
|
219
218
|
def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, workspace: false,
|
220
|
-
link: false, force: false, override: false, **kwargs)
|
219
|
+
link: false, force: false, override: false, sync: invoked_sync?('copy'), **kwargs)
|
221
220
|
glob = kwargs[:include]
|
222
221
|
pass = kwargs[:exclude]
|
223
222
|
if @copy && !override
|
@@ -239,7 +238,7 @@ module Squared
|
|
239
238
|
items = []
|
240
239
|
if build? && path != @workspace.home && @workspace.home?
|
241
240
|
items << @workspace.home
|
242
|
-
@workspace.rev_clear(@workspace.find(@workspace.home).name)
|
241
|
+
@workspace.rev_clear(@workspace.find(@workspace.home).name, sync: sync)
|
243
242
|
end
|
244
243
|
items.concat(as_a(also)) if also
|
245
244
|
return if items.empty?
|
@@ -250,13 +249,13 @@ module Squared
|
|
250
249
|
case dir
|
251
250
|
when Pathname
|
252
251
|
dest = dir
|
253
|
-
@workspace.rev_clear(dest)
|
252
|
+
@workspace.rev_clear(dest, sync: sync)
|
254
253
|
when String
|
255
254
|
dest = @workspace.root + dir
|
256
|
-
@workspace.rev_clear(dest)
|
255
|
+
@workspace.rev_clear(dest, sync: sync)
|
257
256
|
when Symbol
|
258
257
|
if (proj = @workspace.find(name: dir))
|
259
|
-
@workspace.rev_clear(proj.name)
|
258
|
+
@workspace.rev_clear(proj.name, sync: sync)
|
260
259
|
dest = proj.path
|
261
260
|
else
|
262
261
|
log.warn message("copy project :#{dir}", hint: 'not found')
|
@@ -274,10 +273,10 @@ module Squared
|
|
274
273
|
glob = dir[:include]
|
275
274
|
pass = dir[:exclude]
|
276
275
|
dest = items.first unless dest && dest != true
|
277
|
-
@workspace.rev_clear(dest) unless dest == true
|
276
|
+
@workspace.rev_clear(dest, sync: sync) unless dest == true
|
278
277
|
when Project::Base
|
279
278
|
dest = dir.path
|
280
|
-
@workspace.rev_clear(dir.name)
|
279
|
+
@workspace.rev_clear(dir.name, sync: sync)
|
281
280
|
else
|
282
281
|
raise_error "copy: given #{dir}"
|
283
282
|
end
|
@@ -329,7 +328,7 @@ module Squared
|
|
329
328
|
if @depend && !flag
|
330
329
|
super
|
331
330
|
elsif outdated?
|
332
|
-
workspace.rev_clear(name)
|
331
|
+
workspace.rev_clear(name, sync: sync)
|
333
332
|
return update if !flag && env('NODE_UPDATE')
|
334
333
|
|
335
334
|
if (yarn = dependtype(:yarn)) > 0
|
@@ -548,7 +547,7 @@ module Squared
|
|
548
547
|
package 'update'
|
549
548
|
end
|
550
549
|
|
551
|
-
def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil,
|
550
|
+
def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil, access: nil)
|
552
551
|
if read_packagemanager(:private)
|
553
552
|
if warning?
|
554
553
|
warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: 'private', pass: true)
|
@@ -558,11 +557,10 @@ module Squared
|
|
558
557
|
return unless version
|
559
558
|
|
560
559
|
cmd = session 'npm', 'publish'
|
561
|
-
otp = option('otp') if otp.nil?
|
562
|
-
tag = option('tag') if tag.nil?
|
563
560
|
dryrun = dryrun?('npm') if dryrun.nil?
|
564
|
-
cmd << basic_option('otp', otp) if otp
|
565
|
-
cmd <<
|
561
|
+
cmd << basic_option('otp', otp) if otp ||= option('otp')
|
562
|
+
cmd << basic_option('tag', tag) if tag ||= option('tag')
|
563
|
+
cmd << basic_option('access', access) if access ||= option('access')
|
566
564
|
if verbose
|
567
565
|
if dryrun
|
568
566
|
cmd << '--dry-run'
|
@@ -760,6 +758,10 @@ module Squared
|
|
760
758
|
outdated?
|
761
759
|
end
|
762
760
|
|
761
|
+
def refresh?
|
762
|
+
!Node.prod?
|
763
|
+
end
|
764
|
+
|
763
765
|
def yarn?
|
764
766
|
(@pm[:yarn] ||= if rootpath('yarn.lock', ascend: dependext).exist?
|
765
767
|
if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
|
@@ -219,13 +219,20 @@ module Squared
|
|
219
219
|
when :file
|
220
220
|
format_desc action, flag, 'path,opts*,args*'
|
221
221
|
task flag, [:rb] do |_, args|
|
222
|
-
file =
|
223
|
-
|
222
|
+
if (file = args.rb)
|
223
|
+
args = args.to_a.drop(1)
|
224
|
+
else
|
225
|
+
file, opts, extra = choice_index('Select a file', Dir.glob('*.rb', base: path),
|
226
|
+
values: %w[Options Arguments], force: true, series: true)
|
227
|
+
args = OptionPartition.strip(opts)
|
228
|
+
ENV['RUBY_ARGS'] = extra if extra
|
229
|
+
end
|
230
|
+
ruby(flag, args, file: file)
|
224
231
|
end
|
225
232
|
when :script
|
226
|
-
format_desc action, flag, '
|
233
|
+
format_desc action, flag, 'opts*,args*'
|
227
234
|
task flag do |_, args|
|
228
|
-
command = ENV['RUBY_E'] || readline('Enter script', force: true)
|
235
|
+
command = ENV['RUBY_E'] || readline('Enter script', force: true, multiline: ['##', ';'])
|
229
236
|
ruby(flag, args.to_a, command: command)
|
230
237
|
end
|
231
238
|
when :version
|
@@ -246,7 +253,7 @@ module Squared
|
|
246
253
|
if @depend
|
247
254
|
super
|
248
255
|
elsif outdated?
|
249
|
-
workspace.rev_clear(name)
|
256
|
+
workspace.rev_clear(name, sync: sync)
|
250
257
|
cmd = bundle_session 'install'
|
251
258
|
cmd << '--without=development' if prod?
|
252
259
|
if (n = option('jobs')).to_i > 0
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- An Pham
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rake
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
rubygems_version: 3.6.
|
126
|
+
rubygems_version: 3.6.7
|
127
127
|
specification_version: 4
|
128
128
|
summary: Rake task generator for managing multi-language workspaces.
|
129
129
|
test_files: []
|