squared 0.6.2 → 0.6.4
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 +72 -0
- data/README.md +25 -15
- data/lib/squared/common/base.rb +2 -2
- data/lib/squared/common/format.rb +43 -32
- data/lib/squared/common/prompt.rb +6 -4
- data/lib/squared/common/shell.rb +5 -4
- data/lib/squared/config.rb +6 -7
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +74 -25
- data/lib/squared/workspace/project/base.rb +204 -105
- data/lib/squared/workspace/project/docker.rb +28 -34
- data/lib/squared/workspace/project/git.rb +95 -54
- data/lib/squared/workspace/project/node.rb +222 -116
- data/lib/squared/workspace/project/python.rb +77 -44
- data/lib/squared/workspace/project/ruby.rb +100 -75
- data/lib/squared/workspace/project/support/class.rb +45 -657
- data/lib/squared/workspace/project/support/optionpartition.rb +641 -0
- data/lib/squared/workspace/project.rb +0 -1
- data/lib/squared/workspace/repo.rb +45 -18
- data/lib/squared/workspace/series.rb +27 -14
- data/lib/squared/workspace.rb +5 -3
- data/squared.gemspec +2 -2
- metadata +2 -2
- 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: f66aceeba825bcfd6afd3b20e5c39431d94450639cc70e07c3c8c22725426595
|
|
4
|
+
data.tar.gz: b23a0282dbe08d322ed19931ddaa59be93c4b5caeb603fb90ca4283a0f195bb0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ffa105272b8235dd427597c590d372d910edc40e2cd988dfe6b779355c2f036f32fdf6ec909d336cb84a7bf38db425e456a982b51cfad4d4fa499cb583382f27
|
|
7
|
+
data.tar.gz: cb767f0c63b833b4550199caf2d0fc2f2d98bda119e4f0c128de5e7083fe6da7813402a46aaabfabb0b19dd56c23f77d7732167673df2bf50996ca47c55d9fa0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.4] - 2025-11-16
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Python command outdated can hide non-upgradable packages.
|
|
8
|
+
- Ruby command outdated option dry-run was implemented.
|
|
9
|
+
- Ruby command outdated option interactive was implemented.
|
|
10
|
+
- Repo binary can be downloaded and run from any local directory.
|
|
11
|
+
- Python command outdated option dry-run was implemented.
|
|
12
|
+
- Common shell defined Array instance method quote!.
|
|
13
|
+
- Python command outdated option interactive was implemented.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Gem command outdated uses inline interactive prompts.
|
|
18
|
+
- Log messages with level INFO can be called without level argument.
|
|
19
|
+
- Project base attribute project was converted into an accessor.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Node command tsc did not accept a tsconfig or watch argument.
|
|
24
|
+
- Repo application tasks are not created on Windows.
|
|
25
|
+
- Repo module used conflicting REPO_URL with Repo application.
|
|
26
|
+
- Project task outdated did not check pass and only exclusions.
|
|
27
|
+
- Python command install did not include available options.
|
|
28
|
+
- Workspace static method resolve did nothing when given a String.
|
|
29
|
+
- Project base run command types did not include Struct.
|
|
30
|
+
|
|
31
|
+
## [0.6.3] - 2025-11-14
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Node command package action rebuild was implemented.
|
|
36
|
+
- Node command add can remove packages using "-" prefix.
|
|
37
|
+
- Git command log action grep was implemented.
|
|
38
|
+
- Node command package action add was implemented.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Application class extended Enumerable collection class.
|
|
43
|
+
- OptionPartition class is lazily loaded using autoload.
|
|
44
|
+
- Requiring individual project classes in Rakefile is optional.
|
|
45
|
+
- Application class uses static method register instead of series_wrap.
|
|
46
|
+
- Project support modules are required inside Base class module.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Project graph print did not display parent and last child consequetively.
|
|
51
|
+
- Project outdated interactive prompts use exact column alignments.
|
|
52
|
+
|
|
53
|
+
## [0.5.16] - 2025-11-14
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- See `0.4.30`.
|
|
58
|
+
|
|
59
|
+
## [0.4.30] - 2025-11-14
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- Config viewer can read items by index in an Array.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- Node command add uses event name "add" and not "depend".
|
|
68
|
+
- Node command add did not include packages with Yarn and PNPM.
|
|
69
|
+
- Git method revbuild did not splat build arguments.
|
|
70
|
+
|
|
3
71
|
## [0.6.2] - 2025-11-08
|
|
4
72
|
|
|
5
73
|
### Added
|
|
@@ -1351,9 +1419,12 @@
|
|
|
1351
1419
|
|
|
1352
1420
|
- Changelog was created.
|
|
1353
1421
|
|
|
1422
|
+
[0.6.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.4
|
|
1423
|
+
[0.6.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.3
|
|
1354
1424
|
[0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
|
|
1355
1425
|
[0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
|
|
1356
1426
|
[0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
|
|
1427
|
+
[0.5.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.16
|
|
1357
1428
|
[0.5.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.15
|
|
1358
1429
|
[0.5.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.14
|
|
1359
1430
|
[0.5.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.13
|
|
@@ -1370,6 +1441,7 @@
|
|
|
1370
1441
|
[0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
|
|
1371
1442
|
[0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
|
|
1372
1443
|
[0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
|
|
1444
|
+
[0.4.30]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.30
|
|
1373
1445
|
[0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
|
|
1374
1446
|
[0.4.28]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.28
|
|
1375
1447
|
[0.4.27]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.27
|
data/README.md
CHANGED
|
@@ -75,10 +75,14 @@ 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?
|
|
81
|
-
.repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "
|
|
85
|
+
.repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "prod"], install: "#{ENV["HOME"]}/.bin", ref: :node) # Repo (optional)
|
|
82
86
|
.run("rake install", ref: :ruby)
|
|
83
87
|
.depend(false, group: "default")
|
|
84
88
|
.clean("rake clean", group: "default")
|
|
@@ -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
|
|
|
@@ -782,7 +792,7 @@ REPO_DEV # pattern,0,1
|
|
|
782
792
|
REPO_PROD # pattern,0,1
|
|
783
793
|
REPO_WARN # 0,1
|
|
784
794
|
REPO_SYNC # 0,1
|
|
785
|
-
|
|
795
|
+
REPO_GIT # manifest repository
|
|
786
796
|
REPO_MANIFEST # e.g. latest,nightly,prod
|
|
787
797
|
REPO_GROUPS # e.g. base,prod,docs
|
|
788
798
|
REPO_STAGE # 0,1,2,3,4
|
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)
|
|
@@ -185,6 +189,10 @@ module Squared
|
|
|
185
189
|
end
|
|
186
190
|
|
|
187
191
|
def log_message(level, *args, subject: nil, hint: nil, append: true, pass: false, color: ARG[:COLOR])
|
|
192
|
+
if args.empty?
|
|
193
|
+
args.concat(Array(level))
|
|
194
|
+
level = Logger::INFO
|
|
195
|
+
end
|
|
188
196
|
args = args.map(&:to_s)
|
|
189
197
|
if level.is_a?(::Numeric)
|
|
190
198
|
if append && respond_to?(:log)
|
|
@@ -192,9 +200,9 @@ module Squared
|
|
|
192
200
|
ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(::Logger)
|
|
193
201
|
end
|
|
194
202
|
end
|
|
195
|
-
return false
|
|
203
|
+
return false unless pass || level >= ARG[:LEVEL]
|
|
196
204
|
end
|
|
197
|
-
if
|
|
205
|
+
if hint.nil? ? args.size > 1 : !hint
|
|
198
206
|
title = log_title(level, color: false)
|
|
199
207
|
emphasize(args,
|
|
200
208
|
title: title + (subject ? " #{subject}" : ''),
|
|
@@ -204,7 +212,9 @@ module Squared
|
|
|
204
212
|
end)
|
|
205
213
|
else
|
|
206
214
|
msg = [log_title(level, color: color)]
|
|
207
|
-
|
|
215
|
+
if subject
|
|
216
|
+
msg << (color ? sub_style(subject.to_s, (@theme.is_a?(::Hash) && @theme[:subject]) || :bold) : subject)
|
|
217
|
+
end
|
|
208
218
|
msg << args.shift if msg.size == 1
|
|
209
219
|
message(msg.join(' '), *args, hint: hint)
|
|
210
220
|
end
|
|
@@ -236,7 +246,7 @@ module Squared
|
|
|
236
246
|
end
|
|
237
247
|
|
|
238
248
|
def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
|
|
239
|
-
border: @theme && @theme[:border])
|
|
249
|
+
border: @theme.is_a?(::Hash) && @theme[:border])
|
|
240
250
|
n = 0
|
|
241
251
|
max = ->(a) { n = [n, a.max_by(&:size).size].max }
|
|
242
252
|
set = ->(s) { Array(s).map(&:to_s).tap { |a| max.call(a) } }
|
|
@@ -257,17 +267,19 @@ module Squared
|
|
|
257
267
|
out = []
|
|
258
268
|
draw = lambda do |a, b|
|
|
259
269
|
ret = a + (b1 * (n + 2)) + b
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
next ret unless border
|
|
271
|
+
|
|
272
|
+
sub_style ret, border
|
|
262
273
|
end
|
|
263
274
|
sub = sub.is_a?(::Hash) ? [sub] : Array(sub)
|
|
264
275
|
pr = lambda do |line|
|
|
265
276
|
s = line.ljust(n)
|
|
266
|
-
sub.each { |h|
|
|
277
|
+
sub.each { |h| sub_style!(s, **h) }
|
|
267
278
|
s = "#{b0} #{s} #{b0}"
|
|
268
279
|
if border
|
|
269
|
-
|
|
270
|
-
|
|
280
|
+
[[/\A(#{Regexp.escape(b0)})(.+)\z/om], [/\A(.+)(#{Regexp.escape(b0)})\z/om, 2]].each do |args|
|
|
281
|
+
sub_style!(s, **opt_style(border, *args))
|
|
282
|
+
end
|
|
271
283
|
end
|
|
272
284
|
s
|
|
273
285
|
end
|
|
@@ -282,7 +294,7 @@ module Squared
|
|
|
282
294
|
unless sub.empty? && !right
|
|
283
295
|
footer.map! do |s|
|
|
284
296
|
s = s.rjust(n + 4) if right
|
|
285
|
-
sub.each { |h|
|
|
297
|
+
sub.each { |h| sub_style!(s, **h) }
|
|
286
298
|
s
|
|
287
299
|
end
|
|
288
300
|
end
|
|
@@ -291,17 +303,16 @@ module Squared
|
|
|
291
303
|
if block_given?
|
|
292
304
|
yield out
|
|
293
305
|
elsif pipe
|
|
306
|
+
return out if pipe == -1
|
|
307
|
+
|
|
294
308
|
case pipe
|
|
295
|
-
when -1
|
|
296
|
-
return out
|
|
297
309
|
when 0
|
|
298
|
-
|
|
310
|
+
$stdin
|
|
299
311
|
when 2
|
|
300
|
-
|
|
312
|
+
$stderr
|
|
301
313
|
else
|
|
302
|
-
pipe
|
|
303
|
-
end
|
|
304
|
-
pipe.puts out
|
|
314
|
+
pipe.respond_to?(:puts) ? pipe : $stdout
|
|
315
|
+
end.puts(out)
|
|
305
316
|
else
|
|
306
317
|
err ? warn(out) : puts(out)
|
|
307
318
|
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
|
@@ -10,10 +10,11 @@ module Squared
|
|
|
10
10
|
private_constant :QUOTE_VALUE
|
|
11
11
|
|
|
12
12
|
String.define_method(:stripquote) { sub(QUOTE_VALUE, '\2') }
|
|
13
|
+
Array.define_method(:quote!) { |**kwargs| map! { |s| Shell.shell_quote(s, **kwargs) } }
|
|
13
14
|
|
|
14
15
|
module_function
|
|
15
16
|
|
|
16
|
-
def shell_escape(val, quote: false,
|
|
17
|
+
def shell_escape(val, quote: false, option: false, force: false, double: false, override: false)
|
|
17
18
|
if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
|
|
18
19
|
if (data = r[2].match(QUOTE_VALUE))
|
|
19
20
|
double = data[1] == '"'
|
|
@@ -31,7 +32,7 @@ module Squared
|
|
|
31
32
|
r[7]
|
|
32
33
|
end
|
|
33
34
|
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}[
|
|
35
|
+
elsif option && val =~ /\A(-{0,2}[^=\s-][^=\s]*)=(.+)\z/m
|
|
35
36
|
return val if $2.match?(QUOTE_VALUE)
|
|
36
37
|
|
|
37
38
|
"#{$1}=%s" % if $2.include?(' ')
|
|
@@ -55,7 +56,7 @@ module Squared
|
|
|
55
56
|
return val if (!force && !val.include?(' ')) || val.empty?
|
|
56
57
|
|
|
57
58
|
if option
|
|
58
|
-
pat = /\A(?:-[
|
|
59
|
+
pat = /\A(?:-[^=\s-](?:=|\s+)?|(--)?[^=\s-][^=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
|
|
59
60
|
return val if val.match?(pat)
|
|
60
61
|
end
|
|
61
62
|
q = ->(s) { s.gsub("'\\\\''", "'") }
|
|
@@ -103,7 +104,7 @@ module Squared
|
|
|
103
104
|
end
|
|
104
105
|
|
|
105
106
|
def shell_split(val, join: nil, **kwargs)
|
|
106
|
-
ret = val.shellsplit.map! { |opt| shell_escape(opt,
|
|
107
|
+
ret = val.shellsplit.map! { |opt| shell_escape(opt, option: true, double: true, **kwargs) }
|
|
107
108
|
return ret unless join
|
|
108
109
|
|
|
109
110
|
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