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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6a70feacca1b87fbe9d6da4e71045212f5dc5e9add78e93e8223a5f73b6f6d9
4
- data.tar.gz: b73756bef57213d92fe4ed5f0763945645315a06a8d084bb32e40105ce78d64e
3
+ metadata.gz: 41bec81d0daef581416b2c3c7a6cefc66da439794df530c5b2e9c65f7feba6ae
4
+ data.tar.gz: 8b74836f62055cc6d173148753420ac2bb621e951f1d339cae60ed35357c6f5f
5
5
  SHA512:
6
- metadata.gz: 34c45acd9506ad1bc7018c0b0f73e1e2db7623d6b42b7b3199ee7cb7394716a1ec13484d15a71d343415ccd4090a1217579416fba8010b5977cbc324bbf7b849
7
- data.tar.gz: 62ac8c5ea8289fcb08dbf1c5e2cca60e06ea5470eb1f8ec1ce667bcce5cc0eec5d67448ac1b2642a7b5af0c2f3e30530f6513374d2642baa2993aca3ad769608
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", args: "--ssh=default", secrets: ["id=github,env=GITHUB_TOKEN"]) do # Docker
109
- series(:clean) do # run | depend | doc | lint | test | copy | clean
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 >= 0 && val <= 256
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(ARG[:SPACE]) + (hint ? " (#{hint})" : '')
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.map(&:chomp)
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)
@@ -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 >= 0 && key <= 2
157
+ return key if key.between?(0, 2)
145
158
  end
146
159
  default
147
160
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.2'
5
5
  end
@@ -264,7 +264,7 @@ module Squared
264
264
 
265
265
  format_desc action, flag, '(-)project*'
266
266
  task flag do |_, args|
267
- args = param_guard(action, flag, args: args.to_a.reject { |val| name == val.to_s })
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 { |file| FileUtils.mv(file, target) }
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=q name=b network=b
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
- private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER
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
- format_desc(action, flag, flag == :rm ? 'id*,opts*' : 'opts*,args*')
173
- task flag do |_, args|
174
- image flag, args.to_a
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 :exec, :run
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 |id|
356
- run(cmd.temp(id), from: from)
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(flag, if name
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
- reg = (registry || @registry).chomp('/')
410
- uri = shell_quote("#{reg}/#{id}")
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: reg, title: from)
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 tag.empty?
532
+ rt = nil if rt.empty?
483
533
  aa = if data['Names']
484
534
  as_a(data['Names']).join(', ')
485
- elsif tag
535
+ elsif rt
486
536
  dd = true
487
537
  data['Repository']
488
538
  else
489
- data['ID']
539
+ id
490
540
  end
491
541
  bb = index.succ.to_s
492
542
  cc = bb.size + 1
493
- a = sub_style(data['Image'] || rt || aa, styles: theme[:inline])
494
- b = "Execute #{sub_style(flag, styles: theme[:active])} on #{a} (#{data['ID']})"
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 data['ID']
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 'oneline', args.to_a.push('abbrev-commit')
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.format, args.extras
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
- cmd << shell_quote(refs.pop)
787
- option_clear refs
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 |val|
1073
- next unless val.end_with?("/#{branch}")
1083
+ split_escape($1).each do |s|
1084
+ next unless s.end_with?("/#{branch}")
1074
1085
 
1075
- origin = val[0, val.size - branch.size - 1]
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(format, opts = [])
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,8 +4,6 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Node < Git
7
- include Prompt
8
-
9
7
  OPT_NPM = {
10
8
  common: %w[dry-run include-workspace-root workspaces=b? w|workspace=b].freeze,
11
9
  install: %w[prefer-dedupe package-lock-only cpu=b libc=b os=b].freeze,
@@ -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, :OPT_HATCH, :OPT_TWINE
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 == :hatch ? 'location?' : 'srcdir?')
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 == :hatch ? 'artifacts?' : 'dist?')
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
- cmd = pip_session 'install'
156
- case flag
157
- when :user
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
- append_global
165
- end
166
- append_pip(flag, opts, from: :install) if flag
167
- if dependtype == 1 && !session_arg?('e', 'editable')
168
- cmd << '-r requirements.txt' unless session_arg?('r', 'requirement')
169
- elsif !session_arg?('e', 'editable', value: true)
170
- cmd << '.'
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
- if flag == :hatch
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 == :hatch && opt =~ /^(v+|q+)$/
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 action, flag, 'opts*'
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.0
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-06 00:00:00.000000000 Z
10
+ date: 2025-03-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake