squared 0.0.9 → 0.0.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/README.md +2 -6
- data/README.ruby.md +112 -33
- data/lib/squared/common/base.rb +12 -4
- data/lib/squared/common/format.rb +45 -31
- data/lib/squared/common/shell.rb +16 -7
- data/lib/squared/common/system.rb +5 -5
- data/lib/squared/common/task.rb +1 -1
- data/lib/squared/common/utils.rb +60 -0
- data/lib/squared/common.rb +1 -0
- data/lib/squared/config.rb +18 -15
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +104 -70
- data/lib/squared/workspace/project/base.rb +304 -118
- data/lib/squared/workspace/project/git.rb +43 -52
- data/lib/squared/workspace/project/node.rb +125 -126
- data/lib/squared/workspace/project/python.rb +23 -3
- data/lib/squared/workspace/project/ruby.rb +129 -116
- data/lib/squared/workspace/repo.rb +82 -88
- data/lib/squared/workspace/series.rb +15 -13
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71eae17e75e9ebe9a4fbe250f49da6397b169f06ac85c7f77170b9fc575bd63e
|
4
|
+
data.tar.gz: f68b5c36da52802d0b952c54a406d6d6bde3085308c465c2f058c8c944dce894
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 515aa7c65dd969fb9dd165a38716695a6c08ccbf0597ef3d7936bcd70750c2c54f661fc44e9dc303d34b8d99947d27939039654ca5ffd43afcf33f917deb2866
|
7
|
+
data.tar.gz: cfe3827d03d56619de9d3c60a4df2b249ff1f802bc9a6be407b96c5db95fb14faf6b3719e657c83dc046287d62272f1cf2e676fdad67da345abc93675e511474
|
data/README.md
CHANGED
@@ -16,9 +16,6 @@
|
|
16
16
|
* [E-mc](https://github.com/anpham6/e-mc#readme)
|
17
17
|
* [Pi-r](https://github.com/anpham6/pi-r#readme)
|
18
18
|
|
19
|
-
> [!NOTE]
|
20
|
-
> `squared-express` originally was intended to be used as a HTTP/1.1 insecure development server for Android projects. `E-mc` was created a few years later to produce static outputs for any kind of development accessible through a simple REST API. Gradually any new development that calls the REST API will use [NGINX Unit](https://unit.nginx.org) as the *production* application runtime to efficiently serve static assets. Middleware and application code can be conducted in the same manner with Express and other programming frameworks (e.g. Ruby). Maintanence updates with subsequent `E-mc` releases supporting legacy development environments will be tested only against `Express 4.19` although most existing applications can be upgraded without any problems. Upgrading to `Express 5` is not recommended as it offers no new noticeable features (e.g. HTTP/2) and possibly compatibility issues with template libraries.
|
21
|
-
|
22
19
|
## Installation
|
23
20
|
|
24
21
|
* NodeJS 16 LTS
|
@@ -113,14 +110,13 @@ cd workspaces # REPO_ROOT
|
|
113
110
|
|
114
111
|
wget https://raw.githubusercontent.com/anpham6/squared/master/Rakefile
|
115
112
|
|
116
|
-
# REPO_DOCS=1 (venv)
|
117
113
|
rake -T # List tasks
|
118
114
|
|
119
115
|
# REPO_BUILD={dev,prod}
|
120
116
|
# PIPE_FAIL=1
|
121
117
|
rake repo:init # nightly
|
122
|
-
#
|
123
|
-
rake repo:init[
|
118
|
+
rake repo:init[latest] # squared
|
119
|
+
rake repo:init[0.11.x] # e-mc
|
124
120
|
# OR
|
125
121
|
REPO_ROOT=/tmp/123 NODE_INSTALL=pnpm repo:init
|
126
122
|
```
|
data/README.ruby.md
CHANGED
@@ -4,9 +4,17 @@
|
|
4
4
|
* [manifest](https://github.com/anpham6/squared-repo)
|
5
5
|
* [docs](https://squared.readthedocs.io)
|
6
6
|
|
7
|
-
##
|
7
|
+
## Version Compatibility
|
8
8
|
|
9
|
-
|
9
|
+
| Date | squared | Ruby 2 | Ruby 3 |
|
10
|
+
| :------: | ------: | -----: | -----: |
|
11
|
+
| 12-07-24 | 0.1.0 | 2.4.0 | 3.0.0 |
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```sh
|
16
|
+
gem install squared
|
17
|
+
```
|
10
18
|
|
11
19
|
### Optional
|
12
20
|
|
@@ -20,12 +28,6 @@ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
|
|
20
28
|
chmod a+rx ~/.bin/repo
|
21
29
|
```
|
22
30
|
|
23
|
-
## Installation
|
24
|
-
|
25
|
-
```sh
|
26
|
-
gem install squared
|
27
|
-
```
|
28
|
-
|
29
31
|
## Example - Rakefile
|
30
32
|
|
31
33
|
Projects from any accessible folder can be added either relative to `REPO_ROOT` or absolutely. The same Rakefile can also manage other similarly cloned repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
|
@@ -36,24 +38,44 @@ require "squared/workspace/repo" # Repo (optional)
|
|
36
38
|
|
37
39
|
# NODE_ENV = production
|
38
40
|
# REPO_ROOT = /workspaces
|
39
|
-
# REPO_HOME = /workspaces/squared
|
41
|
+
# REPO_HOME = /workspaces/squared (Dir.pwd)
|
40
42
|
# rake = /workspaces/squared/Rakefile
|
43
|
+
# pathname = /workspaces/pathname
|
44
|
+
# optparse = /workspaces/optparse
|
45
|
+
# log = /workspaces/logger
|
46
|
+
# emc = /workspaces/e-mc
|
47
|
+
# pir = /workspaces/pi-r
|
48
|
+
# squared = /workspaces/squared
|
49
|
+
# cli = /workspaces/squared/publish/sqd-cli
|
50
|
+
# sqd-serve = /workspaces/squared/publish/sqd-serve
|
51
|
+
# sqd = /workspaces/squared/sqd
|
41
52
|
|
42
53
|
Workspace::Application
|
43
|
-
.new(main: "squared") # Dir.pwd? (main? is implicitly basename)
|
54
|
+
.new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
|
44
55
|
.banner("group", "project", styles: %i[yellow black], border: "bold") # name | project | path | ref | group?
|
45
|
-
.repo("https://github.com/anpham6/squared-repo", "nightly",
|
56
|
+
.repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "build:prod"], ref: :node) # Repo (optional)
|
46
57
|
.run("rake install", ref: :ruby)
|
47
58
|
.depend(false, group: "default")
|
48
59
|
.clean("rake clean", group: "default")
|
49
60
|
.clean(["build/"], group: "app")
|
50
|
-
.
|
61
|
+
.log({ file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app")
|
62
|
+
.add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", env: { # Ruby (with C extensions)
|
63
|
+
"CFLAGS" => "-fPIC -O1"
|
64
|
+
})
|
51
65
|
.add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
|
52
66
|
.add("logger", copy: { from: "lib", glob: "**/*.rb", gemdir: "~/.rvm/gems/ruby-3.3.5/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
|
53
|
-
.add("
|
54
|
-
.add("
|
55
|
-
.add("squared",
|
56
|
-
|
67
|
+
.add("e-mc", "emc", copy: { from: "publish", into: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
|
68
|
+
.add("pi-r", "pir", copy: { from: "publish", into: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
|
69
|
+
.add("squared", script: ["build:stage1", "build:stage2"], group: "app") do # Copy target (main)
|
70
|
+
add("publish/sqd-cli", "cli", exclude: [:git])
|
71
|
+
add("publish/sqd-serve")
|
72
|
+
add("publish/sqd-admin", group: "sqd", exclude: [:base])
|
73
|
+
end
|
74
|
+
.add("squared/sqd", exclude: [:git]) do
|
75
|
+
variable_set :script, "build:sqd" # Override detection
|
76
|
+
variable_set :depend, false
|
77
|
+
variable_set :clean, ["build/sqd/"]
|
78
|
+
end
|
57
79
|
.style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
|
58
80
|
.build(default: "status", parallel: ["pull", "fetch", "rebase", "copy", "clean"]) do |workspace|
|
59
81
|
workspace
|
@@ -63,16 +85,17 @@ Workspace::Application
|
|
63
85
|
border: "bright_white"
|
64
86
|
})
|
65
87
|
end
|
66
|
-
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
88
|
+
|
89
|
+
# default = /workspaces/ruby/*
|
90
|
+
# pathname = /workspaces/ruby/pathname
|
91
|
+
# optparse = /workspaces/ruby/optparse
|
92
|
+
# logger = /workspaces/ruby/logger
|
93
|
+
# android = /workspaces/android-docs
|
94
|
+
# chrome = /workspaces/chrome-docs
|
72
95
|
|
73
96
|
Workspace::Application
|
74
|
-
.new(ENV["
|
75
|
-
.group("
|
97
|
+
.new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
|
98
|
+
.group("ruby", "default", run: "rake build", copy: "rake install", clean: "rake clean", ref: :ruby, override: {
|
76
99
|
pathname: {
|
77
100
|
run: "rake compile" # rake rb:pathname:build
|
78
101
|
}
|
@@ -82,17 +105,11 @@ Workspace::Application
|
|
82
105
|
doc("make html") # rake rb:doc:python
|
83
106
|
run(false) # rake rb:build:python (disabled)
|
84
107
|
exclude(%i[base git]) # Project::Git.ref (superclass)
|
85
|
-
add("android", "android
|
86
|
-
add("chrome", "chrome
|
108
|
+
add("android-docs", "android") # rake rb:android:doc
|
109
|
+
add("chrome-docs", "chrome") # rake rb:chrome:doc
|
87
110
|
end #
|
88
111
|
.style("inline", "bold")
|
89
112
|
.build
|
90
|
-
# default = /workspaces/ruby/*
|
91
|
-
# pathname = /workspaces/ruby/pathname
|
92
|
-
# optparse = /workspaces/ruby/optparse
|
93
|
-
# logger = /workspaces/ruby/logger
|
94
|
-
# android = /workspaces/android-docs
|
95
|
-
# chrome = /workspaces/chrome-docs
|
96
113
|
```
|
97
114
|
|
98
115
|
**NOTE**: The use of "**ref**" (class name) is only necessary when running `repo:init` for the first time into an empty directory.
|
@@ -123,7 +140,16 @@ rake clean:app # none + skip + ["build/"]
|
|
123
140
|
rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
|
124
141
|
```
|
125
142
|
|
126
|
-
|
143
|
+
```sh
|
144
|
+
rake build:app # squared + cli + sqd-serve
|
145
|
+
rake squared:build:workspace # cli + sqd-serve
|
146
|
+
rake pull:sqd # sqd-admin
|
147
|
+
rake squared:pull:workspace # sqd-serve + sqd-admin
|
148
|
+
```
|
149
|
+
|
150
|
+
## Methods
|
151
|
+
|
152
|
+
Task:
|
127
153
|
|
128
154
|
* run
|
129
155
|
* depend
|
@@ -131,6 +157,11 @@ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
|
|
131
157
|
* doc
|
132
158
|
* clean
|
133
159
|
|
160
|
+
Non-task:
|
161
|
+
|
162
|
+
* log
|
163
|
+
* exclude
|
164
|
+
|
134
165
|
## Styles
|
135
166
|
|
136
167
|
* banner
|
@@ -139,6 +170,54 @@ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
|
|
139
170
|
* active
|
140
171
|
* inline
|
141
172
|
* major
|
173
|
+
* red
|
174
|
+
* yellow
|
175
|
+
* green
|
176
|
+
|
177
|
+
## Environment
|
178
|
+
|
179
|
+
### Build
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# LD_LIBRARY_PATH="path/to/lib" CFLAGS="-Wall" gcc a.c -o a.o -c
|
183
|
+
BUILD_${NAME} # gcc a.c -o a.o
|
184
|
+
BUILD_${NAME}_OPTS # -c
|
185
|
+
BUILD_${NAME}_ENV # {"LD_LIBRARY_PATH":"path/to/lib","CFLAGS":"-Wall"} (json)
|
186
|
+
|
187
|
+
# Scripts
|
188
|
+
BUILD_${NAME}_DEV # pattern,0,1
|
189
|
+
BUILD_${NAME}_PROD # pattern,0,1
|
190
|
+
```
|
191
|
+
|
192
|
+
These options also support the project specific suffix `${NAME}`. (e.g. LOG_FILE_SQUARED)
|
193
|
+
|
194
|
+
### Logger
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
LOG_FILE # %Y-%m-%d.log
|
198
|
+
# OR
|
199
|
+
LOG_AUTO # year,y,month,m,day,d,1
|
200
|
+
# Optional
|
201
|
+
LOG_DIR # exist?
|
202
|
+
LOG_LEVEL # See gem "logger"
|
203
|
+
LOG_COLUMNS # terminal width (default: 80)
|
204
|
+
```
|
205
|
+
|
206
|
+
### Repo
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
REPO_ROOT # parent dir
|
210
|
+
REPO_HOME # project dir (main)
|
211
|
+
REPO_BUILD # run,script
|
212
|
+
REPO_GROUP # string
|
213
|
+
REPO_REF # e.g. ruby,node
|
214
|
+
REPO_DEV # pattern,0,1
|
215
|
+
REPO_PROD # pattern,0,1
|
216
|
+
REPO_WARN # 0,1
|
217
|
+
REPO_SYNC # 0,1
|
218
|
+
REPO_MANIFEST # e.g. latest,nightly,prod
|
219
|
+
REPO_TIMEOUT # confirm dialog (seconds)
|
220
|
+
```
|
142
221
|
|
143
222
|
## LICENSE
|
144
223
|
|
data/lib/squared/common/base.rb
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
module Squared
|
4
4
|
module Common
|
5
|
+
KEY = {
|
6
|
+
PIPE: 1,
|
7
|
+
FAIL: false,
|
8
|
+
COMMON: true
|
9
|
+
}
|
5
10
|
VAR = {
|
6
11
|
project: {},
|
7
12
|
colors: {
|
@@ -86,11 +91,14 @@ module Squared
|
|
86
91
|
def as_a(obj, meth = nil, flat: nil, compact: false)
|
87
92
|
return [] if obj.nil?
|
88
93
|
|
89
|
-
|
90
|
-
obj =
|
91
|
-
|
92
|
-
|
94
|
+
unless obj.is_a?(::Array)
|
95
|
+
obj = if !obj.is_a?(::Hash) && obj.respond_to?(:to_a) && (val = obj.to_a).is_a?(::Array)
|
96
|
+
val
|
97
|
+
else
|
98
|
+
[obj]
|
99
|
+
end
|
93
100
|
end
|
101
|
+
obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
|
94
102
|
obj = obj.map(&meth) if meth
|
95
103
|
compact ? obj.compact : obj
|
96
104
|
end
|
@@ -61,7 +61,7 @@ module Squared
|
|
61
61
|
else
|
62
62
|
s = ret
|
63
63
|
end
|
64
|
-
if type.is_a?(Numeric)
|
64
|
+
if type.is_a?(::Numeric)
|
65
65
|
f, b = type.to_s.split('.')
|
66
66
|
s = wrap.(s, ['38', '5', f]) if f[0] != '-' && f.to_i <= 255
|
67
67
|
if b
|
@@ -77,7 +77,7 @@ module Squared
|
|
77
77
|
code << c
|
78
78
|
end
|
79
79
|
else
|
80
|
-
next unless (n = TEXT_STYLE.index
|
80
|
+
next unless (n = TEXT_STYLE.index(t))
|
81
81
|
|
82
82
|
s = "\x1B[#{n + 1}m#{s}\x1B[#{n == 0 ? 22 : n + 21}m"
|
83
83
|
end
|
@@ -110,7 +110,7 @@ module Squared
|
|
110
110
|
ret = []
|
111
111
|
colors = __get__(:colors)
|
112
112
|
as_a(args, flat: true, compact: true).each do |val|
|
113
|
-
if !val.is_a?(Numeric)
|
113
|
+
if !val.is_a?(::Numeric)
|
114
114
|
val = val.to_sym
|
115
115
|
ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
|
116
116
|
elsif val >= 0 && val <= 256
|
@@ -124,38 +124,40 @@ module Squared
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def apply_style(data, key, *args, empty: true)
|
127
|
-
data = __get__(:theme)[data]
|
128
|
-
return unless data
|
127
|
+
return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
|
129
128
|
|
130
|
-
set = ->(k, v) { data[k
|
131
|
-
if key.is_a?(Hash)
|
132
|
-
key.each { |k, v| set.(k, v || args
|
129
|
+
set = ->(k, v) { data[k] = check_style(v, empty: empty) }
|
130
|
+
if key.is_a?(::Hash)
|
131
|
+
key.each { |k, v| set.(k, v || args) }
|
133
132
|
else
|
134
|
-
set.(key, args
|
133
|
+
set.(key.to_sym, args)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def log_sym(level)
|
138
|
+
if level.is_a?(::Numeric)
|
139
|
+
case level
|
140
|
+
when Logger::DEBUG
|
141
|
+
:debug
|
142
|
+
when Logger::INFO
|
143
|
+
:info
|
144
|
+
when Logger::WARN
|
145
|
+
:warn
|
146
|
+
when Logger::ERROR
|
147
|
+
:error
|
148
|
+
when Logger::FATAL
|
149
|
+
:fatal
|
150
|
+
else
|
151
|
+
:unknown
|
152
|
+
end
|
153
|
+
else
|
154
|
+
level.to_s.downcase.to_sym
|
135
155
|
end
|
136
156
|
end
|
137
157
|
|
138
158
|
def log_title(level, color: true)
|
139
|
-
level = if level.is_a?(::Numeric)
|
140
|
-
case level
|
141
|
-
when Logger::DEBUG
|
142
|
-
:debug
|
143
|
-
when Logger::INFO
|
144
|
-
:info
|
145
|
-
when Logger::WARN
|
146
|
-
:warn
|
147
|
-
when Logger::ERROR
|
148
|
-
:error
|
149
|
-
when Logger::FATAL
|
150
|
-
:fatal
|
151
|
-
else
|
152
|
-
:unknown
|
153
|
-
end
|
154
|
-
else
|
155
|
-
level.to_s.downcase.to_sym
|
156
|
-
end
|
157
159
|
theme = __get__(:theme)[:logger]
|
158
|
-
styles = theme[level] || theme[level = :unknown]
|
160
|
+
styles = theme[level = log_sym(level)] || theme[level = :unknown]
|
159
161
|
case (ret = +level.to_s.upcase)
|
160
162
|
when 'WARN', 'ERROR', 'FATAL'
|
161
163
|
ret += '!'
|
@@ -164,9 +166,21 @@ module Squared
|
|
164
166
|
end
|
165
167
|
|
166
168
|
def log_message(level, *args, subject: nil, hint: nil, color: true)
|
167
|
-
|
168
|
-
|
169
|
-
|
169
|
+
args = args.map(&:to_s)
|
170
|
+
if args.size > 1
|
171
|
+
title = log_title(level, color: false)
|
172
|
+
sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
|
173
|
+
emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
|
174
|
+
else
|
175
|
+
msg = [log_title(level, color: color)]
|
176
|
+
if subject
|
177
|
+
msg << (color ? sub_style(subject, :underline) : subject)
|
178
|
+
else
|
179
|
+
msg += args
|
180
|
+
args.clear
|
181
|
+
end
|
182
|
+
message(msg.join(' '), *args, hint: hint)
|
183
|
+
end
|
170
184
|
end
|
171
185
|
|
172
186
|
def raise_error(*args, hint: nil, kind: ArgumentError)
|
data/lib/squared/common/shell.rb
CHANGED
@@ -11,16 +11,29 @@ module Squared
|
|
11
11
|
def shell_escape(val, quote: false)
|
12
12
|
return Shellwords.escape(val) unless ::Rake::Win32.windows?
|
13
13
|
|
14
|
-
quote ? shell_quote(
|
14
|
+
quote ? shell_quote(opt, force: false) : opt
|
15
15
|
end
|
16
16
|
|
17
17
|
def shell_quote(val, force: true)
|
18
18
|
ret = val.to_s.strip
|
19
|
-
return ret if (!force && !ret.include?(' ')) || ret =~ /(
|
19
|
+
return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|\S=|[^=]\s+)(["']).+\1$/m
|
20
20
|
|
21
21
|
::Rake::Win32.windows? ? "\"#{double_quote(ret)}\"" : "'#{single_quote(ret)}'"
|
22
22
|
end
|
23
23
|
|
24
|
+
def shell_split(val, quote: false, join: false)
|
25
|
+
ret = Shellwords.split(val).map do |opt|
|
26
|
+
if (data = /^(--?[^= ]+)(=|\s+)?(["'])?(.+?)\3?$/m.match(opt))
|
27
|
+
next opt unless data[2] && !data[3]
|
28
|
+
|
29
|
+
data[1] + data[2] + shell_quote(data[4], force: !::Rake::Win32.windows?)
|
30
|
+
else
|
31
|
+
shell_escape(opt, quote: quote)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
join ? ret.join(' ') : ret
|
35
|
+
end
|
36
|
+
|
24
37
|
def fill_option(val)
|
25
38
|
return "-#{val}" if val.size == 1 || val =~ /^[a-z]\d+$/i
|
26
39
|
|
@@ -37,11 +50,7 @@ module Squared
|
|
37
50
|
end
|
38
51
|
|
39
52
|
def split_escape(val, char: ',')
|
40
|
-
val.split(/\s*(?<!\\)#{char}\s*/)
|
41
|
-
end
|
42
|
-
|
43
|
-
def sanitize_args(*opts)
|
44
|
-
opts.map { |val| val.include?(' ') ? shell_quote(val) : shell_escape(val) }.join(' ')
|
53
|
+
val.split(/\s*(?<!\\)#{char}\s*/o)
|
45
54
|
end
|
46
55
|
end
|
47
56
|
end
|
@@ -20,11 +20,11 @@ module Squared
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def confirm(msg, agree: 'Y', cancel: 'N',
|
23
|
+
def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
|
24
24
|
require 'readline'
|
25
25
|
require 'timeout'
|
26
|
-
agree = /^#{agree}$/i if agree.is_a?(String)
|
27
|
-
cancel = /^#{cancel}$/i if cancel.is_a?(String)
|
26
|
+
agree = /^#{agree}$/i if agree.is_a?(::String)
|
27
|
+
cancel = /^#{cancel}$/i if cancel.is_a?(::String)
|
28
28
|
Timeout.timeout(timeout) do
|
29
29
|
begin
|
30
30
|
while (ch = Readline.readline(msg, true))
|
@@ -64,7 +64,7 @@ module Squared
|
|
64
64
|
|
65
65
|
target = dest.join(ent.relative_path_from(src))
|
66
66
|
dir = target.dirname
|
67
|
-
|
67
|
+
unless subdir.include?(dir.to_s)
|
68
68
|
dir.mkpath
|
69
69
|
subdir << dir.to_s
|
70
70
|
end
|
@@ -76,7 +76,7 @@ module Squared
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def copy_f(src, dest, overwrite: true, verbose: false)
|
79
|
-
|
79
|
+
unless overwrite
|
80
80
|
path = Pathname.new(dest)
|
81
81
|
if path.directory?
|
82
82
|
src = [src] unless src.is_a?(::Array)
|
data/lib/squared/common/task.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Common
|
5
|
+
module Utils
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def env_value(key, suffix: nil)
|
9
|
+
if suffix
|
10
|
+
ret = ENV["#{key}_#{suffix}"]
|
11
|
+
return ret unless ret.nil?
|
12
|
+
end
|
13
|
+
ENV.fetch(key, '')
|
14
|
+
end
|
15
|
+
|
16
|
+
def env_bool(key, default = false, suffix: nil)
|
17
|
+
return default if key.nil?
|
18
|
+
|
19
|
+
if key.is_a?(::String)
|
20
|
+
case env_value(key, suffix: suffix)
|
21
|
+
when ''
|
22
|
+
default
|
23
|
+
when '0', 'false'
|
24
|
+
false
|
25
|
+
else
|
26
|
+
true
|
27
|
+
end
|
28
|
+
else
|
29
|
+
key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def env_pipe(key, default = 1, suffix: nil)
|
34
|
+
if key.is_a?(::String)
|
35
|
+
case (ret = env_value(key, suffix: suffix))
|
36
|
+
when '0', '1', '2'
|
37
|
+
ret.to_i
|
38
|
+
else
|
39
|
+
default
|
40
|
+
end
|
41
|
+
else
|
42
|
+
key.is_a?(::Numeric) && key >= 0 && key <= 2 ? key : default
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def env_match(key, default = nil, suffix: nil, options: 0, timeout: nil)
|
47
|
+
case (ret = env_value(key, suffix: suffix))
|
48
|
+
when ''
|
49
|
+
default
|
50
|
+
when '0'
|
51
|
+
false
|
52
|
+
when '1'
|
53
|
+
true
|
54
|
+
else
|
55
|
+
Regexp.new(ret, options, timeout: timeout)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/squared/common.rb
CHANGED
data/lib/squared/config.rb
CHANGED
@@ -9,6 +9,7 @@ module Squared
|
|
9
9
|
class Viewer
|
10
10
|
include Common
|
11
11
|
include Format
|
12
|
+
include Utils
|
12
13
|
include ::Rake::DSL
|
13
14
|
|
14
15
|
class << self
|
@@ -18,8 +19,11 @@ module Squared
|
|
18
19
|
end
|
19
20
|
|
20
21
|
attr_reader :main, :name, :project, :theme
|
22
|
+
attr_accessor :pipe
|
21
23
|
|
22
|
-
def initialize(main, name = nil,
|
24
|
+
def initialize(main, name = nil,
|
25
|
+
project: nil, prefix: nil, dump: nil, opts: {}, auto: true,
|
26
|
+
common: Common::KEY[:COMMON], pipe: Common::KEY[:PIPE], **)
|
23
27
|
if project
|
24
28
|
main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
|
25
29
|
@required = true
|
@@ -30,6 +34,7 @@ module Squared
|
|
30
34
|
@dump = dump
|
31
35
|
@mime = {}
|
32
36
|
@theme = common ? __get__(:theme)[:viewer] : {}
|
37
|
+
@pipe = env_pipe(pipe, @project ? @project.pipe : 1)
|
33
38
|
if exist?
|
34
39
|
@main = main.chomp(@ext)
|
35
40
|
@name = @main unless @name || @required
|
@@ -106,7 +111,8 @@ module Squared
|
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
109
|
-
rescue LoadError, NameError
|
114
|
+
rescue LoadError, NameError => e
|
115
|
+
project&.log&.warn e
|
110
116
|
self
|
111
117
|
else
|
112
118
|
@mime[type] = opts
|
@@ -122,7 +128,7 @@ module Squared
|
|
122
128
|
|
123
129
|
ext = mime_type(file)
|
124
130
|
type = type&.to_s || ext
|
125
|
-
|
131
|
+
unless parse
|
126
132
|
case type
|
127
133
|
when 'json'
|
128
134
|
parse = 'JSON'
|
@@ -190,7 +196,7 @@ module Squared
|
|
190
196
|
.realpath
|
191
197
|
.to_s
|
192
198
|
.sub(Regexp.new("^#{Regexp.escape(File.join(Dir.pwd, ''))}"), '')
|
193
|
-
sub =
|
199
|
+
sub = unless stdin?
|
194
200
|
[
|
195
201
|
{ pat: /^((?:[^:]|(?<! ):(?! ))+)$/, styles: theme[:banner] },
|
196
202
|
{ pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: theme[:undefined], index: 2 },
|
@@ -202,7 +208,7 @@ module Squared
|
|
202
208
|
{ pat: /^(.+ : (?!undefined))([^"\[{].*)$/m, styles: theme[:value], index: 2 }
|
203
209
|
]
|
204
210
|
end
|
205
|
-
emphasize(lines, title: title, sub: sub)
|
211
|
+
emphasize(lines, title: title, sub: sub, pipe: pipe == 2 ? $stderr : nil)
|
206
212
|
end
|
207
213
|
|
208
214
|
def print_keys(type, data, keys, file: nil)
|
@@ -233,13 +239,13 @@ module Squared
|
|
233
239
|
$2 ? ".#{s}" : "#{s}."
|
234
240
|
end
|
235
241
|
end
|
236
|
-
out << [key,
|
242
|
+
out << [key, stdin? ? JSON.dump(nil) : 'undefined']
|
237
243
|
else
|
238
|
-
out << [key, @dump == 'json' ||
|
244
|
+
out << [key, @dump == 'json' || stdin? ? JSON.dump(val) : val.inspect]
|
239
245
|
end
|
240
246
|
pad = [pad, key.size].max
|
241
247
|
end
|
242
|
-
if
|
248
|
+
if stdin?
|
243
249
|
puts out.map(&:last).join("\n")
|
244
250
|
else
|
245
251
|
out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
|
@@ -279,16 +285,13 @@ module Squared
|
|
279
285
|
!@ext.empty? && (!@required || !project.nil?)
|
280
286
|
end
|
281
287
|
|
282
|
-
def pipe?
|
283
|
-
return project.workspace.pipe if project
|
284
|
-
|
285
|
-
val = ENV['PIPE_OUT']
|
286
|
-
!val.nil? && !val.empty? && val != '0'
|
287
|
-
end
|
288
|
-
|
289
288
|
def warning?
|
290
289
|
project ? project.workspace.warning : true
|
291
290
|
end
|
291
|
+
|
292
|
+
def stdin?
|
293
|
+
pipe == 0
|
294
|
+
end
|
292
295
|
end
|
293
296
|
end
|
294
297
|
end
|
data/lib/squared/version.rb
CHANGED