squared 0.1.11 → 0.2.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 +65 -86
- data/README.md +1289 -240
- data/README.ruby.md +384 -0
- data/lib/squared/app.rb +0 -2
- data/lib/squared/common/base.rb +23 -20
- data/lib/squared/common/class.rb +18 -1
- data/lib/squared/common/format.rb +20 -22
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +22 -14
- data/lib/squared/common/system.rb +66 -39
- data/lib/squared/common/utils.rb +6 -6
- data/lib/squared/config.rb +130 -84
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +174 -69
- data/lib/squared/workspace/project/base.rb +368 -185
- data/lib/squared/workspace/project/git.rb +728 -278
- data/lib/squared/workspace/project/node.rb +179 -119
- data/lib/squared/workspace/project/python.rb +190 -75
- data/lib/squared/workspace/project/ruby.rb +342 -178
- data/lib/squared/workspace/repo.rb +38 -47
- data/lib/squared/workspace/series.rb +16 -14
- data/squared.gemspec +3 -4
- metadata +4 -17
data/README.ruby.md
ADDED
@@ -0,0 +1,384 @@
|
|
1
|
+
# squared 0.2
|
2
|
+
|
3
|
+
* [source](https://github.com/anpham6/squared)
|
4
|
+
* [manifest](https://github.com/anpham6/squared-repo)
|
5
|
+
* [docs](https://squared.readthedocs.io)
|
6
|
+
|
7
|
+
## Version Compatibility
|
8
|
+
|
9
|
+
| Date | squared | Min | Max |
|
10
|
+
| :--------: | ------: | -----: | -----: |
|
11
|
+
| 2024-12-07 | 0.1.0 | 2.4.0 | 3.3.6 |
|
12
|
+
| 2025-01-07 | 0.2.0 | 2.4.0 | 3.4.0 |
|
13
|
+
|
14
|
+
The range chart indicates the latest Ruby tested against at the time of release.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
```sh
|
19
|
+
gem install squared
|
20
|
+
```
|
21
|
+
|
22
|
+
### Optional
|
23
|
+
|
24
|
+
* [Repo](https://source.android.com/docs/setup/reference/repo)
|
25
|
+
* Python 3.6
|
26
|
+
* Not compatible with Windows
|
27
|
+
|
28
|
+
```sh
|
29
|
+
mkdir -p ~/.bin
|
30
|
+
PATH="${HOME}/.bin:${PATH}"
|
31
|
+
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
|
32
|
+
chmod a+rx ~/.bin/repo
|
33
|
+
```
|
34
|
+
|
35
|
+
## Example - Rakefile
|
36
|
+
|
37
|
+
Projects from any accessible folder can be added relative to the parent directory (e.g. *REPO_ROOT*) or absolutely. The same Rakefile can also manage other similarly cloned `Repo` repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require "squared"
|
41
|
+
|
42
|
+
require "squared/workspace"
|
43
|
+
require "squared/workspace/repo" # Optional
|
44
|
+
require "squared/workspace/project/node" #
|
45
|
+
require "squared/workspace/project/python" #
|
46
|
+
require "squared/workspace/project/ruby" #
|
47
|
+
# OR
|
48
|
+
require "squared/app" # All workspace related modules
|
49
|
+
|
50
|
+
# NODE_ENV = production
|
51
|
+
|
52
|
+
# REPO_ROOT = /workspaces #
|
53
|
+
# REPO_HOME = /workspaces/squared # Dir.pwd
|
54
|
+
# rake = /workspaces/squared/Rakefile # main?
|
55
|
+
# OR
|
56
|
+
# REPO_ROOT = /workspaces # Dir.pwd
|
57
|
+
# rake = /workspaces/Rakefile #
|
58
|
+
# REPO_HOME = /workspaces/squared # main: "squared"
|
59
|
+
|
60
|
+
# pathname = /workspaces/pathname
|
61
|
+
# optparse = /workspaces/optparse
|
62
|
+
# log = /workspaces/logger
|
63
|
+
# emc = /workspaces/e-mc
|
64
|
+
# pir = /workspaces/pi-r
|
65
|
+
# squared = /workspaces/squared
|
66
|
+
# cli = /workspaces/squared/publish/sqd-cli
|
67
|
+
# sqd-serve = /workspaces/squared/publish/sqd-serve
|
68
|
+
# sqd = /workspaces/squared/sqd
|
69
|
+
|
70
|
+
Workspace::Application
|
71
|
+
.new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
|
72
|
+
.banner("group", "project", styles: ["yellow", "black"], border: "bold") # name | project | path | ref | group? | parent? | version?
|
73
|
+
.repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "build:prod"], ref: :node) # Repo (optional)
|
74
|
+
.run("rake install", ref: :ruby)
|
75
|
+
.depend(false, group: "default")
|
76
|
+
.clean("rake clean", group: "default")
|
77
|
+
.clean(["build/"], group: "app")
|
78
|
+
.log({ file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app")
|
79
|
+
.add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", env: { # Ruby (with C extensions)
|
80
|
+
"CFLAGS" => "-fPIC -O1"
|
81
|
+
})
|
82
|
+
.add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
|
83
|
+
.add("logger", copy: { from: "lib", glob: "**/*.rb", into: "~/.rvm/gems/ruby-3.4.0/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
|
84
|
+
.add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
|
85
|
+
.add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
|
86
|
+
.add("squared", script: ["build:stage1", "build:stage2"], group: "app") do # Copy target (main)
|
87
|
+
add("publish/sqd-cli", "cli", exclude: [:git]) # rake cli:build
|
88
|
+
add("publish/sqd-serve") # rake sqd-serve:build
|
89
|
+
add("publish/sqd-admin", group: "sqd", exclude: [:base])
|
90
|
+
# OR
|
91
|
+
with(exclude: [:base]) { add("publish/*", "packages") } # rake packages:sqd-serve:build
|
92
|
+
# OR
|
93
|
+
add(["publish/sqd-cli", "publish/sqd-serve", "publish/sqd-admin"], true, exclude: [:base]) # rake squared:sqd-serve:build
|
94
|
+
end
|
95
|
+
.add("squared/sqd", exclude: :git, pass: [:node, 'checkout', 'bump']) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
|
96
|
+
variable_set :script, "build:sqd" # Override detection
|
97
|
+
variable_set :depend, false
|
98
|
+
variable_set :clean, ["build/sqd/"]
|
99
|
+
end
|
100
|
+
.style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
|
101
|
+
.build(default: "build", parallel: ["pull", "fetch", "rebase", "copy", "clean", /^outdated:/]) do |workspace|
|
102
|
+
workspace
|
103
|
+
.enable_aixterm
|
104
|
+
.style({
|
105
|
+
banner: ["bright_cyan", "bold", "bright_black!"],
|
106
|
+
border: "bright_white"
|
107
|
+
})
|
108
|
+
end
|
109
|
+
|
110
|
+
# default = /workspaces/ruby/*
|
111
|
+
# pathname = /workspaces/ruby/pathname
|
112
|
+
# optparse = /workspaces/ruby/optparse
|
113
|
+
# logger = /workspaces/ruby/logger
|
114
|
+
# android = /workspaces/android-docs
|
115
|
+
# chrome = /workspaces/chrome-docs
|
116
|
+
|
117
|
+
Workspace::Application
|
118
|
+
.new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
|
119
|
+
.group("ruby", "default", run: "rake build", copy: "rake install", clean: "rake clean", ref: :ruby, override: {
|
120
|
+
pathname: {
|
121
|
+
run: "rake compile" # rake rb:pathname:build
|
122
|
+
}
|
123
|
+
})
|
124
|
+
.with(:python) do # ref=Symbol | group=String
|
125
|
+
banner([:name, ": ", :version], "path") # chrome-docs: 0.1.0 | /workspaces/chrome-docs
|
126
|
+
doc("make html") # rake rb:doc:python
|
127
|
+
run(false) # rake rb:build:python (disabled)
|
128
|
+
exclude(%i[base git]) # Project::Git.ref (superclass)
|
129
|
+
add("android-docs", "android") # rake rb:android:doc
|
130
|
+
add("chrome-docs", "chrome") # rake rb:chrome:doc
|
131
|
+
end
|
132
|
+
.style("inline", "bold")
|
133
|
+
.build
|
134
|
+
```
|
135
|
+
|
136
|
+
**NOTE**: The use of "**ref**" (class name) is only necessary when initializing an empty directory (e.g. *rake repo:init*).
|
137
|
+
|
138
|
+
### Clone
|
139
|
+
|
140
|
+
The task is only active when the project directory is empty or does not exist.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
Workspace::Application
|
144
|
+
.new(main: "squared")
|
145
|
+
.git(
|
146
|
+
"emc": "https://github.com/anpham6/e-mc", # rake emc:clone
|
147
|
+
"pir": { # rake pir:clone
|
148
|
+
uri: "https://github.com/anpham6/pi-r", #
|
149
|
+
options: { #
|
150
|
+
"origin": "github", # --origin='github'
|
151
|
+
"recurse-submodules": false, # --no-recurse-submodules
|
152
|
+
"shallow-exclude": ["v0.0.1", "v0.0.2"] # --shallow-exclude='v0.0.1' --shallow-exclude='v0.0.2'
|
153
|
+
}
|
154
|
+
}
|
155
|
+
)
|
156
|
+
.git("squared", "/path/to/squared", options: { local: true }) # Relative paths resolve from workspace root
|
157
|
+
.git(
|
158
|
+
{
|
159
|
+
emc: { uri: "e-mc", options: { "depth": 2 } }, # https://github.com/anpham6/e-mc
|
160
|
+
pir: "pi-r" # Maps task alias to repository folder
|
161
|
+
},
|
162
|
+
base: "https://github.com/anpham6", # Required
|
163
|
+
repo: ["squared", "android-docs", "chrome-docs"], # https://github.com/anpham6/squared
|
164
|
+
options: { # Only "repo"
|
165
|
+
"depth": 1,
|
166
|
+
"quiet": true
|
167
|
+
}
|
168
|
+
)
|
169
|
+
.with(:node) do # rake clone:node
|
170
|
+
add("e-mc", "emc") # https://github.com/anpham6/e-mc
|
171
|
+
add("pi-r", "pir") # https://github.com/anpham6/pi-r
|
172
|
+
add("squared") # https://github.com/anpham6/squared
|
173
|
+
end
|
174
|
+
.with(:python) do # rake clone:python
|
175
|
+
add("android-docs")
|
176
|
+
add("chrome-docs")
|
177
|
+
end
|
178
|
+
.git("https://github.com/anpham6") # Uses already defined root projects
|
179
|
+
.git("https://github.com/anpham6", ["emc", "pir"]) # Targets any defined project
|
180
|
+
.build(parallel: ["clone"]) # rake clone + rake clone:sync
|
181
|
+
```
|
182
|
+
|
183
|
+
### Graph
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
Workspace::Application
|
187
|
+
.new(main: "squared")
|
188
|
+
.graph(["depend"], ref: :git) # Optional
|
189
|
+
.with(:python) do
|
190
|
+
add("android-docs", "android")
|
191
|
+
add("chrome-docs", "chrome", graph: "android")
|
192
|
+
end
|
193
|
+
.with(:node) do
|
194
|
+
graph(["build", "copy"], on: { # Overrides "git"
|
195
|
+
first: proc { puts "1" },
|
196
|
+
last: proc { puts "2" }
|
197
|
+
})
|
198
|
+
add("e-mc", "emc") do
|
199
|
+
first("build", "emc:clean", "emc:depend") # rake emc:clean; rake emc:depend; rake emc:build; puts "123";
|
200
|
+
last("build", out: "123") { |out: nil| puts out } #
|
201
|
+
error("build") { |err: nil| log.debug err } #
|
202
|
+
end
|
203
|
+
add("pi-r", "pir", graph: "emc", first: {
|
204
|
+
build: proc { puts self.name } # puts "pir"
|
205
|
+
})
|
206
|
+
add("squared-express", "express", graph: "pir")
|
207
|
+
add("squared", graph: ["chrome", "express"]) do
|
208
|
+
first("git:ls-files") { puts path }
|
209
|
+
last("git:ls-files") { puts workspace.root }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
.with(:ruby) do
|
213
|
+
add("pathname")
|
214
|
+
add("fileutils", graph: "pathname")
|
215
|
+
add("optparse")
|
216
|
+
add("rake", graph: ["fileutils", "optparse"])
|
217
|
+
banner(command: false) # Always hide banner
|
218
|
+
end
|
219
|
+
.build
|
220
|
+
```
|
221
|
+
|
222
|
+
```sh
|
223
|
+
rake pir:graph # emc + pir
|
224
|
+
rake express:graph # emc + pir + express
|
225
|
+
rake chrome:graph # android + chrome
|
226
|
+
rake graph:python # same
|
227
|
+
rake squared:graph # android + chrome + emc + pir + express + squared
|
228
|
+
rake graph:node # same
|
229
|
+
rake rake:graph # pathname + fileutils + optparse + rake
|
230
|
+
rake graph:ruby # same
|
231
|
+
rake graph # graph:node + graph:ruby
|
232
|
+
```
|
233
|
+
|
234
|
+
### Batch
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
Workspace::Series.batch(:ruby, :node, {
|
238
|
+
stage: %i[graph test],
|
239
|
+
reset: %i[stash pull]
|
240
|
+
})
|
241
|
+
```
|
242
|
+
|
243
|
+
### Rename
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
Workspace::Series.rename("depend", "install")
|
247
|
+
```
|
248
|
+
|
249
|
+
## Usage
|
250
|
+
|
251
|
+
```sh
|
252
|
+
rake -T # List tasks
|
253
|
+
rake # rake status (usually "build")
|
254
|
+
|
255
|
+
# GIT_OPTIONS=rebase
|
256
|
+
rake pull # All except "default" + "app"
|
257
|
+
rake pull:ruby # pathname + optparse + logger
|
258
|
+
rake pull:default # pathname + optparse
|
259
|
+
rake pull:app # squared
|
260
|
+
rake pull:node # emc + pir + squared
|
261
|
+
|
262
|
+
rake build # All except "android"
|
263
|
+
rake doc # optparse + android
|
264
|
+
rake depend # All except "default"
|
265
|
+
|
266
|
+
rake build:ruby # rake compile + rake install + rake install
|
267
|
+
|
268
|
+
rake clean # All except "default" + "app"
|
269
|
+
rake clean:ruby # rake clean + rake clean + ["tmp/"]
|
270
|
+
rake clean:default # rake clean + rake clean + skip
|
271
|
+
rake clean:app # none + skip + ["build/"]
|
272
|
+
rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
|
273
|
+
|
274
|
+
rake squared:run[#] # List scripts (node)
|
275
|
+
rake squared:rake[#] # List tasks (ruby)
|
276
|
+
```
|
277
|
+
|
278
|
+
```sh
|
279
|
+
rake build:app # squared + cli + sqd-serve
|
280
|
+
rake squared:build:workspace # cli + sqd-serve
|
281
|
+
rake pull:sqd # sqd-admin
|
282
|
+
rake squared:pull:workspace # sqd-serve + sqd-admin
|
283
|
+
rake squared:outdated:workspace # cli + sqd-serve + sqd-admin
|
284
|
+
```
|
285
|
+
|
286
|
+
## Methods
|
287
|
+
|
288
|
+
Task:
|
289
|
+
|
290
|
+
* run
|
291
|
+
* depend
|
292
|
+
* graph
|
293
|
+
* test
|
294
|
+
* doc
|
295
|
+
* clean
|
296
|
+
|
297
|
+
Non-task:
|
298
|
+
|
299
|
+
* log
|
300
|
+
* exclude
|
301
|
+
|
302
|
+
## Styles
|
303
|
+
|
304
|
+
* banner
|
305
|
+
* border
|
306
|
+
* header
|
307
|
+
* active
|
308
|
+
* inline
|
309
|
+
* current
|
310
|
+
* major
|
311
|
+
* red
|
312
|
+
* yellow
|
313
|
+
* green
|
314
|
+
|
315
|
+
## Environment
|
316
|
+
|
317
|
+
### Path
|
318
|
+
|
319
|
+
All project executable programs can have their binary path set to a non-global alias.
|
320
|
+
|
321
|
+
```ruby
|
322
|
+
Common::PATH.merge!({
|
323
|
+
GIT: '/usr/bin/git',
|
324
|
+
GEM: '~/.rvm/rubies/ruby-3.4.0/bin/gem',
|
325
|
+
BUNDLE: '~/.rvm/gems/ruby-3.4.0/bin/bundle',
|
326
|
+
RAKE: '~/.rvm/gems/ruby-3.4.0/bin/rake',
|
327
|
+
NPM: '/opt/node/v22.0.0/bin/npm',
|
328
|
+
PYTHON: "#{ENV['PYTHONPATH']}/bin/python"
|
329
|
+
})
|
330
|
+
```
|
331
|
+
|
332
|
+
### Build
|
333
|
+
|
334
|
+
```ruby
|
335
|
+
# :env :run :opts
|
336
|
+
# LD_LIBRARY_PATH="path/to/lib" CFLAGS="-Wall" gcc a.c -o a.o -c
|
337
|
+
BUILD_${NAME} # gcc a.c -o a.o
|
338
|
+
BUILD_OPTS_${NAME} # -c
|
339
|
+
BUILD_ENV_${NAME} # {"LD_LIBRARY_PATH":"path/to/lib","CFLAGS":"-Wall"} (hash/json)
|
340
|
+
|
341
|
+
# :env :opts :script
|
342
|
+
# NODE_ENV="production" NO_COLOR="1" npm run --loglevel=error --workspaces=false build:dev
|
343
|
+
BUILD_${NAME} # build:dev
|
344
|
+
BUILD_OPTS_${NAME} # --loglevel=error --workspaces=false
|
345
|
+
BUILD_ENV_${NAME} # {"NODE_ENV":"production","NO_COLOR":"1"} (hash/json)
|
346
|
+
BUILD_DEV_${NAME} # pattern,0,1 (:dev)
|
347
|
+
BUILD_PROD_${NAME} # pattern,0,1 (:prod)
|
348
|
+
|
349
|
+
BUILD_${NAME}=0 # skip project
|
350
|
+
```
|
351
|
+
|
352
|
+
These options also support the project specific suffix `${NAME}`. (e.g. LOG_FILE_SQUARED)
|
353
|
+
|
354
|
+
### Logger
|
355
|
+
|
356
|
+
```ruby
|
357
|
+
LOG_FILE # %Y-%m-%d.log
|
358
|
+
# OR
|
359
|
+
LOG_AUTO # year,y,month,m,day,d,1
|
360
|
+
# Optional
|
361
|
+
LOG_DIR # exist?
|
362
|
+
LOG_LEVEL # See gem "logger"
|
363
|
+
LOG_COLUMNS # terminal width (default: 80)
|
364
|
+
```
|
365
|
+
|
366
|
+
### Repo
|
367
|
+
|
368
|
+
```ruby
|
369
|
+
REPO_ROOT # parent dir
|
370
|
+
REPO_HOME # project dir (main)
|
371
|
+
REPO_BUILD # run,script
|
372
|
+
REPO_GROUP # string
|
373
|
+
REPO_REF # e.g. ruby,node
|
374
|
+
REPO_DEV # pattern,0,1
|
375
|
+
REPO_PROD # pattern,0,1
|
376
|
+
REPO_WARN # 0,1
|
377
|
+
REPO_SYNC # 0,1
|
378
|
+
REPO_MANIFEST # e.g. latest,nightly,prod
|
379
|
+
REPO_TIMEOUT # confirm dialog (seconds)
|
380
|
+
```
|
381
|
+
|
382
|
+
## LICENSE
|
383
|
+
|
384
|
+
BSD 3-Clause
|
data/lib/squared/app.rb
CHANGED
data/lib/squared/common/base.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module Squared
|
4
4
|
module Common
|
5
|
+
PATH = {}
|
5
6
|
ARG = {
|
6
7
|
PIPE: 1,
|
7
8
|
OUT: nil,
|
@@ -11,6 +12,7 @@ module Squared
|
|
11
12
|
BANNER: true,
|
12
13
|
SPACE: ' => ',
|
13
14
|
GRAPH: ['│', '─', '├', '└', '┬'],
|
15
|
+
VIEW: 'view',
|
14
16
|
COLOR: ENV.fetch('NO_COLOR', '').empty?
|
15
17
|
}
|
16
18
|
VAR = {
|
@@ -35,30 +37,31 @@ module Squared
|
|
35
37
|
},
|
36
38
|
theme: {
|
37
39
|
workspace: {
|
38
|
-
header:
|
39
|
-
active:
|
40
|
-
inline:
|
41
|
-
|
40
|
+
header: [:bold],
|
41
|
+
active: [:bold],
|
42
|
+
inline: [:bold],
|
43
|
+
current: nil,
|
44
|
+
major: [:bold]
|
42
45
|
},
|
43
46
|
project: {},
|
44
47
|
viewer: {
|
45
|
-
banner:
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
banner: [:bold],
|
49
|
+
border: [:blue],
|
50
|
+
key: nil,
|
51
|
+
value: [:green],
|
52
|
+
string: [:yellow],
|
49
53
|
hash: %i[green black!],
|
50
54
|
array: %i[blue black!],
|
51
|
-
number:
|
52
|
-
boolean: %i[magenta],
|
55
|
+
number: [:magenta],
|
53
56
|
undefined: %i[red italic]
|
54
57
|
},
|
55
58
|
logger: {
|
56
|
-
unknown:
|
59
|
+
unknown: [:cyan],
|
57
60
|
fatal: %i[white bold red!],
|
58
61
|
error: %i[red bold],
|
59
62
|
warn: %i[yellow bold],
|
60
|
-
info:
|
61
|
-
debug:
|
63
|
+
info: [:blue],
|
64
|
+
debug: [:green]
|
62
65
|
}
|
63
66
|
}
|
64
67
|
}.compare_by_identity
|
@@ -77,29 +80,29 @@ module Squared
|
|
77
80
|
end
|
78
81
|
|
79
82
|
def __freeze__
|
83
|
+
PATH.freeze
|
80
84
|
ARG.freeze
|
81
85
|
VAR.each_value(&:freeze)
|
82
|
-
VAR[:theme].each_value
|
86
|
+
VAR[:theme].each_value(&:freeze)
|
83
87
|
VAR.freeze
|
84
88
|
end
|
85
89
|
|
86
90
|
module_function
|
87
91
|
|
88
|
-
def as_a(obj, meth = nil, flat: nil, compact: false)
|
92
|
+
def as_a(obj, meth = nil, flat: nil, compact: false, &blk)
|
89
93
|
return [] if obj.nil?
|
90
94
|
|
91
95
|
unless obj.is_a?(::Array)
|
92
|
-
obj = if obj.respond_to?(:
|
93
|
-
obj.to_ary
|
94
|
-
elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
|
96
|
+
obj = if obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
|
95
97
|
val
|
96
98
|
else
|
97
99
|
[obj]
|
98
100
|
end
|
99
101
|
end
|
100
|
-
obj = flat.is_a?(::Numeric) ?
|
102
|
+
obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
|
101
103
|
obj = obj.compact if compact
|
102
|
-
|
104
|
+
obj = obj.map(&meth) if meth
|
105
|
+
block_given? ? obj.select(&blk) : obj
|
103
106
|
end
|
104
107
|
end
|
105
108
|
end
|
data/lib/squared/common/class.rb
CHANGED
@@ -34,11 +34,28 @@ module Squared
|
|
34
34
|
super.match(/[^:]+\z/)[0]
|
35
35
|
end
|
36
36
|
|
37
|
+
attr_reader :delim
|
38
|
+
|
37
39
|
def initialize(data = [], delim: ' ')
|
38
40
|
super(data.compact)
|
39
41
|
@delim = delim
|
40
42
|
end
|
41
43
|
|
44
|
+
def pass(&blk)
|
45
|
+
ret = to_a.map!(&:to_s).reject(&:empty?)
|
46
|
+
block_given? ? ret.reject(&blk) : ret
|
47
|
+
end
|
48
|
+
|
49
|
+
def temp(*args, &blk)
|
50
|
+
args.compact!
|
51
|
+
ret = pass(&blk)
|
52
|
+
unless args.empty?
|
53
|
+
ret += args
|
54
|
+
ret = Set.new(ret).to_a
|
55
|
+
end
|
56
|
+
ret.join(@delim)
|
57
|
+
end
|
58
|
+
|
42
59
|
def done
|
43
60
|
ret = to_s
|
44
61
|
clear
|
@@ -46,7 +63,7 @@ module Squared
|
|
46
63
|
end
|
47
64
|
|
48
65
|
def to_s
|
49
|
-
|
66
|
+
pass.join(@delim)
|
50
67
|
end
|
51
68
|
end
|
52
69
|
end
|
@@ -53,7 +53,7 @@ module Squared
|
|
53
53
|
end
|
54
54
|
wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
|
55
55
|
code = []
|
56
|
-
args.concat(as_a(styles)).
|
56
|
+
args.concat(as_a(styles)).each_with_index do |type, i|
|
57
57
|
next unless type
|
58
58
|
|
59
59
|
if index == -1
|
@@ -114,7 +114,7 @@ module Squared
|
|
114
114
|
if !val.is_a?(::Numeric)
|
115
115
|
val = val.to_sym
|
116
116
|
ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
|
117
|
-
elsif val
|
117
|
+
elsif val >= 0 && val <= 256
|
118
118
|
ret << val
|
119
119
|
elsif val < 0 && (b = val.to_s.split('.')[1])
|
120
120
|
b = b[0..2]
|
@@ -127,26 +127,26 @@ module Squared
|
|
127
127
|
def apply_style(data, key, args, empty: true)
|
128
128
|
return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
|
129
129
|
|
130
|
-
set = ->(k, v) { data[k
|
130
|
+
set = ->(k, v) { data[k] = check_style(v, empty: empty) }
|
131
131
|
if key.is_a?(::Hash)
|
132
132
|
key.each { |k, v| set.(k, v || args) }
|
133
133
|
else
|
134
|
-
set.(key, args)
|
134
|
+
set.(key.to_sym, args)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
138
|
def log_sym(level)
|
139
139
|
if level.is_a?(::Numeric)
|
140
140
|
case level
|
141
|
-
when
|
141
|
+
when Logger::DEBUG
|
142
142
|
:debug
|
143
|
-
when
|
143
|
+
when Logger::INFO
|
144
144
|
:info
|
145
|
-
when
|
145
|
+
when Logger::WARN
|
146
146
|
:warn
|
147
|
-
when
|
147
|
+
when Logger::ERROR
|
148
148
|
:error
|
149
|
-
when
|
149
|
+
when Logger::FATAL
|
150
150
|
:fatal
|
151
151
|
else
|
152
152
|
:unknown
|
@@ -171,20 +171,24 @@ module Squared
|
|
171
171
|
if args.size > 1
|
172
172
|
title = log_title(level, color: false)
|
173
173
|
sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
|
174
|
-
emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub
|
174
|
+
emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
|
175
175
|
else
|
176
176
|
msg = [log_title(level, color: color)]
|
177
|
-
|
178
|
-
|
177
|
+
if subject
|
178
|
+
msg << (color ? sub_style(subject, :underline) : subject)
|
179
|
+
else
|
180
|
+
msg += args
|
181
|
+
args.clear
|
182
|
+
end
|
179
183
|
message(msg.join(' '), *args, hint: hint)
|
180
184
|
end
|
181
185
|
end
|
182
186
|
|
183
187
|
def puts_oe(*args, pipe: 1)
|
184
|
-
if pipe.is_a?(
|
188
|
+
if pipe.is_a?(Pathname)
|
185
189
|
begin
|
186
|
-
|
187
|
-
br =
|
190
|
+
File.open(pipe, 'a') do |f|
|
191
|
+
br = File::SEPARATOR == '\\' ? "\r\n" : "\n"
|
188
192
|
args.flatten.each { |val| f.write("#{strip_style(val.chomp)}#{br}") }
|
189
193
|
end
|
190
194
|
return
|
@@ -257,8 +261,6 @@ module Squared
|
|
257
261
|
yield out
|
258
262
|
elsif pipe
|
259
263
|
case pipe
|
260
|
-
when -1
|
261
|
-
return out
|
262
264
|
when 0
|
263
265
|
pipe = $stdin
|
264
266
|
when 2
|
@@ -276,12 +278,8 @@ module Squared
|
|
276
278
|
val.gsub(/\x1B\[(\d+;?)+m/, '')
|
277
279
|
end
|
278
280
|
|
279
|
-
def stripext(val)
|
280
|
-
File.basename(val, File.extname(val))
|
281
|
-
end
|
282
|
-
|
283
281
|
def raise_error(*args, hint: nil, kind: ArgumentError)
|
284
|
-
raise kind, message(*args, hint: hint, empty: true)
|
282
|
+
raise kind, message(*args, hint: hint, empty: true), caller_locations(1)
|
285
283
|
end
|
286
284
|
end
|
287
285
|
end
|