squared 0.4.0 → 0.4.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 +43 -2
- data/README.ruby.md +5 -2
- data/lib/squared/common/format.rb +12 -7
- data/lib/squared/common/utils.rb +14 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/project/base.rb +9 -3
- data/lib/squared/workspace/project/docker.rb +74 -23
- data/lib/squared/workspace/project/git.rb +38 -14
- data/lib/squared/workspace/project/node.rb +0 -2
- data/lib/squared/workspace/project/python.rb +62 -25
- data/lib/squared/workspace/project/ruby.rb +2 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41bec81d0daef581416b2c3c7a6cefc66da439794df530c5b2e9c65f7feba6ae
|
4
|
+
data.tar.gz: 8b74836f62055cc6d173148753420ac2bb621e951f1d339cae60ed35357c6f5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f042541b80121e9ef547066105a6148a21c790cf50ef0931097ee1506f75fd0a154323671585ec4c86fce33ac2c4c3d8d52d380550091d88932992fc79491466
|
7
|
+
data.tar.gz: 3fc67865ab3499416cac65f06652206af9dd762f898c561924b19f7c50c5430f640da0e03249ac1cdc39c0a2de1b0ba4125b8e2813805fa65259e5d285d44f79
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,40 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.4.2] - 2025-03-28
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Python command build and publish with Poetry was implemented.
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
- Docker image command list did not display ID when empty.
|
12
|
+
|
13
|
+
## [0.4.1] - 2025-03-20
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- Status logger messages are written to file.
|
18
|
+
- Docker command image action push was implemented.
|
19
|
+
- Git command show action textconv was implemented.
|
20
|
+
- Docker mounts for container command run is supported.
|
21
|
+
|
22
|
+
### Removed
|
23
|
+
|
24
|
+
- Git batch commands pull+s and rebase+s were removed.
|
25
|
+
|
26
|
+
## [0.3.6] - 2025-03-12
|
27
|
+
|
28
|
+
### Added
|
29
|
+
|
30
|
+
- Git command stash action clear was implemented.
|
31
|
+
|
32
|
+
### Fixed
|
33
|
+
|
34
|
+
- Git command stash did not validate index argument.
|
35
|
+
- Project graph command does not require arguments.
|
36
|
+
- Ruby gem command exec did not add project name.
|
37
|
+
|
3
38
|
## [0.4.0] - 2025-03-06
|
4
39
|
|
5
40
|
### Added
|
@@ -37,13 +72,16 @@
|
|
37
72
|
|
38
73
|
- Node copy method will only override when key exists.
|
39
74
|
- Base command copy and clean can accept a hash.
|
40
|
-
- Character methods in Shell common module were removed.
|
41
75
|
- ENV build options are merged with base options.
|
42
|
-
- Git command diff action cached was removed.
|
43
76
|
- Git log and diff uses H0 alias for HEAD~n commit.
|
44
77
|
- Project events support multiple associated routines.
|
45
78
|
- Git command restore was relocated to "git" task namespace.
|
46
79
|
|
80
|
+
### Removed
|
81
|
+
|
82
|
+
- Character methods in Shell common module were removed.
|
83
|
+
- Git command diff action cached was removed.
|
84
|
+
|
47
85
|
### Fixed
|
48
86
|
|
49
87
|
- Git base class did not check for null Logger instance.
|
@@ -352,7 +390,10 @@
|
|
352
390
|
|
353
391
|
- Changelog was created.
|
354
392
|
|
393
|
+
[0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
|
394
|
+
[0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
|
355
395
|
[0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
|
396
|
+
[0.3.6]: https://github.com/anpham6/squared/releases/tag/v0.3.6-ruby
|
356
397
|
[0.3.5]: https://github.com/anpham6/squared/releases/tag/v0.3.5-ruby
|
357
398
|
[0.3.4]: https://github.com/anpham6/squared/releases/tag/v0.3.4-ruby
|
358
399
|
[0.3.3]: https://github.com/anpham6/squared/releases/tag/v0.3.3-ruby
|
data/README.ruby.md
CHANGED
@@ -105,8 +105,11 @@ Workspace::Application
|
|
105
105
|
variable_set :clean, ["build/sqd/"]
|
106
106
|
end
|
107
107
|
.with(:docker, pass: ["unpack"]) do
|
108
|
-
.add("squared", "docker", file: "Dockerfile", context: ".", tag: "latest",
|
109
|
-
|
108
|
+
.add("squared", "docker", file: "Dockerfile", context: ".", tag: "latest", registry: "localhost:5000", username: "squared",
|
109
|
+
args: "--ssh=default",
|
110
|
+
secrets: ["id=github,env=GITHUB_TOKEN"],
|
111
|
+
mounts: ["src=.,dst=/project,ro,bind-propagation=rshared"]) do # Docker
|
112
|
+
series(:clean) do # run | depend | doc | lint | test | copy | clean
|
110
113
|
File.read(basepath("docker-bake.hcl"))
|
111
114
|
.scan(/\btags\s+=\s+\["([^"]+)"\]/)
|
112
115
|
.each { |val| image(:rm, tag: val.first) }
|
@@ -118,7 +118,7 @@ module Squared
|
|
118
118
|
if !val.is_a?(::Numeric)
|
119
119
|
val = val.to_sym
|
120
120
|
ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
|
121
|
-
elsif val
|
121
|
+
elsif val.between?(0, 256)
|
122
122
|
ret << val
|
123
123
|
elsif val < 0 && (b = val.to_s.split('.')[1])
|
124
124
|
b = b[0, 3]
|
@@ -170,10 +170,15 @@ module Squared
|
|
170
170
|
color ? sub_style(ret, *styles) : ret
|
171
171
|
end
|
172
172
|
|
173
|
-
def log_message(level, *args, subject: nil, hint: nil, color: ARG[:COLOR], pass: false)
|
174
|
-
return false if !pass && level.is_a?(::Numeric) && level < ARG[:LEVEL]
|
175
|
-
|
173
|
+
def log_message(level, *args, subject: nil, hint: nil, color: ARG[:COLOR], append: true, pass: false)
|
176
174
|
args = args.map(&:to_s)
|
175
|
+
if level.is_a?(::Numeric)
|
176
|
+
if append && respond_to?(:log)
|
177
|
+
ref = log rescue nil
|
178
|
+
ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(Logger)
|
179
|
+
end
|
180
|
+
return false if !pass && level < ARG[:LEVEL]
|
181
|
+
end
|
177
182
|
if args.size > 1 && !hint
|
178
183
|
title = log_title(level, color: false)
|
179
184
|
sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
|
@@ -209,8 +214,8 @@ module Squared
|
|
209
214
|
|
210
215
|
module_function
|
211
216
|
|
212
|
-
def message(*args, hint: nil, empty: false)
|
213
|
-
(empty ? args.reject { |val| val.nil? || val.empty? } : args).join(
|
217
|
+
def message(*args, hint: nil, empty: false, space: ARG[:SPACE])
|
218
|
+
(empty ? args.reject { |val| val.nil? || val.empty? } : args).join(space) + (hint ? " (#{hint})" : '')
|
214
219
|
end
|
215
220
|
|
216
221
|
def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, border: nil, pipe: nil)
|
@@ -226,7 +231,7 @@ module Squared
|
|
226
231
|
if val.is_a?(::Array)
|
227
232
|
lines = val.map(&:to_s)
|
228
233
|
else
|
229
|
-
lines = val.to_s.lines
|
234
|
+
lines = val.to_s.lines(chomp: true)
|
230
235
|
lines[0] = "#{val.class}: #{lines.first}" if (err = val.is_a?(StandardError))
|
231
236
|
end
|
232
237
|
n = cols || max.(lines)
|
data/lib/squared/common/utils.rb
CHANGED
@@ -12,6 +12,19 @@ module Squared
|
|
12
12
|
val.split(/\s*(?<!\\)#{char}\s*/o)
|
13
13
|
end
|
14
14
|
|
15
|
+
def split_option(val)
|
16
|
+
val = val.strip
|
17
|
+
return [val, '', ''] unless (i = val.index('='))
|
18
|
+
|
19
|
+
last = val[i + 1..-1].strip
|
20
|
+
quote = ''
|
21
|
+
if last =~ /^(["'])(.+)\1$/
|
22
|
+
last = $2
|
23
|
+
quote = $1
|
24
|
+
end
|
25
|
+
[val[0..i - 1], last, quote]
|
26
|
+
end
|
27
|
+
|
15
28
|
def task_invoke(*cmd, args: [], exception: true, warning: true)
|
16
29
|
cmd.each { |name| Rake::Task[name].invoke(*args) }
|
17
30
|
rescue StandardError => e
|
@@ -141,7 +154,7 @@ module Squared
|
|
141
154
|
return ret.to_i
|
142
155
|
end
|
143
156
|
when ::Numeric
|
144
|
-
return key if key
|
157
|
+
return key if key.between?(0, 2)
|
145
158
|
end
|
146
159
|
default
|
147
160
|
end
|
data/lib/squared/version.rb
CHANGED
@@ -264,7 +264,7 @@ module Squared
|
|
264
264
|
|
265
265
|
format_desc action, flag, '(-)project*'
|
266
266
|
task flag do |_, args|
|
267
|
-
args =
|
267
|
+
args = args.to_a.reject { |val| name == val.to_s }
|
268
268
|
if flag == :run
|
269
269
|
graph args
|
270
270
|
else
|
@@ -639,7 +639,7 @@ module Squared
|
|
639
639
|
|
640
640
|
dest = target.join(File.basename(file.path))
|
641
641
|
FileUtils.mv(entry, dest)
|
642
|
-
dest.children.each { |
|
642
|
+
dest.children.each { |child| FileUtils.mv(child, target) }
|
643
643
|
dest.rmdir
|
644
644
|
target = entry
|
645
645
|
depth -= 1
|
@@ -871,7 +871,7 @@ module Squared
|
|
871
871
|
log&.warn "ENV was discarded: #{var}" if var
|
872
872
|
task_invoke(cmd, exception: exception, warning: warning?)
|
873
873
|
else
|
874
|
-
print_item format_banner(cmd, banner: banner) if sync
|
874
|
+
print_item format_banner(cmd, banner: banner) if sync && !env('BANNER', equals: '0')
|
875
875
|
args = var.is_a?(Hash) ? [var, cmd] : [cmd]
|
876
876
|
shell(*args, chdir: chdir, exception: exception)
|
877
877
|
end
|
@@ -970,7 +970,13 @@ module Squared
|
|
970
970
|
next if pass.include?(meth)
|
971
971
|
|
972
972
|
if workspace.task_defined?(cmd = task_join(proj.name, meth))
|
973
|
+
if ENV.key?(key = "BANNER_#{proj.name.upcase}")
|
974
|
+
key = nil
|
975
|
+
else
|
976
|
+
ENV[key] = '0'
|
977
|
+
end
|
973
978
|
run(cmd, sync: false, banner: false)
|
979
|
+
ENV.delete(key) if key
|
974
980
|
elsif proj.has?(meth, tasks || group ? nil : workspace.baseref)
|
975
981
|
proj.__send__(meth.to_sym, sync: sync)
|
976
982
|
end
|
@@ -42,7 +42,7 @@ module Squared
|
|
42
42
|
env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
|
43
43
|
health-start-interval=b health-start-period=b health-timeout=b h|hostname=e io-maxbandwidth=b
|
44
44
|
io-maxiops=b ip=b ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b
|
45
|
-
link-local-ip=b log-driver=b log-opt=q mac-address=e memory-swappiness=b mount=
|
45
|
+
link-local-ip=b log-driver=b log-opt=q mac-address=e memory-swappiness=b mount=qq name=b network=b
|
46
46
|
network-alias=b oom-score-adj=b pid=b platform=b p|publish=e pull=b restart=b runtime=b
|
47
47
|
security-opt=q shm-size=b sig-proxy=b? stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q
|
48
48
|
ulimit=q user=e userns=b uts=b v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
|
@@ -61,11 +61,17 @@ module Squared
|
|
61
61
|
}.freeze,
|
62
62
|
image: {
|
63
63
|
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
64
|
-
push: %w[disable-content-trust=b? platform=b q|quiet].freeze,
|
64
|
+
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
65
65
|
rm: %w[f|force no-prune].freeze
|
66
66
|
}.freeze
|
67
67
|
}.freeze
|
68
|
-
|
68
|
+
VAL_DOCKER = {
|
69
|
+
run: {
|
70
|
+
bind: %w[type source src destination dst target readonly ro bind-propagation].freeze,
|
71
|
+
tmpfs: %w[type destination dst target tmpfs-size tmpfs-mode].freeze
|
72
|
+
}.freeze
|
73
|
+
}.freeze
|
74
|
+
private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER, :VAL_DOCKER
|
69
75
|
|
70
76
|
class << self
|
71
77
|
def tasks
|
@@ -82,7 +88,7 @@ module Squared
|
|
82
88
|
@@tasks[ref] = {
|
83
89
|
'build' => %i[tag context bake].freeze,
|
84
90
|
'compose' => %i[build run exec up].freeze,
|
85
|
-
'image' => %i[list rm].freeze,
|
91
|
+
'image' => %i[list rm push].freeze,
|
86
92
|
'container' => %i[run exec update commit inspect diff start stop restart pause unpause top stats kill
|
87
93
|
rm].freeze
|
88
94
|
}.freeze
|
@@ -90,14 +96,15 @@ module Squared
|
|
90
96
|
attr_reader :context
|
91
97
|
attr_accessor :tag
|
92
98
|
|
93
|
-
def initialize(*, file: nil, context: nil, tag: nil, secrets: nil, registry: nil, **kwargs)
|
99
|
+
def initialize(*, file: nil, context: nil, tag: nil, secrets: nil, mounts: [], registry: nil, **kwargs)
|
94
100
|
super
|
95
101
|
return unless dockerfile(file).exist?
|
96
102
|
|
97
103
|
@context = context
|
98
104
|
@tag = tag || "#{@project}:latest"
|
105
|
+
@mounts = mounts
|
99
106
|
@secrets = secrets
|
100
|
-
@registry = registry
|
107
|
+
@registry = [registry, kwargs[:username]].compact.join('/')
|
101
108
|
initialize_ref Docker.ref
|
102
109
|
initialize_logger(**kwargs)
|
103
110
|
initialize_env(**kwargs)
|
@@ -169,9 +176,18 @@ module Squared
|
|
169
176
|
end
|
170
177
|
end
|
171
178
|
when 'image'
|
172
|
-
|
173
|
-
|
174
|
-
|
179
|
+
case flag
|
180
|
+
when :push
|
181
|
+
format_desc action, flag, 'tag,registry/username?,opts*'
|
182
|
+
task flag, [:tag] do |_, args|
|
183
|
+
tag = param_guard(action, flag, args: args, key: :tag)
|
184
|
+
image(flag, args.to_a.drop(1), id: tag)
|
185
|
+
end
|
186
|
+
else
|
187
|
+
format_desc(action, flag, flag == :rm ? 'id*,opts*' : 'opts*,args*')
|
188
|
+
task flag do |_, args|
|
189
|
+
image flag, args.to_a
|
190
|
+
end
|
175
191
|
end
|
176
192
|
end
|
177
193
|
end
|
@@ -299,7 +315,39 @@ module Squared
|
|
299
315
|
out = option_sanitize(opts, list, first: flag == :exec).first
|
300
316
|
from = :"container:#{flag}"
|
301
317
|
case flag
|
302
|
-
when :
|
318
|
+
when :run, :exec
|
319
|
+
if flag == :run && !session_arg?('mount')
|
320
|
+
run = VAL_DOCKER[:run]
|
321
|
+
both = run[:bind] + run[:tmpfs]
|
322
|
+
diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
|
323
|
+
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
324
|
+
as_a(@mounts).each do |val|
|
325
|
+
args = []
|
326
|
+
tmpfs = true
|
327
|
+
val.split(delim).each do |opt|
|
328
|
+
k, v, q = split_option(opt)
|
329
|
+
next unless both.include?(k)
|
330
|
+
|
331
|
+
if k == 'type'
|
332
|
+
tmpfs = false if v == 'bind'
|
333
|
+
next
|
334
|
+
elsif diff.include?(k)
|
335
|
+
tmpfs = false
|
336
|
+
end
|
337
|
+
case k
|
338
|
+
when 'readonly', 'ro'
|
339
|
+
args << k
|
340
|
+
next
|
341
|
+
when 'source', 'src', 'destination', 'dst', 'target'
|
342
|
+
v = basepath(v)
|
343
|
+
v = shell_quote(v, option: false, force: false) if q == ''
|
344
|
+
tmpfs = false if k[0] == 's'
|
345
|
+
end
|
346
|
+
args << "#{k}=#{q + v + q}"
|
347
|
+
end
|
348
|
+
cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
|
349
|
+
end
|
350
|
+
end
|
303
351
|
append_command(flag, id.to_s.empty? ? tag : id, out, target: cmd, from: from)
|
304
352
|
when :update
|
305
353
|
raise_error('missing container', hint: from) if out.empty?
|
@@ -352,8 +400,8 @@ module Squared
|
|
352
400
|
status = %w[created exited dead]
|
353
401
|
end
|
354
402
|
ps.merge(status.map { |s| "--filter=\"status=#{s}\"" })
|
355
|
-
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |
|
356
|
-
run(cmd.temp(
|
403
|
+
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
|
404
|
+
run(cmd.temp(img), from: from)
|
357
405
|
end
|
358
406
|
return
|
359
407
|
else
|
@@ -378,9 +426,8 @@ module Squared
|
|
378
426
|
break
|
379
427
|
end
|
380
428
|
end
|
381
|
-
flag = :run if flag == :list
|
382
429
|
list_image(flag, cmd << '-a', from: from) do |val|
|
383
|
-
container(
|
430
|
+
container(:run, if name
|
384
431
|
opts.dup << "name=#{index == 0 ? name : "#{name}-#{index}"}"
|
385
432
|
else
|
386
433
|
opts
|
@@ -405,12 +452,14 @@ module Squared
|
|
405
452
|
end
|
406
453
|
when :push
|
407
454
|
id ||= tag
|
455
|
+
registry ||= out.shift || @registry
|
408
456
|
raise_error(id ? "unknown args: #{out.join(', ')}" : 'no id/tag given', hint: from) unless id && out.empty?
|
409
|
-
|
410
|
-
|
457
|
+
raise_error('username/registry not provided', hint: from) unless registry
|
458
|
+
registry.chomp!('/')
|
459
|
+
uri = shell_quote("#{registry}/#{id}")
|
411
460
|
cmd << uri
|
412
461
|
img = docker_output 'image', 'tag', id, uri
|
413
|
-
return unless confirm_command(img.to_s, cmd.to_s, target: id, as:
|
462
|
+
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
414
463
|
|
415
464
|
run(img, exception: true, sync: false, banner: false)
|
416
465
|
end
|
@@ -478,20 +527,22 @@ module Squared
|
|
478
527
|
found = false
|
479
528
|
IO.popen(session_done(cmd << '--format=json')).each_with_index do |line, index|
|
480
529
|
data = JSON.parse(line)
|
530
|
+
id = data['ID']
|
481
531
|
rt = [data['Repository'], data['Tag']].reject { |val| val == '<none>' }.join(':')
|
482
|
-
rt = nil if
|
532
|
+
rt = nil if rt.empty?
|
483
533
|
aa = if data['Names']
|
484
534
|
as_a(data['Names']).join(', ')
|
485
|
-
elsif
|
535
|
+
elsif rt
|
486
536
|
dd = true
|
487
537
|
data['Repository']
|
488
538
|
else
|
489
|
-
|
539
|
+
id
|
490
540
|
end
|
491
541
|
bb = index.succ.to_s
|
492
542
|
cc = bb.size + 1
|
493
|
-
|
494
|
-
|
543
|
+
ee = data['Image'] || rt || aa
|
544
|
+
a = sub_style(ee, styles: theme[:inline])
|
545
|
+
b = "Execute #{sub_style(flag, styles: theme[:active])} on #{a}#{ee == id ? '' : " (#{id})"}"
|
495
546
|
c, d = no ? ['y/N', 'N'] : ['Y/n', 'Y']
|
496
547
|
e = time_format(time_offset(data['CreatedAt']), pass: ['ms'])
|
497
548
|
f = sub_style(ARG[:BORDER][0], styles: theme[:inline])
|
@@ -510,7 +561,7 @@ module Squared
|
|
510
561
|
next unless confirm("#{h + b}? [#{c}] ", d, timeout: 60)
|
511
562
|
|
512
563
|
puts if @@print_order == 0
|
513
|
-
blk.call
|
564
|
+
blk.call id
|
514
565
|
end
|
515
566
|
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) unless found
|
516
567
|
end
|
@@ -145,6 +145,8 @@ module Squared
|
|
145
145
|
|
146
146
|
module Project
|
147
147
|
class Git < Base
|
148
|
+
include Prompt
|
149
|
+
|
148
150
|
OPT_GIT = {
|
149
151
|
common: %w[bare p|paginate P|no-pager glob-pathspecs icase-pathspecs literal-pathspecs no-optional-locks
|
150
152
|
no-replace-objects noglob-pathspecs c=q config-env=q exec-path=p namespace=p].freeze,
|
@@ -300,10 +302,6 @@ module Squared
|
|
300
302
|
%i[pull rebase fetch clone stash status branch revbuild].freeze
|
301
303
|
end
|
302
304
|
|
303
|
-
def batchargs
|
304
|
-
[ref, { 'pull+s': %i[stash pull], 'rebase+s': %i[stash rebase] }]
|
305
|
-
end
|
306
|
-
|
307
305
|
def config?(val)
|
308
306
|
return false unless (val = as_path(val))
|
309
307
|
|
@@ -326,8 +324,8 @@ module Squared
|
|
326
324
|
'refs' => %i[heads tags remote].freeze,
|
327
325
|
'reset' => %i[commit index patch mode].freeze,
|
328
326
|
'rev' => %i[commit branch output parseopt build].freeze,
|
329
|
-
'show' => %i[format oneline].freeze,
|
330
|
-
'stash' => %i[push pop apply drop list].freeze,
|
327
|
+
'show' => %i[format oneline textconv].freeze,
|
328
|
+
'stash' => %i[push pop apply drop clear list].freeze,
|
331
329
|
'tag' => %i[add delete list].freeze
|
332
330
|
}.freeze
|
333
331
|
|
@@ -579,12 +577,18 @@ module Squared
|
|
579
577
|
when :oneline
|
580
578
|
format_desc action, flag, 'opts*,object*'
|
581
579
|
task flag do |_, args|
|
582
|
-
show
|
580
|
+
show flag, args.to_a.push('abbrev-commit')
|
583
581
|
end
|
584
582
|
when :format
|
585
583
|
format_desc action, flag, 'format?,opts*,object*'
|
586
584
|
task flag, [:format] do |_, args|
|
587
|
-
show args.
|
585
|
+
show(flag, args.extras, format: args.format)
|
586
|
+
end
|
587
|
+
when :textconv
|
588
|
+
format_desc action, flag, 'files+'
|
589
|
+
task flag do |_, args|
|
590
|
+
files = param_guard(action, flag, args: args.to_a)
|
591
|
+
show(flag, files: files)
|
588
592
|
end
|
589
593
|
end
|
590
594
|
when 'rebase', 'merge'
|
@@ -783,8 +787,15 @@ module Squared
|
|
783
787
|
when :push
|
784
788
|
append_pathspec refs
|
785
789
|
when :pop, :apply, :drop
|
786
|
-
|
787
|
-
|
790
|
+
unless refs.empty?
|
791
|
+
cmd << shell_escape(refs.pop)
|
792
|
+
option_clear refs
|
793
|
+
end
|
794
|
+
when :clear
|
795
|
+
if confirm("Remove #{sub_style('all', styles: theme[:active])} the stash entries? [y/N] ", 'N')
|
796
|
+
source(stdout: true)
|
797
|
+
end
|
798
|
+
return
|
788
799
|
when :list
|
789
800
|
out, banner, from = source(io: true)
|
790
801
|
print_item banner
|
@@ -1069,10 +1080,10 @@ module Squared
|
|
1069
1080
|
unless (origin = option('repository', prefix: 'git', ignore: false))
|
1070
1081
|
out = source(git_output('log -n1 --format=%h%d'), io: true, banner: false, stdout: true).first
|
1071
1082
|
if out =~ /^#{r[2]} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/
|
1072
|
-
split_escape($1).each do |
|
1073
|
-
next unless
|
1083
|
+
split_escape($1).each do |s|
|
1084
|
+
next unless s.end_with?("/#{branch}")
|
1074
1085
|
|
1075
|
-
origin =
|
1086
|
+
origin = s[0, s.size - branch.size - 1]
|
1076
1087
|
break
|
1077
1088
|
end
|
1078
1089
|
end
|
@@ -1218,8 +1229,21 @@ module Squared
|
|
1218
1229
|
source(stdout: stdout)
|
1219
1230
|
end
|
1220
1231
|
|
1221
|
-
def show(
|
1232
|
+
def show(flag, opts = [], format: nil, files: [])
|
1222
1233
|
cmd, opts = git_session('show', opts: opts)
|
1234
|
+
case flag
|
1235
|
+
when :textconv
|
1236
|
+
cmd << '--textconv'
|
1237
|
+
files = files.map { |val| Dir[val] }
|
1238
|
+
.flatten
|
1239
|
+
.select { |val| projectpath?(val) }
|
1240
|
+
.map { |val| shell_quote("HEAD:#{val}") }
|
1241
|
+
append_value files
|
1242
|
+
source(banner: false)
|
1243
|
+
return
|
1244
|
+
when :oneline
|
1245
|
+
format = flag.to_s
|
1246
|
+
end
|
1223
1247
|
if format
|
1224
1248
|
case (val = format.downcase)
|
1225
1249
|
when 'oneline', 'short', 'medium', 'full', 'fuller', 'reference', 'email', 'raw'
|
@@ -4,7 +4,7 @@ module Squared
|
|
4
4
|
module Workspace
|
5
5
|
module Project
|
6
6
|
class Python < Git
|
7
|
-
REQUIREMENTS = %w[requirements.txt pyproject.toml setup.cfg].freeze
|
7
|
+
REQUIREMENTS = %w[requirements.txt pyproject.toml setup.cfg poetry.lock].freeze
|
8
8
|
SETUPTOOLS = %w[setup.py pyproject.toml].freeze
|
9
9
|
DIR_PYTHON = (REQUIREMENTS + SETUPTOOLS).freeze
|
10
10
|
OPT_PYTHON = {
|
@@ -24,6 +24,12 @@ module Squared
|
|
24
24
|
python-version=q report=p r|requirement=p root=p root-user-action=b src=p t|target=p
|
25
25
|
upgrade-strategy=b].freeze
|
26
26
|
}.freeze
|
27
|
+
OPT_POETRY = {
|
28
|
+
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins P|project=p q|quiet v|verbose].freeze,
|
29
|
+
build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
|
30
|
+
publish: %w[build dry-run client-cert=p cert=p dist-dir=p p|password=b r|repository=b skip-existing
|
31
|
+
u|username=b].freeze
|
32
|
+
}.freeze
|
27
33
|
OPT_HATCH = {
|
28
34
|
common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=e
|
29
35
|
q|quiet v|verbose].freeze,
|
@@ -36,11 +42,11 @@ module Squared
|
|
36
42
|
config-file=p cert=p client-cert=p i|identity=b p|password=q r|repository=b repository-url=q
|
37
43
|
sign-with=b u|username=q].freeze
|
38
44
|
}.freeze
|
39
|
-
private_constant :REQUIREMENTS, :SETUPTOOLS, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :
|
45
|
+
private_constant :REQUIREMENTS, :SETUPTOOLS, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_HATCH,
|
46
|
+
:OPT_TWINE
|
40
47
|
|
41
48
|
class << self
|
42
49
|
def populate(*); end
|
43
|
-
def batchargs(*); end
|
44
50
|
|
45
51
|
def tasks
|
46
52
|
[:outdated].freeze
|
@@ -76,8 +82,8 @@ module Squared
|
|
76
82
|
|
77
83
|
@@tasks[ref] = {
|
78
84
|
'install' => %i[user force upgrade target editable].freeze,
|
79
|
-
'build' => %i[python hatch].freeze,
|
80
|
-
'publish' => %i[twine hatch].freeze
|
85
|
+
'build' => %i[python poetry hatch].freeze,
|
86
|
+
'publish' => %i[poetry twine hatch].freeze
|
81
87
|
}.freeze
|
82
88
|
|
83
89
|
def ref
|
@@ -131,12 +137,22 @@ module Squared
|
|
131
137
|
end
|
132
138
|
end
|
133
139
|
when 'build'
|
134
|
-
format_desc(action, flag, 'opts*', after: flag
|
140
|
+
format_desc(action, flag, 'opts*', after: case flag
|
141
|
+
when :python
|
142
|
+
'srcdir?'
|
143
|
+
when :hatch
|
144
|
+
'location?'
|
145
|
+
end)
|
135
146
|
task flag do |_, args|
|
136
147
|
buildx flag, args.to_a
|
137
148
|
end
|
138
149
|
when 'publish'
|
139
|
-
format_desc(action, flag, 'opts*', after: flag
|
150
|
+
format_desc(action, flag, 'opts*', after: case flag
|
151
|
+
when :hatch
|
152
|
+
'artifacts?'
|
153
|
+
when :twine
|
154
|
+
'dist?'
|
155
|
+
end)
|
140
156
|
task flag do |_, args|
|
141
157
|
publish flag, args.to_a
|
142
158
|
end
|
@@ -152,22 +168,27 @@ module Squared
|
|
152
168
|
super
|
153
169
|
elsif outdated?
|
154
170
|
workspace.rev_clear name
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
cmd << "--#{flag}"
|
159
|
-
when :target
|
160
|
-
cmd << quote_option('target', basepath(target))
|
161
|
-
when :force
|
162
|
-
cmd << '--force-reinstall'
|
171
|
+
if !flag && dependtype == 4
|
172
|
+
cmd = session 'poetry', 'install'
|
173
|
+
cmd << '--no-root' if option('no-root')
|
163
174
|
else
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
175
|
+
cmd = pip_session 'install'
|
176
|
+
case flag
|
177
|
+
when :user
|
178
|
+
cmd << "--#{flag}"
|
179
|
+
when :target
|
180
|
+
cmd << quote_option('target', basepath(target))
|
181
|
+
when :force
|
182
|
+
cmd << '--force-reinstall'
|
183
|
+
else
|
184
|
+
append_global
|
185
|
+
end
|
186
|
+
append_pip(flag, opts, from: :install) if flag
|
187
|
+
if dependtype == 1 && !session_arg?('e', 'editable')
|
188
|
+
cmd << '-r requirements.txt' unless session_arg?('r', 'requirement')
|
189
|
+
elsif !session_arg?('e', 'editable', value: true)
|
190
|
+
cmd << '.'
|
191
|
+
end
|
171
192
|
end
|
172
193
|
run(from: :depend, sync: sync)
|
173
194
|
end
|
@@ -269,6 +290,9 @@ module Squared
|
|
269
290
|
when :python
|
270
291
|
cmd << shell_option('m', 'build')
|
271
292
|
list = OPT_PYTHON[:build] + OPT_PYTHON[:common]
|
293
|
+
when :poetry
|
294
|
+
cmd << 'build'
|
295
|
+
list = OPT_POETRY[:build] + OPT_POETRY[:common]
|
272
296
|
when :hatch
|
273
297
|
cmd << 'build'
|
274
298
|
list = OPT_HATCH[:build] + OPT_HATCH[:common]
|
@@ -282,7 +306,17 @@ module Squared
|
|
282
306
|
out << opt
|
283
307
|
end
|
284
308
|
end
|
285
|
-
|
309
|
+
case flag
|
310
|
+
when :poetry
|
311
|
+
if srcdir
|
312
|
+
if session_arg?('o', 'output')
|
313
|
+
out << srcdir
|
314
|
+
else
|
315
|
+
cmd << quote_option('output', basepath(srcdir))
|
316
|
+
end
|
317
|
+
srcdir = nil
|
318
|
+
end
|
319
|
+
when :hatch
|
286
320
|
if ENV['HATCH_BUILD_LOCATION']
|
287
321
|
srcdir = nil
|
288
322
|
else
|
@@ -299,6 +333,9 @@ module Squared
|
|
299
333
|
cmd = session flag
|
300
334
|
out = []
|
301
335
|
case flag
|
336
|
+
when :poetry
|
337
|
+
cmd << 'publish'
|
338
|
+
list = OPT_POETRY[:publish] + OPT_POETRY[:common]
|
302
339
|
when :twine
|
303
340
|
cmd << 'upload'
|
304
341
|
list = OPT_TWINE[:publish]
|
@@ -307,7 +344,7 @@ module Squared
|
|
307
344
|
list = OPT_HATCH[:publish] + OPT_HATCH[:common]
|
308
345
|
end
|
309
346
|
option_sanitize(opts, list).first.each do |opt|
|
310
|
-
if flag
|
347
|
+
if flag != :twine && opt =~ /^(v+|q+)$/
|
311
348
|
cmd << "-#{$1}"
|
312
349
|
else
|
313
350
|
out << opt
|
@@ -316,7 +353,7 @@ module Squared
|
|
316
353
|
if out.empty?
|
317
354
|
dist = basepath.join('dist')
|
318
355
|
raise_error('no source files given', hint: dist) unless dist.directory? && !dist.empty?
|
319
|
-
out << "#{dist}/*"
|
356
|
+
out << "#{dist}/*" unless flag == :poetry
|
320
357
|
end
|
321
358
|
append_value out
|
322
359
|
run(from: :"#{flag}:publish")
|
@@ -39,7 +39,6 @@ module Squared
|
|
39
39
|
|
40
40
|
class << self
|
41
41
|
def populate(*); end
|
42
|
-
def batchargs(*); end
|
43
42
|
|
44
43
|
def tasks
|
45
44
|
[:outdated].freeze
|
@@ -155,7 +154,7 @@ module Squared
|
|
155
154
|
when 'gem'
|
156
155
|
case flag
|
157
156
|
when :outdated, :build, :push, :exec
|
158
|
-
format_desc
|
157
|
+
format_desc(action, flag, 'opts*', before: flag == :exec ? 'command+' : nil)
|
159
158
|
task flag do |_, args|
|
160
159
|
gemx flag, args.to_a
|
161
160
|
end
|
@@ -471,7 +470,7 @@ module Squared
|
|
471
470
|
end
|
472
471
|
when :exec
|
473
472
|
raise_error('no command given', hint: flag) if out.empty?
|
474
|
-
cmd << out.join(' ')
|
473
|
+
cmd << project << out.join(' ')
|
475
474
|
else
|
476
475
|
raise_error('no gemname given', hint: flag) if out.empty? && !session_arg?('system')
|
477
476
|
if flag == :pristine
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- An Pham
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03-
|
10
|
+
date: 2025-03-28 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rake
|