squared 0.6.2 → 0.6.3
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 +40 -0
- data/README.md +23 -13
- data/lib/squared/common/base.rb +2 -2
- data/lib/squared/common/format.rb +39 -32
- data/lib/squared/common/prompt.rb +6 -4
- data/lib/squared/common/shell.rb +4 -4
- data/lib/squared/config.rb +6 -7
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +72 -23
- data/lib/squared/workspace/project/base.rb +145 -83
- data/lib/squared/workspace/project/docker.rb +15 -15
- data/lib/squared/workspace/project/git.rb +74 -27
- data/lib/squared/workspace/project/node.rb +211 -109
- data/lib/squared/workspace/project/python.rb +9 -9
- data/lib/squared/workspace/project/ruby.rb +29 -34
- data/lib/squared/workspace/project/support/class.rb +36 -652
- data/lib/squared/workspace/project/support/optionpartition.rb +641 -0
- data/lib/squared/workspace/project.rb +0 -1
- data/lib/squared/workspace/repo.rb +23 -14
- data/lib/squared/workspace/series.rb +10 -8
- data/squared.gemspec +2 -2
- metadata +3 -3
- data/lib/squared/workspace/project/support.rb +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac2411d2abc2d5caca8296cd25de89f28ede8458dd42809216e9ecb60dbc12e3
|
|
4
|
+
data.tar.gz: 2574d5d757f7405c47d792c47f83520325a633514801885706404efc3a10fa8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6623132213ca2b9510f867ffd711ce8541ef3d707290a51ae40eeca20dbe8ec027c4b47630d67ba96527faa9630a71b9befd89020bbba2ac329fc76925200c61
|
|
7
|
+
data.tar.gz: 909a95ac73cd5261d4d2bf184fb90ae6069d92fc30ba850d574da048f73938090ddea6ea7693fc6d0353df8a63213d964b2a964f44e3afa9f8f4188c47f8f5aa
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.3] - 2025-11-14
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Node command package action rebuild was implemented.
|
|
8
|
+
- Node command add can remove packages using "-" prefix.
|
|
9
|
+
- Git command log action grep was implemented.
|
|
10
|
+
- Node command package action add was implemented.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Application class extended Enumerable collection class.
|
|
15
|
+
- OptionPartition class is lazily loaded using autoload.
|
|
16
|
+
- Requiring individual project classes in Rakefile is optional.
|
|
17
|
+
- Application class uses static method register instead of series_wrap.
|
|
18
|
+
- Project support modules are required inside Base class module.
|
|
19
|
+
- Project graph print did not display parent and last child consequetively.
|
|
20
|
+
- Project outdated interactive prompts use exact column alignments.
|
|
21
|
+
|
|
22
|
+
## [0.5.16] - 2025-11-14
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- See `0.4.30`.
|
|
27
|
+
|
|
28
|
+
## [0.4.30] - 2025-11-14
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Config viewer can read items by index in an Array.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Node command add uses event name "add" and not "depend".
|
|
37
|
+
- Node command add did not include packages with Yarn and PNPM.
|
|
38
|
+
- Git method revbuild did not splat build arguments.
|
|
39
|
+
|
|
3
40
|
## [0.6.2] - 2025-11-08
|
|
4
41
|
|
|
5
42
|
### Added
|
|
@@ -1351,9 +1388,11 @@
|
|
|
1351
1388
|
|
|
1352
1389
|
- Changelog was created.
|
|
1353
1390
|
|
|
1391
|
+
[0.6.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.3
|
|
1354
1392
|
[0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
|
|
1355
1393
|
[0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
|
|
1356
1394
|
[0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
|
|
1395
|
+
[0.5.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.16
|
|
1357
1396
|
[0.5.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.15
|
|
1358
1397
|
[0.5.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.14
|
|
1359
1398
|
[0.5.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.13
|
|
@@ -1370,6 +1409,7 @@
|
|
|
1370
1409
|
[0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
|
|
1371
1410
|
[0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
|
|
1372
1411
|
[0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
|
|
1412
|
+
[0.4.30]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.30
|
|
1373
1413
|
[0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
|
|
1374
1414
|
[0.4.28]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.28
|
|
1375
1415
|
[0.4.27]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.27
|
data/README.md
CHANGED
|
@@ -75,6 +75,10 @@ require "squared/app" # All workspace related mod
|
|
|
75
75
|
# sqd-serve = /workspaces/squared/publish/sqd-serve
|
|
76
76
|
# sqd = /workspaces/squared/sqd
|
|
77
77
|
|
|
78
|
+
# Load external Project classes (optional)
|
|
79
|
+
Workspace::Application.load_ref('/home/user/.gem/ruby/3.4.0/gems/squared-0.6.0/lib/squared/workspace/project') # ref = :node => node.rb (absolute)
|
|
80
|
+
Workspace::Application.load_ref('lib/squared/workspace/project', gem: 'squared') # bundle env (relative)
|
|
81
|
+
|
|
78
82
|
Workspace::Application
|
|
79
83
|
.new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
|
|
80
84
|
.banner("group", "project", styles: ["yellow", "black"], border: "bold") # name | project | path | ref | group? | parent? | version?
|
|
@@ -150,13 +154,13 @@ Node = Workspace::Project::Node # tsc
|
|
|
150
154
|
Node.options("build:dev", "target=es2022", project: "tsconfig.json") # :node (ref)
|
|
151
155
|
Node.options("build:dev", "outDir=tmp", :squared) # squared (project name)
|
|
152
156
|
|
|
153
|
-
Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb
|
|
157
|
+
Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb | rbs
|
|
154
158
|
Ruby.options("lint", "rubocop", opts: ["gemfile=Gemfile"]) # :ruby
|
|
155
159
|
Ruby.options("lint", "--parallel", :squared)
|
|
156
160
|
|
|
157
|
-
Python = Workspace::Project::Python
|
|
158
|
-
Python.options("build", opts: ["r=requirements.txt"])
|
|
159
|
-
Python.options(:build, "build:dev", opts: ["no-deps"])
|
|
161
|
+
Python = Workspace::Project::Python # pip
|
|
162
|
+
Python.options("build", opts: ["r=requirements.txt"]) # :python
|
|
163
|
+
Python.options(:build, "build:dev", opts: ["no-deps"]) # inherits "build" as "build:dev"
|
|
160
164
|
|
|
161
165
|
Workspace::Application
|
|
162
166
|
.new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
|
|
@@ -692,7 +696,8 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
|
|
|
692
696
|
| checkout | track | COUNT=n |
|
|
693
697
|
| checkout | global path | HEAD=s PATHSPEC=s |
|
|
694
698
|
| checkout | * | F|FORCE MERGE |
|
|
695
|
-
| clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s LOCAL=0,1
|
|
699
|
+
| clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s BARE=1 LOCAL=0,1 |
|
|
700
|
+
| | | SINGLE_BRANCH=0,1 NO_CHECKOUT=1 NO_TAGS=1 QUIET=1 |
|
|
696
701
|
| commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
|
|
697
702
|
| diff | -between -contain | MERGE_BASE |
|
|
698
703
|
| diff | head branch | INDEX=n |
|
|
@@ -742,14 +747,19 @@ BUILD_SQUARED_OPTS="NODE_TAG=24 RUBY_VERSION=3.4.0" DOCKER_SQUARED_OPTS="--no-ca
|
|
|
742
747
|
docker build --no-cache --label=v1 --build-arg='NODE_TAG=24' --build-arg='RUBY_VERSION=3.4.0' .
|
|
743
748
|
```
|
|
744
749
|
|
|
745
|
-
| Command | Flag
|
|
746
|
-
| :--------- |
|
|
747
|
-
| buildx | build
|
|
748
|
-
| buildx | bake
|
|
749
|
-
| compose | build
|
|
750
|
-
|
|
|
751
|
-
|
|
|
752
|
-
|
|
|
750
|
+
| Command | Flag | ENV |
|
|
751
|
+
| :--------- | :----------------- | :---------------------------------------------- |
|
|
752
|
+
| buildx | build context | TAG=s |
|
|
753
|
+
| buildx | bake | SERVICE=s |
|
|
754
|
+
| compose | build | TARGET=s |
|
|
755
|
+
| compose | run | VERSION=s |
|
|
756
|
+
| container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
|
|
757
|
+
| container | -run -create -exec | ALL=1 |
|
|
758
|
+
| | -update -commit | |
|
|
759
|
+
| image | rm | Y=1 |
|
|
760
|
+
| image | push | TAG=s REGISTRY=s |
|
|
761
|
+
| image | -push | ALL=1 |
|
|
762
|
+
| network | * | ALL=1 |
|
|
753
763
|
|
|
754
764
|
### asdf
|
|
755
765
|
|
data/lib/squared/common/base.rb
CHANGED
|
@@ -14,8 +14,8 @@ module Squared
|
|
|
14
14
|
CHOICE: 25,
|
|
15
15
|
QUOTE: "'",
|
|
16
16
|
SPACE: ' => ',
|
|
17
|
-
GRAPH: [
|
|
18
|
-
BORDER: [
|
|
17
|
+
GRAPH: %w[| - | \\ -].freeze,
|
|
18
|
+
BORDER: %w[| - - - - - | | - -].freeze,
|
|
19
19
|
VIEW: 'view',
|
|
20
20
|
BACKTRACE: $DEBUG || !$VERBOSE.nil?,
|
|
21
21
|
LEVEL: ENV.fetch('LOG_LEVEL', 0).to_i,
|
|
@@ -28,8 +28,8 @@ module Squared
|
|
|
28
28
|
bright_cyan!: '106',
|
|
29
29
|
bright_white!: '107'
|
|
30
30
|
}.freeze
|
|
31
|
-
BOX_GRAPH = [
|
|
32
|
-
BOX_BORDER = [
|
|
31
|
+
BOX_GRAPH = %w[│ ─ ├ └ ┬].freeze
|
|
32
|
+
BOX_BORDER = %w[│ ─ ┌ ┐ ┘ └ ├ ┤ ┬ ┴].tap do |val|
|
|
33
33
|
if ENV['TERM']&.end_with?('256color')
|
|
34
34
|
val.slice!(2, 4)
|
|
35
35
|
val.insert(2, '╭', '╮', '╯', '╰')
|
|
@@ -61,25 +61,25 @@ module Squared
|
|
|
61
61
|
def sub_style(val, *args, styles: nil, pat: nil, index: 1)
|
|
62
62
|
return val unless ARG[:COLOR]
|
|
63
63
|
|
|
64
|
-
if pat && index != 0
|
|
65
|
-
|
|
64
|
+
ret = if pat && index != 0
|
|
65
|
+
return val unless (data = pat.match(val))
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
index == -1 ? data.to_a.drop(1) : data[index]
|
|
68
|
+
else
|
|
69
|
+
index = 0
|
|
70
|
+
val
|
|
71
|
+
end
|
|
72
72
|
wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
|
|
73
73
|
code = []
|
|
74
|
+
args.clear if args.size == 1 && args.first.nil?
|
|
74
75
|
args.concat(Array(styles)).flatten.each_with_index do |type, i|
|
|
75
76
|
next unless type
|
|
76
77
|
|
|
77
|
-
if index == -1
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
end
|
|
78
|
+
s = if index == -1
|
|
79
|
+
ret[i] || (next ret[i] = '')
|
|
80
|
+
else
|
|
81
|
+
ret
|
|
82
|
+
end
|
|
83
83
|
if type.is_a?(::Numeric)
|
|
84
84
|
f, b = type.to_s.split('.')
|
|
85
85
|
s = wrap.call(s, ['38', '5', f]) if f[0] != '-' && f.to_i <= 255
|
|
@@ -125,6 +125,10 @@ module Squared
|
|
|
125
125
|
out
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
+
def sub_style!(val, *args, **kwargs)
|
|
129
|
+
val.replace(sub_style(val, *args, **kwargs))
|
|
130
|
+
end
|
|
131
|
+
|
|
128
132
|
def check_style(args, empty: true)
|
|
129
133
|
ret = []
|
|
130
134
|
colors = __get__(:colors)
|
|
@@ -192,9 +196,9 @@ module Squared
|
|
|
192
196
|
ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(::Logger)
|
|
193
197
|
end
|
|
194
198
|
end
|
|
195
|
-
return false
|
|
199
|
+
return false unless pass || level >= ARG[:LEVEL]
|
|
196
200
|
end
|
|
197
|
-
if
|
|
201
|
+
if hint.nil? ? args.size > 1 : !hint
|
|
198
202
|
title = log_title(level, color: false)
|
|
199
203
|
emphasize(args,
|
|
200
204
|
title: title + (subject ? " #{subject}" : ''),
|
|
@@ -204,7 +208,9 @@ module Squared
|
|
|
204
208
|
end)
|
|
205
209
|
else
|
|
206
210
|
msg = [log_title(level, color: color)]
|
|
207
|
-
|
|
211
|
+
if subject
|
|
212
|
+
msg << (color ? sub_style(subject.to_s, (@theme.is_a?(::Hash) && @theme[:subject]) || :bold) : subject)
|
|
213
|
+
end
|
|
208
214
|
msg << args.shift if msg.size == 1
|
|
209
215
|
message(msg.join(' '), *args, hint: hint)
|
|
210
216
|
end
|
|
@@ -236,7 +242,7 @@ module Squared
|
|
|
236
242
|
end
|
|
237
243
|
|
|
238
244
|
def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
|
|
239
|
-
border: @theme && @theme[:border])
|
|
245
|
+
border: @theme.is_a?(::Hash) && @theme[:border])
|
|
240
246
|
n = 0
|
|
241
247
|
max = ->(a) { n = [n, a.max_by(&:size).size].max }
|
|
242
248
|
set = ->(s) { Array(s).map(&:to_s).tap { |a| max.call(a) } }
|
|
@@ -257,17 +263,19 @@ module Squared
|
|
|
257
263
|
out = []
|
|
258
264
|
draw = lambda do |a, b|
|
|
259
265
|
ret = a + (b1 * (n + 2)) + b
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
next ret unless border
|
|
267
|
+
|
|
268
|
+
sub_style ret, border
|
|
262
269
|
end
|
|
263
270
|
sub = sub.is_a?(::Hash) ? [sub] : Array(sub)
|
|
264
271
|
pr = lambda do |line|
|
|
265
272
|
s = line.ljust(n)
|
|
266
|
-
sub.each { |h|
|
|
273
|
+
sub.each { |h| sub_style!(s, **h) }
|
|
267
274
|
s = "#{b0} #{s} #{b0}"
|
|
268
275
|
if border
|
|
269
|
-
|
|
270
|
-
|
|
276
|
+
[[/\A(#{Regexp.escape(b0)})(.+)\z/om], [/\A(.+)(#{Regexp.escape(b0)})\z/om, 2]].each do |args|
|
|
277
|
+
sub_style!(s, **opt_style(border, *args))
|
|
278
|
+
end
|
|
271
279
|
end
|
|
272
280
|
s
|
|
273
281
|
end
|
|
@@ -282,7 +290,7 @@ module Squared
|
|
|
282
290
|
unless sub.empty? && !right
|
|
283
291
|
footer.map! do |s|
|
|
284
292
|
s = s.rjust(n + 4) if right
|
|
285
|
-
sub.each { |h|
|
|
293
|
+
sub.each { |h| sub_style!(s, **h) }
|
|
286
294
|
s
|
|
287
295
|
end
|
|
288
296
|
end
|
|
@@ -291,17 +299,16 @@ module Squared
|
|
|
291
299
|
if block_given?
|
|
292
300
|
yield out
|
|
293
301
|
elsif pipe
|
|
302
|
+
return out if pipe == -1
|
|
303
|
+
|
|
294
304
|
case pipe
|
|
295
|
-
when -1
|
|
296
|
-
return out
|
|
297
305
|
when 0
|
|
298
|
-
|
|
306
|
+
$stdin
|
|
299
307
|
when 2
|
|
300
|
-
|
|
308
|
+
$stderr
|
|
301
309
|
else
|
|
302
|
-
pipe
|
|
303
|
-
end
|
|
304
|
-
pipe.puts out
|
|
310
|
+
pipe.respond_to?(:puts) ? pipe : $stdout
|
|
311
|
+
end.puts(out)
|
|
305
312
|
else
|
|
306
313
|
err ? warn(out) : puts(out)
|
|
307
314
|
end
|
|
@@ -19,7 +19,7 @@ module Squared
|
|
|
19
19
|
module Prompt
|
|
20
20
|
module_function
|
|
21
21
|
|
|
22
|
-
def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 3, timeout: 60)
|
|
22
|
+
def confirm(msg, default = nil, agree: 'Y', cancel: 'N', force: false, attempts: 3, timeout: 60)
|
|
23
23
|
require 'timeout'
|
|
24
24
|
if agree == 'Y' && cancel == 'N' && !msg.match?(%r{\[(?:Yn|nY|Y/n|y/N)\]})
|
|
25
25
|
case default
|
|
@@ -38,6 +38,7 @@ module Squared
|
|
|
38
38
|
when agree
|
|
39
39
|
return true
|
|
40
40
|
when cancel
|
|
41
|
+
exit 1 if force
|
|
41
42
|
return false
|
|
42
43
|
end
|
|
43
44
|
attempts -= 1
|
|
@@ -47,6 +48,7 @@ module Squared
|
|
|
47
48
|
puts
|
|
48
49
|
exit 0
|
|
49
50
|
else
|
|
51
|
+
exit 1 if force
|
|
50
52
|
false
|
|
51
53
|
end
|
|
52
54
|
end
|
|
@@ -129,7 +131,7 @@ module Squared
|
|
|
129
131
|
multiline = if multiline && Readline.respond_to?(:readmultiline)
|
|
130
132
|
multiline.is_a?(::Enumerable) || block_given? ? multiline : [multiline.to_s]
|
|
131
133
|
end
|
|
132
|
-
|
|
134
|
+
read = lambda do
|
|
133
135
|
if !multiline
|
|
134
136
|
Readline.readline(msg, history)
|
|
135
137
|
elsif block_given?
|
|
@@ -145,12 +147,12 @@ module Squared
|
|
|
145
147
|
else
|
|
146
148
|
[force ? ':' : '?', '']
|
|
147
149
|
end
|
|
148
|
-
ret = (
|
|
150
|
+
ret = (read.call || '').strip
|
|
149
151
|
multiline.each { |val| break if ret.delete_suffix!(val.to_s) } if multiline.is_a?(::Enumerable)
|
|
150
152
|
exit 1 if force && ret.empty?
|
|
151
153
|
ret
|
|
152
154
|
else
|
|
153
|
-
|
|
155
|
+
read.call
|
|
154
156
|
end
|
|
155
157
|
end
|
|
156
158
|
end
|
data/lib/squared/common/shell.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Squared
|
|
|
13
13
|
|
|
14
14
|
module_function
|
|
15
15
|
|
|
16
|
-
def shell_escape(val, quote: false,
|
|
16
|
+
def shell_escape(val, quote: false, option: false, force: false, double: false, override: false)
|
|
17
17
|
if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
|
|
18
18
|
if (data = r[2].match(QUOTE_VALUE))
|
|
19
19
|
double = data[1] == '"'
|
|
@@ -31,7 +31,7 @@ module Squared
|
|
|
31
31
|
r[7]
|
|
32
32
|
end
|
|
33
33
|
r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, force: force, double: double, override: override)
|
|
34
|
-
elsif option && val =~ /\A(-{0,2}[
|
|
34
|
+
elsif option && val =~ /\A(-{0,2}[^=\s-][^=\s]*)=(.+)\z/m
|
|
35
35
|
return val if $2.match?(QUOTE_VALUE)
|
|
36
36
|
|
|
37
37
|
"#{$1}=%s" % if $2.include?(' ')
|
|
@@ -55,7 +55,7 @@ module Squared
|
|
|
55
55
|
return val if (!force && !val.include?(' ')) || val.empty?
|
|
56
56
|
|
|
57
57
|
if option
|
|
58
|
-
pat = /\A(?:-[
|
|
58
|
+
pat = /\A(?:-[^=\s-](?:=|\s+)?|(--)?[^=\s-][^=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
|
|
59
59
|
return val if val.match?(pat)
|
|
60
60
|
end
|
|
61
61
|
q = ->(s) { s.gsub("'\\\\''", "'") }
|
|
@@ -103,7 +103,7 @@ module Squared
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def shell_split(val, join: nil, **kwargs)
|
|
106
|
-
ret = val.shellsplit.map! { |opt| shell_escape(opt,
|
|
106
|
+
ret = val.shellsplit.map! { |opt| shell_escape(opt, option: true, double: true, **kwargs) }
|
|
107
107
|
return ret unless join
|
|
108
108
|
|
|
109
109
|
ret.join(join.is_a?(::String) ? join : ' ')
|
data/lib/squared/config.rb
CHANGED
|
@@ -12,15 +12,14 @@ module Squared
|
|
|
12
12
|
include Rake::DSL
|
|
13
13
|
|
|
14
14
|
class << self
|
|
15
|
-
def parse(gem, namespace, ext = [
|
|
15
|
+
def parse(gem, namespace, ext = [gem])
|
|
16
16
|
require gem
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
[eval(namespace), Array(ext)].tap do |data|
|
|
18
|
+
data.last.each { |key| @@mime_obj[key] = data }
|
|
19
|
+
end
|
|
19
20
|
rescue LoadError, NameError => e
|
|
20
21
|
warn e
|
|
21
22
|
nil
|
|
22
|
-
else
|
|
23
|
-
@@mime_obj[ext.first]
|
|
24
23
|
end
|
|
25
24
|
|
|
26
25
|
def link(project, main = project.dependfile.basename, name = nil, **kwargs, &blk)
|
|
@@ -245,7 +244,7 @@ module Squared
|
|
|
245
244
|
opt_style(theme[:key], /\A((?~ : ))( : (?!undefined).+)\z/m),
|
|
246
245
|
opt_style(theme[:number], /\A((?~: ): )(-?[\d.]+)(\s*)\z/m, 2),
|
|
247
246
|
opt_style(theme[:string], /\A((?~: ): ")(.+)("\s*)\z/m, 2),
|
|
248
|
-
opt_style(theme[:hash], /\A((?~: ): \{)(.+)(
|
|
247
|
+
opt_style(theme[:hash], /\A((?~: ): \{)(.+)(}\s*)\z/m, 2),
|
|
249
248
|
opt_style(theme[:array], /\A((?~: ): \[)(.+)(\]\s*)\z/m, 2),
|
|
250
249
|
opt_style(theme[:boolean], /\A((?~: ): )(true|false)(\s*)\z/m, 2),
|
|
251
250
|
opt_style(theme[:value], /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, 2)
|
|
@@ -259,7 +258,7 @@ module Squared
|
|
|
259
258
|
symbolize = opts[:symbolize_names]
|
|
260
259
|
keys.each do |key|
|
|
261
260
|
begin
|
|
262
|
-
items = key.split('.')
|
|
261
|
+
items = key.split('.').flat_map { |name| name =~ /^(.+)\[(\d+)\]$/ ? [$1, $2.to_i] : name }
|
|
263
262
|
items = items.map(&:to_sym) if symbolize
|
|
264
263
|
val = data.dig(*items)
|
|
265
264
|
if val.nil?
|
data/lib/squared/version.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Squared
|
|
4
4
|
module Workspace
|
|
5
5
|
class Application
|
|
6
|
+
include Enumerable
|
|
6
7
|
include Common::Format
|
|
7
8
|
include Utils
|
|
8
9
|
include Support::Variables
|
|
@@ -49,10 +50,31 @@ module Squared
|
|
|
49
50
|
@task_exclude.merge(args.map!(&:to_sym))
|
|
50
51
|
end
|
|
51
52
|
|
|
52
|
-
def
|
|
53
|
+
def register(app)
|
|
54
|
+
@session << app
|
|
53
55
|
impl_series.new(app, exclude: @task_exclude.to_a)
|
|
54
56
|
end
|
|
55
57
|
|
|
58
|
+
def load_ref(path, gem: nil)
|
|
59
|
+
if gem
|
|
60
|
+
unless @gemsdir
|
|
61
|
+
IO.popen('bundle env').each do |val|
|
|
62
|
+
next unless val =~ /^\s+Gem Home\s+(.+)$/
|
|
63
|
+
|
|
64
|
+
@gemsdir = File.join($1, 'gems')
|
|
65
|
+
break
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
dir = if gem.match?(/-\d+(?:\.|$)/)
|
|
69
|
+
gem
|
|
70
|
+
else
|
|
71
|
+
Dir.glob("#{gem}-*", base: @gemsdir).pop
|
|
72
|
+
end
|
|
73
|
+
path = File.join(@gemsdir, dir, path) if dir
|
|
74
|
+
end
|
|
75
|
+
@load_project.unshift(path.cleanpath.to_s) if (path = Pathname.new(path)).absolute? && path.exist?
|
|
76
|
+
end
|
|
77
|
+
|
|
56
78
|
def baseref
|
|
57
79
|
impl_project.ref
|
|
58
80
|
end
|
|
@@ -61,11 +83,15 @@ module Squared
|
|
|
61
83
|
super[/[^:]+\z/, 0]
|
|
62
84
|
end
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
alias series_wrap register
|
|
87
|
+
|
|
88
|
+
attr_reader :kind_project, :load_project, :session
|
|
65
89
|
attr_accessor :impl_series, :impl_project, :attr_banner
|
|
66
90
|
end
|
|
67
91
|
|
|
68
92
|
@kind_project = []
|
|
93
|
+
@load_project = [File.expand_path('project', __dir__)]
|
|
94
|
+
@session = []
|
|
69
95
|
@task_exclude = Set.new
|
|
70
96
|
|
|
71
97
|
attr_reader :root, :home, :main, :prefix, :theme, :series, :closed
|
|
@@ -84,7 +110,7 @@ module Squared
|
|
|
84
110
|
@home.mkpath rescue nil
|
|
85
111
|
@root = @home.parent
|
|
86
112
|
@prefix = prefix
|
|
87
|
-
@series = Application.
|
|
113
|
+
@series = Application.register(self)
|
|
88
114
|
@project = {}
|
|
89
115
|
@kind = hashlist
|
|
90
116
|
@extensions = []
|
|
@@ -138,6 +164,12 @@ module Squared
|
|
|
138
164
|
puts bord, msg, bord
|
|
139
165
|
end
|
|
140
166
|
|
|
167
|
+
def each(&blk)
|
|
168
|
+
return to_enum(:each) unless block_given?
|
|
169
|
+
|
|
170
|
+
@project.each_value(&blk)
|
|
171
|
+
end
|
|
172
|
+
|
|
141
173
|
def build(parallel: [], pass: nil, **kwargs)
|
|
142
174
|
return self unless enabled? && !@closed
|
|
143
175
|
|
|
@@ -148,7 +180,8 @@ module Squared
|
|
|
148
180
|
parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map!(&:to_s)
|
|
149
181
|
end
|
|
150
182
|
@pass[:pattern].concat(pass.map { |val| val.is_a?(Regexp) ? val : val.to_s }) if pass
|
|
151
|
-
|
|
183
|
+
series.reset
|
|
184
|
+
each do |proj|
|
|
152
185
|
if proj.enabled?
|
|
153
186
|
proj.populate(series.keys.dup, **kwargs)
|
|
154
187
|
elsif proj.enabled?(base: false)
|
|
@@ -330,11 +363,12 @@ module Squared
|
|
|
330
363
|
name = task_name "#{project}-#{index}"
|
|
331
364
|
end
|
|
332
365
|
proj = ((if !ref.is_a?(Class)
|
|
366
|
+
require_project ref
|
|
333
367
|
Application.find(ref, path: path)
|
|
334
368
|
elsif ref < Project::Base
|
|
335
369
|
ref
|
|
336
370
|
end) || @kind[name]&.last || Project::Base).new(self, path, name, **kwargs)
|
|
337
|
-
proj.__send__(:index_set,
|
|
371
|
+
proj.__send__(:index_set, size)
|
|
338
372
|
@project[name] = proj
|
|
339
373
|
__get__(:project)[name] = proj unless kwargs[:private]
|
|
340
374
|
proj.instance_eval(&blk) if block_given?
|
|
@@ -348,11 +382,11 @@ module Squared
|
|
|
348
382
|
basename = dir.basename.to_s
|
|
349
383
|
[dir, basename, override[basename.to_sym]]
|
|
350
384
|
end
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
385
|
+
.each do |dir, basename, opts|
|
|
386
|
+
args = kwargs.dup
|
|
387
|
+
args.update(opts) if opts
|
|
388
|
+
add(dir, basename, group: val, **args, &blk)
|
|
389
|
+
end
|
|
356
390
|
self
|
|
357
391
|
end
|
|
358
392
|
|
|
@@ -406,18 +440,21 @@ module Squared
|
|
|
406
440
|
end
|
|
407
441
|
|
|
408
442
|
def find(path = nil, name: nil, group: nil, ref: nil, &blk)
|
|
409
|
-
|
|
443
|
+
return @project.values.find(&blk) if block_given? && !path && !name && !group && !ref
|
|
444
|
+
|
|
445
|
+
ret = group ? select { |item| item.group == group } : []
|
|
410
446
|
if path.is_a?(Symbol)
|
|
411
447
|
ref ||= path
|
|
412
448
|
path = nil
|
|
413
449
|
end
|
|
414
450
|
if ret.empty?
|
|
415
|
-
ret =
|
|
451
|
+
ret = select { |item| item.ref?(ref) } if ref
|
|
416
452
|
if ret.empty? && (path || name)
|
|
417
453
|
path &&= rootpath path
|
|
418
454
|
name &&= name.to_s
|
|
419
|
-
proj =
|
|
420
|
-
|
|
455
|
+
if (proj = find { |item| (path && item.path == path) || (name && item.name == name) })
|
|
456
|
+
ret << proj
|
|
457
|
+
end
|
|
421
458
|
end
|
|
422
459
|
end
|
|
423
460
|
return (group || ref ? ret : ret.first) unless block_given?
|
|
@@ -453,7 +490,7 @@ module Squared
|
|
|
453
490
|
if @describe
|
|
454
491
|
val = name || task_join(*args)
|
|
455
492
|
found = false
|
|
456
|
-
|
|
493
|
+
sub = lambda do |data, out|
|
|
457
494
|
index = data.size
|
|
458
495
|
data.to_a.reverse_each { |group| out.sub!("%#{index -= 1}", group) }
|
|
459
496
|
out
|
|
@@ -461,7 +498,7 @@ module Squared
|
|
|
461
498
|
@describe[:replace].each do |pat, tmpl|
|
|
462
499
|
next unless val =~ pat
|
|
463
500
|
|
|
464
|
-
val =
|
|
501
|
+
val = sub.call($~, tmpl.dup)
|
|
465
502
|
found = true
|
|
466
503
|
end
|
|
467
504
|
if (out = @describe[:alias][val])
|
|
@@ -471,7 +508,7 @@ module Squared
|
|
|
471
508
|
@describe[:pattern].each do |key, pat|
|
|
472
509
|
next unless val =~ pat
|
|
473
510
|
|
|
474
|
-
val =
|
|
511
|
+
val = sub.call($~, key.dup)
|
|
475
512
|
found = true
|
|
476
513
|
break
|
|
477
514
|
end
|
|
@@ -579,7 +616,7 @@ module Squared
|
|
|
579
616
|
end
|
|
580
617
|
|
|
581
618
|
def enabled?
|
|
582
|
-
!@extensions.empty? ||
|
|
619
|
+
!@extensions.empty? || any? { |proj| proj.enabled?(base: false) }
|
|
583
620
|
end
|
|
584
621
|
|
|
585
622
|
def task_base?(key)
|
|
@@ -726,7 +763,7 @@ module Squared
|
|
|
726
763
|
a = data.after
|
|
727
764
|
b = data.before
|
|
728
765
|
level.each_with_index do |tasks, k|
|
|
729
|
-
|
|
766
|
+
ac = lambda do |n|
|
|
730
767
|
tasks.insert(n, *data.action)
|
|
731
768
|
sync << tasks
|
|
732
769
|
data.action.clear
|
|
@@ -735,14 +772,14 @@ module Squared
|
|
|
735
772
|
index = k if w && has.call(w, v1)
|
|
736
773
|
if a && has.call(a, v1)
|
|
737
774
|
if index
|
|
738
|
-
|
|
775
|
+
ac.call(l.succ)
|
|
739
776
|
throw :found
|
|
740
777
|
else
|
|
741
778
|
index = k.succ
|
|
742
779
|
end
|
|
743
780
|
elsif b && has.call(b, v1)
|
|
744
781
|
if index
|
|
745
|
-
|
|
782
|
+
ac.call(l)
|
|
746
783
|
throw :found
|
|
747
784
|
else
|
|
748
785
|
index = k.pred
|
|
@@ -751,10 +788,10 @@ module Squared
|
|
|
751
788
|
if a || b
|
|
752
789
|
tasks.each_with_index do |v2, m|
|
|
753
790
|
if a && has.call(a, v2)
|
|
754
|
-
|
|
791
|
+
ac.call(m.succ)
|
|
755
792
|
throw :found
|
|
756
793
|
elsif b && has.call(b, v2)
|
|
757
|
-
|
|
794
|
+
ac.call(m)
|
|
758
795
|
throw :found
|
|
759
796
|
end
|
|
760
797
|
end
|
|
@@ -865,6 +902,18 @@ module Squared
|
|
|
865
902
|
end
|
|
866
903
|
end
|
|
867
904
|
|
|
905
|
+
def require_project(ref)
|
|
906
|
+
return unless ref.is_a?(Symbol) && Application.kind_project.none? { |proj| proj.ref == ref }
|
|
907
|
+
|
|
908
|
+
name = ref.to_s
|
|
909
|
+
Application.load_project.each do |val|
|
|
910
|
+
next unless File.exist?("#{rb = File.join(val, name)}.rb")
|
|
911
|
+
|
|
912
|
+
require_relative rb
|
|
913
|
+
break
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
|
|
868
917
|
def root?(path, pass: [])
|
|
869
918
|
return false unless path.directory?
|
|
870
919
|
|