squared 0.7.1 → 0.7.2
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 +19 -3
- data/README.md +3 -3
- data/lib/squared/common/shell.rb +4 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/project/base.rb +122 -70
- data/lib/squared/workspace/project/docker.rb +18 -8
- data/lib/squared/workspace/project/git.rb +4 -3
- data/lib/squared/workspace/project/node.rb +44 -1
- data/lib/squared/workspace/project/python.rb +10 -1
- data/lib/squared/workspace/project/ruby.rb +45 -4
- data/lib/squared/workspace/project/support/optionpartition.rb +26 -12
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a9e8d3d41e090465c85e45088c984711f2a26f6ab2f38d56ed8b58658735f678
|
|
4
|
+
data.tar.gz: 2ff93124747a950b6ac94424052268e4ab6b107e934a2fd16478ca03d74a5409
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60b75a0d2d6c361ccf9341496b0b4e9e3a0599030ea6099f50a2819246111ff671a8f52cf583e91294593179949542f1e18814059c953007bbee528c1dbaa244
|
|
7
|
+
data.tar.gz: c52d560aacea0d6279948db05d29c1a5b5c55a5d7fb2218f03d418122417a8ca3377a1b4af54238538d4d911c4827b6a2921b76001b161a6bfdd460e55dd13e5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.7.
|
|
3
|
+
## [0.7.2] - 2026-02-09
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- OptionPartition can parse flags with a custom switch or separator.
|
|
8
|
+
- Gem command uninstall and pristine are interactive.
|
|
9
|
+
- Docker command network action create was implemented.
|
|
10
|
+
- Python command serve using http.server module was implemented.
|
|
11
|
+
- Ruby command serve using webrick was implemented.
|
|
12
|
+
- Node command serve using filename or string was implemented.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Docker task clean does not run in parallel without ENV override.
|
|
17
|
+
|
|
18
|
+
## [0.7.1] - 2026-01-20
|
|
4
19
|
|
|
5
20
|
### Added
|
|
6
21
|
|
|
@@ -14,7 +29,7 @@
|
|
|
14
29
|
|
|
15
30
|
- Git task show was completely non-functional due to excessive formatting.
|
|
16
31
|
|
|
17
|
-
## [0.7.0] -
|
|
32
|
+
## [0.7.0] - 2026-01-07
|
|
18
33
|
|
|
19
34
|
### Added
|
|
20
35
|
|
|
@@ -87,7 +102,7 @@
|
|
|
87
102
|
- Project base method command_args did not append prompted value.
|
|
88
103
|
- Bundler command exec did not use correct delegate for delete.
|
|
89
104
|
|
|
90
|
-
## [0.6.9] -
|
|
105
|
+
## [0.6.9] - 2026-01-07
|
|
91
106
|
|
|
92
107
|
### Added
|
|
93
108
|
|
|
@@ -1680,6 +1695,7 @@
|
|
|
1680
1695
|
|
|
1681
1696
|
- Changelog was created.
|
|
1682
1697
|
|
|
1698
|
+
[0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
|
|
1683
1699
|
[0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
|
|
1684
1700
|
[0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
|
|
1685
1701
|
[0.6.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.9
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
| 2025-01-07 | 0.2.0 | | 3.4.0 | |
|
|
12
12
|
| 2025-02-07 | 0.3.0 | | 3.4.1 | |
|
|
13
13
|
| 2025-03-06 | 0.4.0 | | 3.4.2 | * |
|
|
14
|
-
| 2025-06-16 | 0.5.0 | 2.5.0 | 3.4.
|
|
14
|
+
| 2025-06-16 | 0.5.0 | 2.5.0 | 3.4.4 | * |
|
|
15
15
|
| ---------- | ----- | ----- | ----- | --- |
|
|
16
16
|
| 2025-08-23 | 0.5.5 | | 3.4.5 | |
|
|
17
17
|
| 2025-10-31 | 0.6.0 | | 3.4.7 | * |
|
|
@@ -300,10 +300,10 @@ Workspace::Application
|
|
|
300
300
|
end
|
|
301
301
|
.with(:python) do
|
|
302
302
|
doc("make html")
|
|
303
|
-
add("android-docs") do
|
|
303
|
+
add("android-docs", serve: "./build/html") do # Uses built-in http.server module (ruby: webrick)
|
|
304
304
|
chain "all", "doc", with: "squared", after: "squared" # step: 4
|
|
305
305
|
end
|
|
306
|
-
add("chrome-docs") do
|
|
306
|
+
add("chrome-docs", serve: { root: "./build/html", port: 8000 }) do # root | bind | port | opts[]
|
|
307
307
|
chain "all", "doc", with: "squared", before: "squared:revbuild" # Same
|
|
308
308
|
end
|
|
309
309
|
end
|
data/lib/squared/common/shell.rb
CHANGED
|
@@ -73,7 +73,7 @@ module Squared
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def shell_option(flag, val = nil, sep: '=', escape: true, quote: true, force: true, double: false, merge: false,
|
|
76
|
-
override: false)
|
|
76
|
+
switch: nil, override: false)
|
|
77
77
|
flag = flag.to_s
|
|
78
78
|
if flag =~ QUOTE_VALUE
|
|
79
79
|
double = $1 == '"'
|
|
@@ -88,6 +88,9 @@ module Squared
|
|
|
88
88
|
else
|
|
89
89
|
merge ? '' : ' '
|
|
90
90
|
end
|
|
91
|
+
elsif switch
|
|
92
|
+
pre = switch unless flag.start_with?(switch)
|
|
93
|
+
merge ? '' : sep
|
|
91
94
|
elsif flag.size == 1
|
|
92
95
|
pre = '-'
|
|
93
96
|
merge ? '' : ' '
|
data/lib/squared/version.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Squared
|
|
|
23
23
|
|
|
24
24
|
OPTIONS = Workspace::Support.hashobj
|
|
25
25
|
VAR_SET = %i[parent global script index envname desc dependfile dependname dependindex theme archive env graph
|
|
26
|
-
dev prod timeout pass only exclude asdf].freeze
|
|
26
|
+
dev prod timeout pass only exclude serve asdf].freeze
|
|
27
27
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
|
28
28
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
|
|
29
29
|
URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
|
@@ -117,7 +117,8 @@ module Squared
|
|
|
117
117
|
subtasks({
|
|
118
118
|
'graph' => %i[run print].freeze,
|
|
119
119
|
'unpack' => %i[zip gz tar ext],
|
|
120
|
-
'asdf' => %i[set exec env current update latest where reshim]
|
|
120
|
+
'asdf' => %i[set exec env current update latest where reshim],
|
|
121
|
+
'serve' => nil
|
|
121
122
|
})
|
|
122
123
|
|
|
123
124
|
attr_reader :name, :workspace, :path, :theme, :group, :parent, :children, :dependfile,
|
|
@@ -276,80 +277,114 @@ module Squared
|
|
|
276
277
|
Base.subtasks do |action, flags|
|
|
277
278
|
next if task_pass?(action)
|
|
278
279
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
280
|
+
if flags.nil?
|
|
281
|
+
case action
|
|
282
|
+
when 'serve'
|
|
283
|
+
next unless serve?
|
|
284
|
+
|
|
285
|
+
format_desc action, nil, 'root,port?,bind?,opts*'
|
|
286
|
+
task action, [:root] do |_, args|
|
|
287
|
+
if !args.root && @serve
|
|
288
|
+
kwargs = @serve.dup
|
|
289
|
+
root = kwargs.delete(:root)
|
|
290
|
+
opts = kwargs.delete(:opts) || []
|
|
291
|
+
else
|
|
292
|
+
root = param_guard(action, 'path', args: args, key: :root)
|
|
293
|
+
opts = args.extras
|
|
294
|
+
unless opts.empty?
|
|
295
|
+
port = opts.shift
|
|
296
|
+
if port.match?(/^\d+$/)
|
|
297
|
+
bind = opts.shift
|
|
298
|
+
else
|
|
299
|
+
bind = port
|
|
300
|
+
port = nil
|
|
301
|
+
end
|
|
302
|
+
if bind&.start_with?('-')
|
|
303
|
+
opts << bind
|
|
304
|
+
bind = nil
|
|
305
|
+
end
|
|
297
306
|
end
|
|
307
|
+
kwargs = { port: port, bind: bind }.compact
|
|
298
308
|
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
unless
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
serve(basepath(root).to_s, opts, **kwargs)
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
else
|
|
313
|
+
namespace action do
|
|
314
|
+
flags.each do |flag|
|
|
315
|
+
case action
|
|
316
|
+
when 'graph'
|
|
317
|
+
break unless graph?
|
|
318
|
+
|
|
319
|
+
format_desc action, flag, '(-)project*'
|
|
320
|
+
task flag do |_, args|
|
|
321
|
+
args = args.to_a.reject { |val| val == name }
|
|
322
|
+
if flag == :run
|
|
323
|
+
graph args
|
|
324
|
+
else
|
|
325
|
+
out = graph(args, out: [], order: {})
|
|
326
|
+
emphasize(out, title: path, right: true, border: borderstyle, sub: [
|
|
327
|
+
opt_style(theme[:header], /\A(#{Regexp.escape(path.to_s)})(.*)\z/),
|
|
328
|
+
opt_style(theme[:active], /\A(#{Regexp.escape(name)})(.*)\z/),
|
|
329
|
+
opt_style(theme[:inline], /\A((?~ \() \()(\d+)(\).*)\z/, 2)
|
|
330
|
+
])
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
when 'unpack'
|
|
334
|
+
format_desc(action, flag, 'tag/url,dir,digest?,f/orce?', before: ('ext' if flag == :ext))
|
|
335
|
+
params = %i[tag dir digest force]
|
|
336
|
+
params.unshift(:ext) if flag == :ext
|
|
337
|
+
task flag, params do |_, args|
|
|
338
|
+
ext = flag == :ext ? param_guard(action, flag, args: args, key: :ext) : flag.to_s
|
|
339
|
+
tag = param_guard(action, flag, args: args, key: :tag)
|
|
340
|
+
dir = param_guard(action, flag, args: args, key: :dir)
|
|
341
|
+
unless tag.match?(URI_SCHEME)
|
|
342
|
+
tag = unpack_get tag, ext
|
|
343
|
+
tag ||= if @release
|
|
344
|
+
"%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
|
|
345
|
+
else
|
|
346
|
+
raise_error ArgumentError, "no base uri: #{tag}", hint: ext
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
force = case (digest = args.digest)
|
|
350
|
+
when 'f', 'force'
|
|
351
|
+
digest = nil
|
|
352
|
+
true
|
|
311
353
|
else
|
|
312
|
-
|
|
354
|
+
args.fetch(:force, false)
|
|
313
355
|
end
|
|
356
|
+
unpack(basepath(dir), uri: tag, digest: digest, ext: ext, force: force)
|
|
314
357
|
end
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
end
|
|
345
|
-
else
|
|
346
|
-
format_desc(action, flag, case flag when :exec, :env then 'command' end)
|
|
347
|
-
task flag do |_, args|
|
|
348
|
-
args = args.to_a
|
|
349
|
-
if args.empty? && (flag == :exec || flag == :env)
|
|
350
|
-
args << readline('Enter command', force: flag == :exec)
|
|
358
|
+
when 'asdf'
|
|
359
|
+
break unless @asdf
|
|
360
|
+
|
|
361
|
+
case flag
|
|
362
|
+
when :set
|
|
363
|
+
format_desc action, flag, 'version,dir?=u/home|p/arent'
|
|
364
|
+
task flag, [:version] do |_, args|
|
|
365
|
+
args = if (version = args.version)
|
|
366
|
+
args.extras
|
|
367
|
+
else
|
|
368
|
+
version, opts = choice_index('Select a version',
|
|
369
|
+
@asdf[1].children
|
|
370
|
+
.map(&:basename)
|
|
371
|
+
.sort { |a, b| b <=> a }
|
|
372
|
+
.push('latest', 'system'),
|
|
373
|
+
accept: [accept_y('Confirm?')],
|
|
374
|
+
values: 'Options')
|
|
375
|
+
OptionPartition.strip(opts)
|
|
376
|
+
end
|
|
377
|
+
asdf(flag, args, version: version)
|
|
378
|
+
end
|
|
379
|
+
else
|
|
380
|
+
format_desc(action, flag, case flag when :exec, :env then 'command' end)
|
|
381
|
+
task flag do |_, args|
|
|
382
|
+
args = args.to_a
|
|
383
|
+
if args.empty? && (flag == :exec || flag == :env)
|
|
384
|
+
args << readline('Enter command', force: flag == :exec)
|
|
385
|
+
end
|
|
386
|
+
asdf flag, args
|
|
351
387
|
end
|
|
352
|
-
asdf flag, args
|
|
353
388
|
end
|
|
354
389
|
end
|
|
355
390
|
end
|
|
@@ -959,6 +994,8 @@ module Squared
|
|
|
959
994
|
parent_set val
|
|
960
995
|
when :archive
|
|
961
996
|
archive_set val
|
|
997
|
+
when :serve
|
|
998
|
+
serve_set val
|
|
962
999
|
when :asdf
|
|
963
1000
|
asdf_set val
|
|
964
1001
|
when :run
|
|
@@ -2499,6 +2536,17 @@ module Squared
|
|
|
2499
2536
|
end
|
|
2500
2537
|
end
|
|
2501
2538
|
|
|
2539
|
+
def serve_set(val)
|
|
2540
|
+
@serve = case val
|
|
2541
|
+
when false
|
|
2542
|
+
false
|
|
2543
|
+
when String
|
|
2544
|
+
{ root: val }
|
|
2545
|
+
when Hash
|
|
2546
|
+
val if val.key?(:root)
|
|
2547
|
+
end
|
|
2548
|
+
end
|
|
2549
|
+
|
|
2502
2550
|
def asdf_set(val)
|
|
2503
2551
|
@asdf = if @@asdf && val
|
|
2504
2552
|
dir = @@asdf.path.join('installs', val)
|
|
@@ -2660,6 +2708,10 @@ module Squared
|
|
|
2660
2708
|
level.empty? ? ex != false && ex != Logger::INFO : ex.is_a?(Numeric) && level.include?(ex)
|
|
2661
2709
|
end
|
|
2662
2710
|
|
|
2711
|
+
def serve?
|
|
2712
|
+
false
|
|
2713
|
+
end
|
|
2714
|
+
|
|
2663
2715
|
def variables
|
|
2664
2716
|
VAR_SET
|
|
2665
2717
|
end
|
|
@@ -72,6 +72,8 @@ module Squared
|
|
|
72
72
|
}.freeze,
|
|
73
73
|
network: {
|
|
74
74
|
connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=q link=b link-local-ip=q].freeze,
|
|
75
|
+
create: %w[attachable config-only gateway ingress internal ipv4 ipv6 aux-address=q config-from=b d|driver=b
|
|
76
|
+
ip-range=q ipam-driver=b ipam-opt=q label=q o|opt=q scope=b subnet=q].freeze,
|
|
75
77
|
disconnect: %w[f|force].freeze
|
|
76
78
|
}.freeze
|
|
77
79
|
}.freeze
|
|
@@ -114,7 +116,7 @@ module Squared
|
|
|
114
116
|
'image' => %i[ls rm pull push tag save].freeze,
|
|
115
117
|
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
|
116
118
|
rm].freeze,
|
|
117
|
-
'network' => %i[connect disconnect].freeze,
|
|
119
|
+
'network' => %i[connect disconnect create].freeze,
|
|
118
120
|
'ls' => nil
|
|
119
121
|
})
|
|
120
122
|
|
|
@@ -312,8 +314,9 @@ module Squared
|
|
|
312
314
|
when 'network'
|
|
313
315
|
format_desc action, flag, 'target,opts*'
|
|
314
316
|
task flag, [:target] do |_, args|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
+
target = flag == :create ? param_guard(action, flag, args: args, key: :target) : args.target
|
|
318
|
+
if target
|
|
319
|
+
network(flag, args.extras, target: target)
|
|
317
320
|
else
|
|
318
321
|
choice_command flag
|
|
319
322
|
end
|
|
@@ -329,8 +332,8 @@ module Squared
|
|
|
329
332
|
def clean(*, sync: invoked_sync?('clean'), **)
|
|
330
333
|
if runnable?(@clean)
|
|
331
334
|
super
|
|
332
|
-
|
|
333
|
-
image
|
|
335
|
+
elsif sync || option('y', prefix: 'docker')
|
|
336
|
+
image :rm
|
|
334
337
|
end
|
|
335
338
|
end
|
|
336
339
|
|
|
@@ -635,10 +638,17 @@ module Squared
|
|
|
635
638
|
|
|
636
639
|
def network(flag, opts = [], target: nil)
|
|
637
640
|
cmd, opts = docker_session('network', flag, opts: opts)
|
|
638
|
-
OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
|
|
639
|
-
|
|
641
|
+
op = OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
|
|
642
|
+
.clear
|
|
640
643
|
from = symjoin 'network', flag
|
|
641
|
-
|
|
644
|
+
if flag == :create
|
|
645
|
+
op.add_quote(target)
|
|
646
|
+
run(from: from)
|
|
647
|
+
else
|
|
648
|
+
list_image(flag, docker_output('ps -a'), from: from) do |id|
|
|
649
|
+
success?(run(cmd.temp(target, id), from: from))
|
|
650
|
+
end
|
|
651
|
+
end
|
|
642
652
|
end
|
|
643
653
|
|
|
644
654
|
def build?
|
|
@@ -1108,15 +1108,16 @@ module Squared
|
|
|
1108
1108
|
pull(:autostash, sync: sync)
|
|
1109
1109
|
end
|
|
1110
1110
|
|
|
1111
|
-
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil
|
|
1111
|
+
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil,
|
|
1112
|
+
banner: !sync || verbose? || task_invoked?('fetch'))
|
|
1112
1113
|
opts = git_session('fetch', opts: opts).last
|
|
1113
1114
|
opts << 'all' if flag == :all || option('all')
|
|
1114
1115
|
append_pull(opts, collect_hash(OPT_GIT[:fetch]), flag: flag, from: :fetch, remote: remote,
|
|
1115
1116
|
no: collect_hash(OPT_GIT[:no][:fetch]))
|
|
1116
1117
|
if sync
|
|
1117
|
-
source
|
|
1118
|
+
source(banner: banner)
|
|
1118
1119
|
else
|
|
1119
|
-
source(sync: false, **threadargs)
|
|
1120
|
+
source(sync: false, banner: banner, **threadargs)
|
|
1120
1121
|
end
|
|
1121
1122
|
end
|
|
1122
1123
|
|
|
@@ -106,7 +106,21 @@ module Squared
|
|
|
106
106
|
tsc: %w[excludeDirectories excludeFiles customConditions lib moduleSuffixes plugins rootDirs typeRoots
|
|
107
107
|
types].freeze
|
|
108
108
|
}.freeze
|
|
109
|
-
|
|
109
|
+
APP_SERVE = 'const t=require("http"),e=require("fs"),a=require("path"),i="$ROOT",o={avif:"image/avif",css:"te' \
|
|
110
|
+
'xt/css",gif:"image/gif",htm:"text/html",html:"text/html",ico:"image/x-icon",jpeg:"image/jpeg",jp' \
|
|
111
|
+
'g:"image/jpeg",js:"text/javascript",mjs:"application/javascript",json:"application/json",md:"tex' \
|
|
112
|
+
't/markdown",m4a:"audio/x-m4a",mp3:"audio/mpeg",mp4:"video/mp4",otf:"font/otf",pdf:"application/p' \
|
|
113
|
+
'df",png:"image/png",rss:"application/rss+xml",svg:"image/svg+xml",ttc:"font/collection",ttf:"fon' \
|
|
114
|
+
't/ttf",txt:"text/plain",wasm:"application/wasm",webp:"image/webp",woff:"font/woff",woff2:"font/w' \
|
|
115
|
+
'off2",xml:"application/xml",webmanifest:"application/manifest+json",yaml:"text/yaml",yml:"text/y' \
|
|
116
|
+
'aml"};function n(t){return o[a.extname(t).slice(1)]||"application/octet-stream"}t.createServer((' \
|
|
117
|
+
't,o)=>{let l=a.join(i,t.url.split("?")[0]);try{e.statSync(l).isDirectory()&&(l=a.join(l,"index.h' \
|
|
118
|
+
'tml"))}catch{}e.readFile(l,(t,e)=>{console.error(`[${(new Date).toLocaleTimeString().padStart(11' \
|
|
119
|
+
', 0)}] ${t?"\x1B[31m404\x1B[39m":"\x1B[1m200\x1B[22m"} ${l.slice(i.length)}`);if(t)return o.writ' \
|
|
120
|
+
'eHead(404,{"Content-Type":"text/plain"}),void o.end("404 Not Found");o.writeHead(200,{"Content-T' \
|
|
121
|
+
'ype":n(l)}),o.end(e)})}).listen({host:"$HOST",port:+"$PORT"},()=>{console.log("HTTP server liste' \
|
|
122
|
+
'ning on http://$HOST:$PORT")});'
|
|
123
|
+
private_constant :OPT_NPM, :OPT_PNPM, :OPT_YARN, :OPT_BERRY, :OPT_TSC, :PASS_NODE, :APP_SERVE
|
|
110
124
|
|
|
111
125
|
class << self
|
|
112
126
|
def tasks
|
|
@@ -160,6 +174,7 @@ module Squared
|
|
|
160
174
|
end
|
|
161
175
|
@dependname = 'package.json'
|
|
162
176
|
dependfile_set [@dependname]
|
|
177
|
+
serve_set kwargs[:serve]
|
|
163
178
|
@tsfile = basepath! ts
|
|
164
179
|
@pm = { __: kwargs[:init] }
|
|
165
180
|
end
|
|
@@ -1148,6 +1163,30 @@ module Squared
|
|
|
1148
1163
|
end
|
|
1149
1164
|
end
|
|
1150
1165
|
|
|
1166
|
+
def serve(root, opts = [], bind: nil, port: 3000, **)
|
|
1167
|
+
var = {}
|
|
1168
|
+
if File.extname(root) =~ /[cm]?js/
|
|
1169
|
+
var['HOST'] = bind if bind
|
|
1170
|
+
var['PORT'] = port.to_s if port
|
|
1171
|
+
target = root
|
|
1172
|
+
root = File.dirname(target)
|
|
1173
|
+
else
|
|
1174
|
+
require 'tempfile'
|
|
1175
|
+
app = APP_SERVE.dup
|
|
1176
|
+
app.gsub!('$ROOT', root)
|
|
1177
|
+
app.gsub!('$HOST', bind || 'localhost')
|
|
1178
|
+
app.gsub!('$PORT', port.to_s)
|
|
1179
|
+
file = Tempfile.new([name, '.cjs'])
|
|
1180
|
+
file.write(app)
|
|
1181
|
+
file.close
|
|
1182
|
+
trap 'INT' do
|
|
1183
|
+
file.unlink
|
|
1184
|
+
end
|
|
1185
|
+
target = file.path
|
|
1186
|
+
end
|
|
1187
|
+
shell(var, session('node', shell_quote(target), *opts.map { |s| fill_option(s) }).done, chdir: root)
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1151
1190
|
def depend?
|
|
1152
1191
|
@depend != false && (!@depend.nil? || outdated?)
|
|
1153
1192
|
end
|
|
@@ -1438,6 +1477,10 @@ module Squared
|
|
|
1438
1477
|
ret
|
|
1439
1478
|
end
|
|
1440
1479
|
|
|
1480
|
+
def serve?
|
|
1481
|
+
@serve != false
|
|
1482
|
+
end
|
|
1483
|
+
|
|
1441
1484
|
def nolockfile?(prefix = dependbin)
|
|
1442
1485
|
option('package-lock', 'lockfile', prefix: prefix, equals: '0') || !option('no-lockfile', prefix: prefix).nil?
|
|
1443
1486
|
end
|
|
@@ -129,6 +129,7 @@ module Squared
|
|
|
129
129
|
initialize_env(**kwargs)
|
|
130
130
|
end
|
|
131
131
|
dependfile_set DEP_PYTHON
|
|
132
|
+
serve_set kwargs[:serve]
|
|
132
133
|
editable_set editable
|
|
133
134
|
venv_set kwargs[:venv]
|
|
134
135
|
end
|
|
@@ -272,7 +273,7 @@ module Squared
|
|
|
272
273
|
if args.empty?
|
|
273
274
|
args = readline('Enter command', force: true).split(' ', 2)
|
|
274
275
|
elsif args.size == 1 && option('interactive', notequals: '0', prefix: ref)
|
|
275
|
-
args << readline('Enter arguments', force: false)
|
|
276
|
+
args << readline('Enter arguments', force: false) unless args.first.include?(' ')
|
|
276
277
|
end
|
|
277
278
|
venv_init
|
|
278
279
|
run args.join(' ')
|
|
@@ -804,6 +805,10 @@ module Squared
|
|
|
804
805
|
.yield_self { |val| ret || val }
|
|
805
806
|
end
|
|
806
807
|
|
|
808
|
+
def serve(root, opts = [], bind: 'localhost', port: nil, **)
|
|
809
|
+
shell(python_session('-m http.server', port, basic_option('b', bind), opts: opts).first.done, chdir: root)
|
|
810
|
+
end
|
|
811
|
+
|
|
807
812
|
def project
|
|
808
813
|
return @project unless @project.frozen?
|
|
809
814
|
|
|
@@ -855,6 +860,10 @@ module Squared
|
|
|
855
860
|
!venv.nil?
|
|
856
861
|
end
|
|
857
862
|
|
|
863
|
+
def serve?
|
|
864
|
+
@serve != false
|
|
865
|
+
end
|
|
866
|
+
|
|
858
867
|
private
|
|
859
868
|
|
|
860
869
|
def pip_session(*cmd)
|
|
@@ -213,6 +213,7 @@ module Squared
|
|
|
213
213
|
initialize_env(**kwargs)
|
|
214
214
|
end
|
|
215
215
|
dependfile_set GEMFILE
|
|
216
|
+
serve_set kwargs[:serve]
|
|
216
217
|
gemfile_set kwargs[:gemspec]
|
|
217
218
|
@autodetect = autodetect
|
|
218
219
|
@steepfile = basepath! steep if steep
|
|
@@ -458,9 +459,10 @@ module Squared
|
|
|
458
459
|
bundle(flag, opts: args.to_a, banner: flag == :exec ? verbose? : true)
|
|
459
460
|
end
|
|
460
461
|
when :reinstall
|
|
461
|
-
format_desc action, flag, 'f/orce?,opts*'
|
|
462
|
+
format_desc action, flag, 'f/orce?,l/ocal?,opts*'
|
|
462
463
|
task flag do |_, args|
|
|
463
464
|
opts = args.to_a
|
|
465
|
+
opts << 'local' if has_value!(opts, 'l')
|
|
464
466
|
opts << 'redownload' if has_value!(opts, 'f', 'force')
|
|
465
467
|
if (lock = basepath!('Gemfile.lock'))
|
|
466
468
|
config = basepath '.bundle', 'config'
|
|
@@ -1167,6 +1169,7 @@ module Squared
|
|
|
1167
1169
|
when :dependency, :environment, :list, :search, :specification, :which
|
|
1168
1170
|
op.concat(args)
|
|
1169
1171
|
end
|
|
1172
|
+
ia = op.remove(':')
|
|
1170
1173
|
op.each do |opt|
|
|
1171
1174
|
if gems && !opt.start_with?('-') && !opt.match?(GEMNAME)
|
|
1172
1175
|
op.errors << opt
|
|
@@ -1228,7 +1231,7 @@ module Squared
|
|
|
1228
1231
|
end
|
|
1229
1232
|
when :install, :uninstall, :pristine
|
|
1230
1233
|
if flag == :install
|
|
1231
|
-
post = if
|
|
1234
|
+
post = if ia
|
|
1232
1235
|
op.concat(args)
|
|
1233
1236
|
readline('Enter command [args]', force: true)
|
|
1234
1237
|
elsif op.empty?
|
|
@@ -1237,6 +1240,25 @@ module Squared
|
|
|
1237
1240
|
elsif !args.empty?
|
|
1238
1241
|
args.join(' ')
|
|
1239
1242
|
end
|
|
1243
|
+
elsif ia
|
|
1244
|
+
name = op.shift || args.shift || (s = readline('Enter gem name', force: true))
|
|
1245
|
+
list = []
|
|
1246
|
+
pwd_set do
|
|
1247
|
+
pat = /^#{name}\s+\((.+)\)$/
|
|
1248
|
+
IO.popen(gem_output("list -a #{shell_quote(name)}").to_s).each do |val|
|
|
1249
|
+
next unless val =~ pat
|
|
1250
|
+
|
|
1251
|
+
split_escape($1).each { |val| list << val unless val.start_with?('default:') }
|
|
1252
|
+
break
|
|
1253
|
+
end
|
|
1254
|
+
end
|
|
1255
|
+
ver = choice_index('Select version', list, force: s.nil?) unless list.empty?
|
|
1256
|
+
if ver
|
|
1257
|
+
op << '--force'
|
|
1258
|
+
op.unshift("#{name}@#{ver}")
|
|
1259
|
+
else
|
|
1260
|
+
op.unshift(name)
|
|
1261
|
+
end
|
|
1240
1262
|
end
|
|
1241
1263
|
raise_error ArgumentError, 'missing gem name', hint: flag if op.empty?
|
|
1242
1264
|
if op.arg?('all')
|
|
@@ -1246,7 +1268,7 @@ module Squared
|
|
|
1246
1268
|
else
|
|
1247
1269
|
op.clear
|
|
1248
1270
|
end
|
|
1249
|
-
elsif (n = op.index { |val| val.match?(/(\A|[
|
|
1271
|
+
elsif (n = op.index { |val| val.match?(/(\A|[\w.-])@\d/) })
|
|
1250
1272
|
name = op.remove_at(n)
|
|
1251
1273
|
n = name.index('@')
|
|
1252
1274
|
pre, ver = if n == 0
|
|
@@ -1254,7 +1276,7 @@ module Squared
|
|
|
1254
1276
|
else
|
|
1255
1277
|
[name[0, n], name[n.succ..-1]]
|
|
1256
1278
|
end
|
|
1257
|
-
op.adjoin(pre,
|
|
1279
|
+
op.adjoin(pre, quote_option('version', ver))
|
|
1258
1280
|
.clear
|
|
1259
1281
|
end
|
|
1260
1282
|
if flag == :install
|
|
@@ -1540,6 +1562,18 @@ module Squared
|
|
|
1540
1562
|
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :rubocop)
|
|
1541
1563
|
end
|
|
1542
1564
|
|
|
1565
|
+
def serve(root, *, bind: nil, port: nil, **kwargs)
|
|
1566
|
+
require 'webrick'
|
|
1567
|
+
config = kwargs.merge({ DocumentRoot: root })
|
|
1568
|
+
config[:BindAddress] = bind if bind
|
|
1569
|
+
config[:Port] = port if port
|
|
1570
|
+
server = WEBrick::HTTPServer.new(config)
|
|
1571
|
+
trap 'INT' do
|
|
1572
|
+
server.shutdown
|
|
1573
|
+
end
|
|
1574
|
+
server.start
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1543
1577
|
def gemspec
|
|
1544
1578
|
@gemspec = !gemfile.nil? && Gem::Specification.load(gemfile.to_s) rescue false if @gemspec.nil?
|
|
1545
1579
|
@gemspec || nil
|
|
@@ -1873,6 +1907,13 @@ module Squared
|
|
|
1873
1907
|
semgte?(ver.to_s, min.to_s) && (max == Float::INFINITY || !semgte?(ver.to_s, max.to_s))
|
|
1874
1908
|
end
|
|
1875
1909
|
end
|
|
1910
|
+
|
|
1911
|
+
def serve?
|
|
1912
|
+
!Gem::Specification.find_by_name('webrick').nil?
|
|
1913
|
+
rescue Gem::MissingSpecError => e
|
|
1914
|
+
log.warn e if @serve
|
|
1915
|
+
false
|
|
1916
|
+
end
|
|
1876
1917
|
end
|
|
1877
1918
|
|
|
1878
1919
|
Application.implement Ruby
|
|
@@ -221,6 +221,8 @@ module Squared
|
|
|
221
221
|
si = []
|
|
222
222
|
bl = []
|
|
223
223
|
ml = []
|
|
224
|
+
sw = {}
|
|
225
|
+
se = {}
|
|
224
226
|
list.flat_map do |val|
|
|
225
227
|
x, y = val.split('|', 2)
|
|
226
228
|
if y
|
|
@@ -233,6 +235,11 @@ module Squared
|
|
|
233
235
|
end
|
|
234
236
|
end
|
|
235
237
|
.each do |val|
|
|
238
|
+
if val.size > 1 && val =~ /^\{([^},]*)(?:,([^}]+))?\}(.+)$/
|
|
239
|
+
op1 = $1 unless $1.empty?
|
|
240
|
+
op2 = $2
|
|
241
|
+
val = $3
|
|
242
|
+
end
|
|
236
243
|
if (n = val.index('='))
|
|
237
244
|
flag = val[0, n]
|
|
238
245
|
case val[n.succ]
|
|
@@ -265,9 +272,12 @@ module Squared
|
|
|
265
272
|
end
|
|
266
273
|
m << flag if val[n + 2] == 'm'
|
|
267
274
|
bare << flag if val.end_with?('?')
|
|
275
|
+
val = flag
|
|
268
276
|
else
|
|
269
277
|
bare << val
|
|
270
278
|
end
|
|
279
|
+
sw[val] = op1 if op1
|
|
280
|
+
se[val] = op2 if op2
|
|
271
281
|
end
|
|
272
282
|
no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
|
|
273
283
|
bare.concat(no)
|
|
@@ -316,30 +326,34 @@ module Squared
|
|
|
316
326
|
if single&.match?(opt)
|
|
317
327
|
add "-#{opt}"
|
|
318
328
|
elsif bare.include?(opt)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
329
|
+
if sw[opt]
|
|
330
|
+
add "#{sw[opt]}#{opt}"
|
|
331
|
+
else
|
|
332
|
+
add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
|
|
333
|
+
end
|
|
334
|
+
elsif opt.start_with?(/no[-_]/) && no.include?(s = opt[3..-1])
|
|
335
|
+
add "--no-#{s}"
|
|
322
336
|
else
|
|
323
337
|
if opt =~ OPT_VALUE
|
|
324
338
|
key = $1
|
|
325
339
|
val = $2
|
|
326
340
|
merge = m.include?(key)
|
|
327
|
-
|
|
328
|
-
|
|
341
|
+
switch = sw[key]
|
|
342
|
+
kwargs = { sep: se[key] || sep, merge: merge, switch: switch }
|
|
343
|
+
if e.include?(key) || (bl.include?(key) && %w[true false].include?(val))
|
|
344
|
+
add shell_option(key, val, **kwargs)
|
|
329
345
|
elsif q.include?(key)
|
|
330
|
-
add quote_option(key, val, double: qq.include?(key),
|
|
346
|
+
add quote_option(key, val, double: qq.include?(key), **kwargs)
|
|
331
347
|
elsif p.include?(key)
|
|
332
348
|
if val.match?(/\A(["']).+\1\z/)
|
|
333
|
-
add shell_option(key, val, escape: false,
|
|
349
|
+
add shell_option(key, val, escape: false, **kwargs)
|
|
334
350
|
elsif path
|
|
335
|
-
add quote_option(key, path + val,
|
|
351
|
+
add quote_option(key, path + val, **kwargs)
|
|
336
352
|
else
|
|
337
353
|
push opt
|
|
338
354
|
end
|
|
339
|
-
elsif b.include?(key) ||
|
|
340
|
-
add basic_option(key, val,
|
|
341
|
-
elsif merge
|
|
342
|
-
add basic_option(key, val, merge: true, sep: sep)
|
|
355
|
+
elsif b.include?(key) || numcheck.call(key, val) || se[key] || merge || switch
|
|
356
|
+
add basic_option(key, val, **kwargs)
|
|
343
357
|
else
|
|
344
358
|
push opt
|
|
345
359
|
end
|