squared 0.4.14 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -58
- data/README.md +4 -4
- data/README.ruby.md +15 -12
- data/lib/squared/common/base.rb +7 -8
- data/lib/squared/common/format.rb +3 -9
- data/lib/squared/common/prompt.rb +36 -40
- data/lib/squared/common/shell.rb +13 -8
- data/lib/squared/common/system.rb +45 -48
- data/lib/squared/common/utils.rb +3 -19
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +16 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +27 -40
- data/lib/squared/workspace/project/base.rb +128 -196
- data/lib/squared/workspace/project/docker.rb +37 -38
- data/lib/squared/workspace/project/git.rb +113 -139
- data/lib/squared/workspace/project/node.rb +64 -49
- data/lib/squared/workspace/project/python.rb +57 -251
- data/lib/squared/workspace/project/ruby.rb +119 -139
- data/lib/squared/workspace/project/support/class.rb +73 -34
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +6 -7
- data/lib/squared/workspace/series.rb +8 -8
- data/lib/squared/workspace/support/data.rb +3 -2
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +1 -1
- metadata +2 -3
- data/lib/squared/common/class.rb +0 -110
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46ea608e0b2d67acb3d15eaf67d7c70fc4c301c1c7ebf0dbfa9fba2e9ccabe0b
|
4
|
+
data.tar.gz: 806aeee453718e1ff75f1f83c3f2ac763fd989cdddeca18b570a1d383c90484c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcde780730f2426af5561183d7d33d172f7dc7a096f9b21b3098593e18758a6a5bdb26e40ccabfaf7e0cf2e6963f067289c304e2e7626b85c15dd2c589e907e0
|
7
|
+
data.tar.gz: efcae50c9cfd39b72c013035df135533fee434e7985c3896d409a3d2d1850f16c2c7d2dd811e89431ddc46e2fbc64f752ece5bc8f1205d79d052bcec59fb7749
|
data/CHANGELOG.md
CHANGED
@@ -1,66 +1,29 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [0.
|
3
|
+
## [0.5.0] - 2025-06-16
|
4
4
|
|
5
5
|
### Added
|
6
6
|
|
7
|
-
-
|
8
|
-
-
|
9
|
-
- Python command run detects program tool scripts.
|
10
|
-
- Git command stash action branch was implemented.
|
11
|
-
- Docker command compose action exec and run are interactive.
|
12
|
-
- Double dash can be used to end parsing for options.
|
13
|
-
- Python command outdated tasks with semver was implemented.
|
7
|
+
- Node command exec through NVM was implemented.
|
8
|
+
- Git command options were updated to version 2.49.
|
14
9
|
|
15
10
|
### Changed
|
16
11
|
|
17
|
-
-
|
18
|
-
-
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
22
|
-
-
|
23
|
-
- Ruby public method irb parameter load was renamed args.
|
12
|
+
- Gem specification required Ruby version set to 2.5.
|
13
|
+
- Docker build options from ENV do not require dashes.
|
14
|
+
- Unused task descriptions are not generated.
|
15
|
+
- Class object shapes were declared in initialize.
|
16
|
+
- Project outdated interactive uses a more compact prompt.
|
17
|
+
- Workspace banner configuration uses a struct.
|
24
18
|
|
25
|
-
###
|
26
|
-
|
27
|
-
- Box border did not print corners on Windows.
|
28
|
-
- Index character was not captured on Windows.
|
29
|
-
- Node command publish did not prompt for package to publish.
|
30
|
-
- Python command publish did not prompt for package to publish.
|
31
|
-
- Project confirmation accept dialog did not always quit.
|
32
|
-
- Git command add did not detect when no files were changed.
|
33
|
-
|
34
|
-
## [0.3.12] - 2025-07-05
|
35
|
-
|
36
|
-
### Fixed
|
37
|
-
|
38
|
-
- Gem command exec did not include gem option flag.
|
39
|
-
- Project graph did not print first level border.
|
40
|
-
- Node command update did not use correct event name.
|
41
|
-
- Gem command push did not validate gem file to publish.
|
42
|
-
- Node command publish did not publish when silent.
|
43
|
-
|
44
|
-
## [0.2.12] - 2025-07-05
|
45
|
-
|
46
|
-
### Fixed
|
47
|
-
|
48
|
-
- See `0.1.9`.
|
49
|
-
|
50
|
-
## [0.1.9] - 2025-07-05
|
51
|
-
|
52
|
-
### Added
|
19
|
+
### Removed
|
53
20
|
|
54
|
-
-
|
55
|
-
-
|
21
|
+
- Git commit hash identifier uses only a colon for a prefix.
|
22
|
+
- Common module for classes was delegated to support namespaces.
|
56
23
|
|
57
24
|
### Fixed
|
58
25
|
|
59
|
-
- Project
|
60
|
-
- Directory context was not threaded using JRuby.
|
61
|
-
- Index character was not captured on Windows.
|
62
|
-
- Common method is used for Kernel shell commands.
|
63
|
-
- Git did not highlight output for single commands.
|
26
|
+
- Project private variables external modification was revised.
|
64
27
|
|
65
28
|
## [0.4.13] - 2025-06-16
|
66
29
|
|
@@ -115,8 +78,6 @@
|
|
115
78
|
|
116
79
|
## [0.3.11] - 2025-05-15
|
117
80
|
|
118
|
-
### Fixed
|
119
|
-
|
120
81
|
- See `0.2.11`.
|
121
82
|
|
122
83
|
## [0.2.11] - 2025-05-15
|
@@ -379,8 +340,6 @@
|
|
379
340
|
|
380
341
|
## [0.3.7] - 2025-04-08
|
381
342
|
|
382
|
-
### Fixed
|
383
|
-
|
384
343
|
- See `0.2.7`.
|
385
344
|
|
386
345
|
## [0.2.7] - 2025-04-08
|
@@ -802,7 +761,7 @@
|
|
802
761
|
|
803
762
|
- Changelog was created.
|
804
763
|
|
805
|
-
[0.
|
764
|
+
[0.5.0]: https://github.com/anpham6/squared/releases/tag/v0.5.0-ruby
|
806
765
|
[0.4.13]: https://github.com/anpham6/squared/releases/tag/v0.4.13-ruby
|
807
766
|
[0.4.12]: https://github.com/anpham6/squared/releases/tag/v0.4.12-ruby
|
808
767
|
[0.4.11]: https://github.com/anpham6/squared/releases/tag/v0.4.11-ruby
|
@@ -817,7 +776,6 @@
|
|
817
776
|
[0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
|
818
777
|
[0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
|
819
778
|
[0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
|
820
|
-
[0.3.12]: https://github.com/anpham6/squared/releases/tag/v0.3.12-ruby
|
821
779
|
[0.3.11]: https://github.com/anpham6/squared/releases/tag/v0.3.11-ruby
|
822
780
|
[0.3.10]: https://github.com/anpham6/squared/releases/tag/v0.3.10-ruby
|
823
781
|
[0.3.9]: https://github.com/anpham6/squared/releases/tag/v0.3.9-ruby
|
@@ -830,7 +788,6 @@
|
|
830
788
|
[0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
|
831
789
|
[0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
|
832
790
|
[0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
|
833
|
-
[0.2.12]: https://github.com/anpham6/squared/releases/tag/v0.2.12-ruby
|
834
791
|
[0.2.11]: https://github.com/anpham6/squared/releases/tag/v0.2.11-ruby
|
835
792
|
[0.2.10]: https://github.com/anpham6/squared/releases/tag/v0.2.10-ruby
|
836
793
|
[0.2.9]: https://github.com/anpham6/squared/releases/tag/v0.2.9-ruby
|
@@ -843,7 +800,6 @@
|
|
843
800
|
[0.2.2]: https://github.com/anpham6/squared/releases/tag/v0.2.2-ruby
|
844
801
|
[0.2.1]: https://github.com/anpham6/squared/releases/tag/v0.2.1-ruby
|
845
802
|
[0.2.0]: https://github.com/anpham6/squared/releases/tag/v0.2.0-ruby
|
846
|
-
[0.1.9]: https://github.com/anpham6/squared/releases/tag/v0.1.9-ruby
|
847
803
|
[0.1.8]: https://github.com/anpham6/squared/releases/tag/v0.1.8-ruby
|
848
804
|
[0.1.7]: https://github.com/anpham6/squared/releases/tag/v0.1.7-ruby
|
849
805
|
[0.1.6]: https://github.com/anpham6/squared/releases/tag/v0.1.6-ruby
|
data/README.md
CHANGED
@@ -140,13 +140,13 @@ rake clone # node + docs
|
|
140
140
|
# PIPE_FAIL={0,1}
|
141
141
|
# PORT=3000
|
142
142
|
docker build -t squared --build-arg MANIFEST=prod --build-arg NODE_ENV=production .
|
143
|
-
docker build -t node --build-arg NODE_TAG=22 --build-arg NODE_INSTALL=pnpm -f slim
|
143
|
+
docker build -t node --build-arg NODE_TAG=22 --build-arg NODE_INSTALL=pnpm -f Dockerfile.slim .
|
144
144
|
NODE=22 docker buildx bake node
|
145
145
|
# OR
|
146
|
-
docker build -t ruby --build-arg RUBY_TAG=3.4.0 --build-arg NODE_VERSION=22 --build-arg PIPE_FAIL=0 -f 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
147
|
RUBY=3.4.0 docker buildx bake ruby
|
148
148
|
# OR
|
149
|
-
docker build -t nginx --build-arg NGINX_VERSION=1.27 --build-arg PORT=3000 --build-arg NODE_VERSION=20 -f 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
150
|
NGINX=1.27 docker buildx bake nginx
|
151
151
|
|
152
152
|
# Express
|
@@ -1359,4 +1359,4 @@ NOTE: Defining an element "**id**" will prevent it from being removed during the
|
|
1359
1359
|
|
1360
1360
|
## LICENSE
|
1361
1361
|
|
1362
|
-
BSD 3-Clause
|
1362
|
+
BSD 3-Clause
|
data/README.ruby.md
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
# squared 0.
|
1
|
+
# squared 0.5
|
2
2
|
|
3
3
|
* [source](https://github.com/anpham6/squared)
|
4
4
|
* [docs](https://squared.readthedocs.io)
|
5
5
|
|
6
6
|
## Version Compatibility
|
7
7
|
|
8
|
-
| Date | squared | Min | Max |
|
9
|
-
| :--------: | ------: | -----: | -----: |
|
10
|
-
| 2024-12-07 | 0.1.0 | 2.4.0 | 3.3.6 |
|
11
|
-
| 2025-01-07 | 0.2.0 |
|
12
|
-
| 2025-02-07 | 0.3.0 |
|
13
|
-
| 2025-03-06 | 0.4.0 |
|
8
|
+
| Date | squared | Min | Max |
|
9
|
+
| :--------: | ------: | -----: | -----: |
|
10
|
+
| 2024-12-07 | 0.1.0 | 2.4.0 | 3.3.6 |
|
11
|
+
| 2025-01-07 | 0.2.0 | | 3.4.0 |
|
12
|
+
| 2025-02-07 | 0.3.0 | | 3.4.1 |
|
13
|
+
| 2025-03-06 | 0.4.0 | | 3.4.2 |
|
14
|
+
| 2025-06-16 | 0.5.0 | 2.5.0 | 3.4.3 |
|
14
15
|
|
15
16
|
The range chart indicates the latest Ruby tested against at the time of release.
|
16
17
|
|
@@ -263,7 +264,7 @@ Workspace::Application
|
|
263
264
|
add("squared") do
|
264
265
|
revbuild(include: %w[src/ framework/ types/]) # Git revision build command (optional)
|
265
266
|
chain "all", "revbuild", after: "express:build" # step: 4
|
266
|
-
chain "publish", "bump:patch", "publish:latest", step: 0, sync: true # rake publish
|
267
|
+
chain "publish", "bump:patch", "publish:latest", step: 0, sync: true # rake publish
|
267
268
|
end
|
268
269
|
end
|
269
270
|
.with(:python) do
|
@@ -275,12 +276,12 @@ Workspace::Application
|
|
275
276
|
chain "all", "doc", with: "squared", before: "squared:revbuild" # Same
|
276
277
|
end
|
277
278
|
end
|
278
|
-
.chain
|
279
|
+
.chain("all", "status", with: "squared", after: "android-docs") # Global tasks (e.g. without ":")
|
279
280
|
.build
|
280
281
|
```
|
281
282
|
|
282
283
|
```sh
|
283
|
-
rake all
|
284
|
+
rake all # all[1-3-4]
|
284
285
|
rake all:print
|
285
286
|
```
|
286
287
|
|
@@ -508,7 +509,7 @@ Most project classes will inherit from `Git` which enables these tasks:
|
|
508
509
|
| restore | restore | staged worktree |
|
509
510
|
| rev | rev | commit output |
|
510
511
|
| show | show | format oneline |
|
511
|
-
| stash | stash | push pop apply
|
512
|
+
| stash | stash | push pop apply drop list |
|
512
513
|
| switch | switch | create detach merge |
|
513
514
|
| tag | tag | add sign delete list |
|
514
515
|
|
@@ -537,7 +538,6 @@ Commands which use commit hashes are parsed using a ":" prefix as to not be conf
|
|
537
538
|
|
538
539
|
```sh
|
539
540
|
rake squared:log:view[:af012345] # git log af012345
|
540
|
-
rake squared:log:view[#{af012345}] # deprecated
|
541
541
|
rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- 'lib' 'H12345'
|
542
542
|
```
|
543
543
|
|
@@ -683,6 +683,9 @@ DOCKER_TAG=latest # all
|
|
683
683
|
DOCKER_TAG_${NAME}=v0.1.0 # project only (override)
|
684
684
|
DOCKER_ALL=1 # list every image/container
|
685
685
|
DOCKER_Y=1 # confirm all
|
686
|
+
|
687
|
+
BUILD_SQUARED_OPTS="NODE_TAG=24 RUBY_VERSION=3.4.0" DOCKER_SQUARED_OPTS="--no-cache --label=v1" rake squared:build
|
688
|
+
docker build --no-cache --label=v1 --build-arg='NODE_TAG=24' --build-arg='RUBY_VERSION=3.4.0' .
|
686
689
|
```
|
687
690
|
|
688
691
|
| Command | Flag | ENV |
|
data/lib/squared/common/base.rb
CHANGED
@@ -63,7 +63,6 @@ module Squared
|
|
63
63
|
hash: %i[green black!],
|
64
64
|
array: %i[blue black!],
|
65
65
|
number: [:magenta],
|
66
|
-
boolean: [:magenta],
|
67
66
|
undefined: %i[red italic]
|
68
67
|
},
|
69
68
|
logger: {
|
@@ -100,22 +99,22 @@ module Squared
|
|
100
99
|
|
101
100
|
module_function
|
102
101
|
|
103
|
-
def as_a(obj, meth
|
102
|
+
def as_a(obj, *meth, flat: nil, compact: false, &blk)
|
104
103
|
return [] if obj.nil?
|
105
104
|
|
106
105
|
unless obj.is_a?(::Array)
|
107
|
-
obj = if obj.respond_to?(:
|
108
|
-
obj.to_ary
|
109
|
-
elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
|
106
|
+
obj = if obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
|
110
107
|
val
|
111
108
|
else
|
112
109
|
[obj]
|
113
110
|
end
|
114
111
|
end
|
115
|
-
obj = flat.is_a?(::Numeric) ?
|
112
|
+
obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
|
116
113
|
obj = obj.compact if compact
|
117
|
-
obj = obj.map(&meth)
|
118
|
-
|
114
|
+
obj = obj.map(&meth.shift) until meth.empty?
|
115
|
+
return obj unless block_given?
|
116
|
+
|
117
|
+
obj.select(&blk)
|
119
118
|
end
|
120
119
|
end
|
121
120
|
end
|
@@ -29,19 +29,13 @@ module Squared
|
|
29
29
|
bright_white!: '107'
|
30
30
|
}.freeze
|
31
31
|
BOX_GRAPH = ['│', '─', '├', '└', '┬'].freeze
|
32
|
-
BOX_BORDER = ['│', '─', '
|
33
|
-
if ENV['TERM']&.end_with?('256color')
|
34
|
-
val.slice!(2, 4)
|
35
|
-
val.insert(2, '╭', '╮', '╯', '╰')
|
36
|
-
end
|
37
|
-
val.freeze
|
38
|
-
end
|
32
|
+
BOX_BORDER = ['│', '─', '╭', '╮', '╯', '╰', '├', '┤', '┬', '┴'].freeze
|
39
33
|
TEXT_STYLE = [:bold, :dim, :italic, :underline, :blinking, nil, :inverse, :hidden, :strikethrough].freeze
|
40
34
|
private_constant :AIX_TERM, :BOX_GRAPH, :BOX_BORDER, :TEXT_STYLE
|
41
35
|
|
42
36
|
def enable_aixterm
|
43
37
|
unless (colors = __get__(:colors)).frozen?
|
44
|
-
colors.
|
38
|
+
colors.update(AIX_TERM)
|
45
39
|
end
|
46
40
|
self
|
47
41
|
end
|
@@ -67,7 +61,7 @@ module Squared
|
|
67
61
|
end
|
68
62
|
wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
|
69
63
|
code = []
|
70
|
-
args.concat(
|
64
|
+
args.concat(as_a(styles)).flatten.each_with_index do |type, i|
|
71
65
|
next unless type
|
72
66
|
|
73
67
|
if index == -1
|
@@ -11,24 +11,22 @@ module Squared
|
|
11
11
|
agree = /^#{Regexp.escape(agree)}$/i if agree.is_a?(::String)
|
12
12
|
cancel = /^#{Regexp.escape(cancel)}$/i if cancel.is_a?(::String)
|
13
13
|
Timeout.timeout(timeout) do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
return false
|
22
|
-
end
|
23
|
-
attempts -= 1
|
24
|
-
exit 1 unless attempts > 0
|
14
|
+
while (ch = Readline.readline(msg))
|
15
|
+
ch = ch.chomp
|
16
|
+
case (ch.empty? ? default : ch)
|
17
|
+
when agree
|
18
|
+
return true
|
19
|
+
when cancel
|
20
|
+
return false
|
25
21
|
end
|
26
|
-
|
27
|
-
|
28
|
-
exit 0
|
29
|
-
else
|
30
|
-
false
|
22
|
+
attempts -= 1
|
23
|
+
exit 1 unless attempts > 0
|
31
24
|
end
|
25
|
+
rescue Interrupt
|
26
|
+
puts
|
27
|
+
exit 0
|
28
|
+
else
|
29
|
+
false
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
@@ -37,7 +35,7 @@ module Squared
|
|
37
35
|
require 'readline'
|
38
36
|
require 'timeout'
|
39
37
|
if list
|
40
|
-
grep &&=
|
38
|
+
grep &&= (grep.is_a?(::Enumerable) ? grep : [grep]).map { |val| Regexp.new(val) }
|
41
39
|
items = []
|
42
40
|
list.each do |val|
|
43
41
|
next if grep&.none? { |pat| pat.match?(line) }
|
@@ -56,33 +54,31 @@ module Squared
|
|
56
54
|
end
|
57
55
|
valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max) }
|
58
56
|
Timeout.timeout(timeout) do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
next if multiple.is_a?(::Numeric) && multiple != b.size
|
57
|
+
while (ch = Readline.readline(msg))
|
58
|
+
unless (ch = ch.strip).empty?
|
59
|
+
if multiple
|
60
|
+
a = ch.split(/\s*,\s*/)
|
61
|
+
b = a.select { |s| valid.call(s) }.map!(&:to_i).sort
|
62
|
+
next unless a.size == b.size
|
63
|
+
return b unless items
|
64
|
+
next if multiple.is_a?(::Numeric) && multiple != b.size
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
66
|
+
return b.map! { |i| items[i - 1] }
|
67
|
+
elsif valid.call(ch)
|
68
|
+
return items ? items[ch.to_i - 1] : ch.to_i
|
73
69
|
end
|
74
|
-
attempts -= 1
|
75
|
-
next if attempts > 0
|
76
|
-
break unless force
|
77
|
-
|
78
|
-
exit 1
|
79
70
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
71
|
+
attempts -= 1
|
72
|
+
next if attempts > 0
|
73
|
+
break unless force
|
74
|
+
|
75
|
+
exit 1
|
85
76
|
end
|
77
|
+
rescue Interrupt
|
78
|
+
puts
|
79
|
+
exit 0
|
80
|
+
else
|
81
|
+
multiple ? [] : nil
|
86
82
|
end
|
87
83
|
end
|
88
84
|
|
data/lib/squared/common/shell.rb
CHANGED
@@ -85,26 +85,31 @@ module Squared
|
|
85
85
|
end}"
|
86
86
|
end
|
87
87
|
|
88
|
-
def shell_split(val,
|
88
|
+
def shell_split(val, join: nil, **kwargs)
|
89
89
|
ret = val.shellsplit
|
90
|
-
ret.map! { |opt| shell_escape(opt,
|
90
|
+
ret.map! { |opt| shell_escape(opt, double: true, option: true, **kwargs) }
|
91
91
|
return ret unless join
|
92
92
|
|
93
93
|
ret.join(join.is_a?(::String) ? join : ' ')
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
96
|
+
def line_width(lines)
|
97
|
+
ret = [lines.max_by(&:size).size, 80].max
|
98
|
+
[ret, Rake.application.terminal_width].min
|
99
|
+
end
|
100
|
+
|
101
|
+
def fill_option(val, **kwargs)
|
97
102
|
return "-#{val}" if val.match?(/\A(?:[a-z]\d*|\d)\z/i)
|
98
103
|
|
99
|
-
shell_escape(val.start_with?('-') ? val : "--#{val}",
|
104
|
+
shell_escape(val.start_with?('-') ? val : "--#{val}", **kwargs)
|
100
105
|
end
|
101
106
|
|
102
|
-
def quote_option(flag, val,
|
103
|
-
shell_option(flag, val, escape: false,
|
107
|
+
def quote_option(flag, val, **kwargs)
|
108
|
+
shell_option(flag, val, escape: false, **kwargs)
|
104
109
|
end
|
105
110
|
|
106
|
-
def basic_option(flag, val,
|
107
|
-
shell_option(flag, val, escape: false, force: false,
|
111
|
+
def basic_option(flag, val, **kwargs)
|
112
|
+
shell_option(flag, val, escape: false, force: false, **kwargs)
|
108
113
|
end
|
109
114
|
end
|
110
115
|
end
|
@@ -1,55 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'pathname'
|
4
|
-
require '
|
4
|
+
require 'fileutils'
|
5
5
|
|
6
6
|
module Squared
|
7
7
|
module Common
|
8
8
|
module System
|
9
9
|
module_function
|
10
10
|
|
11
|
-
def shell(*args,
|
12
|
-
if
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
else
|
19
|
-
ret = Kernel.send(name, *args)
|
20
|
-
end
|
21
|
-
elsif RUBY_VERSION < '2.6'
|
22
|
-
e = kwargs.delete(:exception)
|
23
|
-
ret = Kernel.send(name, *args, **kwargs)
|
11
|
+
def shell(*args, **kwargs)
|
12
|
+
if RUBY_VERSION < '2.6'
|
13
|
+
exception = kwargs.delete(:exception)
|
14
|
+
ret = Kernel.system(*args, **kwargs)
|
15
|
+
return ret if ret || !exception
|
16
|
+
|
17
|
+
raise $?.to_s
|
24
18
|
else
|
25
|
-
|
19
|
+
Kernel.system(*args, **kwargs)
|
26
20
|
end
|
27
|
-
return ret if ret || !e
|
28
|
-
|
29
|
-
raise $?.to_s
|
30
21
|
end
|
31
22
|
|
32
|
-
def copy_dir(src, dest, glob = ['**/*'], create: false, link: nil, force: false, pass: nil,
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
def copy_dir(src, dest, glob = ['**/*'], create: false, link: nil, force: false, pass: nil, hidden: false,
|
24
|
+
verbose: true)
|
25
|
+
base = Pathname.new(src)
|
26
|
+
target = Pathname.new(dest)
|
27
|
+
raise "#{target.cleanpath} (not found)" if !create && !target.parent.exist?
|
36
28
|
|
37
29
|
subdir = {}
|
38
|
-
|
30
|
+
target.mkpath if create
|
31
|
+
flags = hidden ? [File::FNM_DOTMATCH] : []
|
39
32
|
if pass
|
40
33
|
exclude = []
|
41
|
-
|
34
|
+
pass = [pass] unless pass.is_a?(::Array)
|
35
|
+
pass.each { |val| exclude.concat(Dir.glob(val, *flags, base: base)) }
|
42
36
|
end
|
43
|
-
|
44
|
-
Dir.glob(
|
45
|
-
next if exclude&.include?(
|
37
|
+
(glob.is_a?(::Enumerable) ? glob : [glob]).each do |val|
|
38
|
+
Dir.glob(val, *flags, base: base) do |file|
|
39
|
+
next if exclude&.include?(file) || (entry = base + file).directory?
|
46
40
|
|
47
|
-
dir =
|
41
|
+
dir = target.join(file).dirname
|
48
42
|
if (data = subdir[dir.to_s])
|
49
|
-
data <<
|
43
|
+
data << entry
|
50
44
|
else
|
51
45
|
dir.mkpath
|
52
|
-
subdir[dir.to_s] = [
|
46
|
+
subdir[dir.to_s] = [entry]
|
53
47
|
end
|
54
48
|
end
|
55
49
|
end
|
@@ -57,23 +51,24 @@ module Squared
|
|
57
51
|
soft = 0
|
58
52
|
subdir.each do |dir, files|
|
59
53
|
if link
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
54
|
+
files.dup.yield_self do |items|
|
55
|
+
files.clear
|
56
|
+
items.each do |file|
|
57
|
+
if file.exist?
|
58
|
+
if file.symlink?
|
59
|
+
next unless force
|
60
|
+
else
|
61
|
+
files << file
|
62
|
+
next
|
63
|
+
end
|
64
|
+
end
|
65
|
+
if link == 'hard'
|
66
|
+
FileUtils.ln(file, dir, force: force, verbose: false)
|
66
67
|
else
|
67
|
-
|
68
|
-
next
|
68
|
+
FileUtils.ln_s(file, dir, force: force, verbose: false)
|
69
69
|
end
|
70
|
+
soft += 1
|
70
71
|
end
|
71
|
-
if link == 'hard'
|
72
|
-
FileUtils.ln(file, dir, force: force, verbose: false)
|
73
|
-
else
|
74
|
-
FileUtils.ln_s(file, dir, force: force, verbose: false)
|
75
|
-
end
|
76
|
-
soft += 1
|
77
72
|
end
|
78
73
|
end
|
79
74
|
next if files.empty?
|
@@ -81,15 +76,17 @@ module Squared
|
|
81
76
|
out = FileUtils.cp(files, dir, verbose: false)
|
82
77
|
count += out.size
|
83
78
|
end
|
84
|
-
puts [
|
79
|
+
puts [target.realpath, subdir.size, soft > 0 ? "#{count}+#{soft}" : count].join(' => ') if verbose
|
85
80
|
end
|
86
81
|
|
87
82
|
def copy_guard(src, dest, link: nil, force: false, verbose: true)
|
88
83
|
unless force
|
89
|
-
|
90
|
-
|
84
|
+
target = Pathname.new(dest)
|
85
|
+
if target.directory?
|
86
|
+
src = [src] unless src.is_a?(::Enumerable)
|
87
|
+
src = src.reject { |val| target.join(File.basename(val)).exist? }
|
91
88
|
return if src.empty?
|
92
|
-
elsif
|
89
|
+
elsif target.exist?
|
93
90
|
return
|
94
91
|
end
|
95
92
|
end
|
data/lib/squared/common/utils.rb
CHANGED
@@ -17,13 +17,13 @@ module Squared
|
|
17
17
|
val = val.strip
|
18
18
|
return [val, '', ''] unless (i = val.index('='))
|
19
19
|
|
20
|
-
last = val[
|
20
|
+
last = val[i + 1..-1].strip
|
21
21
|
quote = ''
|
22
22
|
if last =~ /\A(["'])(.+)\1\z/
|
23
23
|
last = $2
|
24
24
|
quote = $1
|
25
25
|
end
|
26
|
-
[val[0..
|
26
|
+
[val[0..i - 1], last, quote]
|
27
27
|
end
|
28
28
|
|
29
29
|
def task_invoke(*cmd, args: [], exception: true, warning: true)
|
@@ -88,18 +88,6 @@ module Squared
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
def time_offset(val = nil)
|
92
|
-
val = DateTime.parse(val) if val.is_a?(::String)
|
93
|
-
cur = DateTime.now
|
94
|
-
ret = 0
|
95
|
-
if (r = /^([+-])(\d+):(\d+):(\d+)$/.match((val || cur).strftime('%::z')))
|
96
|
-
ret += (r[1] == '+' ? -1 : 1) * ((r[2].to_i * 60 * 60) + (r[3].to_i * 60) + r[4].to_i) * 1000
|
97
|
-
end
|
98
|
-
return ret unless val
|
99
|
-
|
100
|
-
(cur.strftime('%Q').to_i + time_offset) - (val.strftime('%Q').to_i + ret)
|
101
|
-
end
|
102
|
-
|
103
91
|
def time_since(val, ms: true)
|
104
92
|
s = ms ? '%s%L' : '%s'
|
105
93
|
Time.now.utc.strftime(s).to_i - Time.parse(val).utc.strftime(s).to_i
|
@@ -109,11 +97,7 @@ module Squared
|
|
109
97
|
ret = env_value(key, suffix: suffix, strict: strict)
|
110
98
|
return ret == equals.to_s unless equals.nil?
|
111
99
|
|
112
|
-
ret.empty? || (ignore &&
|
113
|
-
end
|
114
|
-
|
115
|
-
def env_key(*val)
|
116
|
-
val.join('_').gsub(/\W+/, '_').upcase
|
100
|
+
ret.empty? || (ignore && as_a(ignore).any? { |val| val.to_s == ret }) ? default : ret
|
117
101
|
end
|
118
102
|
|
119
103
|
def env_value(key, default = '', suffix: nil, strict: false)
|