squared 0.5.7 → 0.5.8

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: a2f2ae101197ffdfdc4f744db59b842e2d1d7f333f9fd2f450ea94aa89a57dcd
4
- data.tar.gz: b935b9e2787c79ea413e3449df1ba53e524928f0f1a48e90639147c91a945e43
3
+ metadata.gz: ec0306a0e60a4854a3c3be267b5c66577702dee8908bf36eb7c4ccfb98b2b4ff
4
+ data.tar.gz: 3463f8bce9cfe67a18a2e09d9d7358a4f8c8bebcddc9037612bfc1cb2b213d93
5
5
  SHA512:
6
- metadata.gz: 982f19b327aa713258196aeaa3514edbc685840f838cc25eef01c7fef812807c9ac089b67d0145e6d6ee70ee1f57620b5254b9fe23bf6315a40a8d8dfa9a9816
7
- data.tar.gz: 59ba49e317403c120081d842afb0e9747a63b79669bd852fa064e09da51176a3bdcbad973b7c64b771a1ccb8ac58654918d830719c8700610c5de07fb7096d07
6
+ metadata.gz: 1f47734d5f11de8e4106ab249a276b3e42ca9d70de61863a24f51e65b579a187a27cfad2b21593d9a79bb0aeb9a6a192775e3753d3ff02d546fee06057cf7cd1
7
+ data.tar.gz: 01b1520fe506cdb8d8e08213794aaa72d8a55e7ddb51b139573d67ee46e613d9ee600809799972b57a1f3435e8672f0b3ea3d8398e381cc72bdf955d9e330c58
data/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.8] - 2025-10-01
4
+
5
+ ### Fixed
6
+
7
+ - See `0.4.21`.
8
+
9
+ ## [0.4.21] - 2025-10-01
10
+
11
+ ### Added
12
+
13
+ - Project base method variable_set was aliased to the name apply.
14
+
15
+ ### Changed
16
+
17
+ - Project base method run visibility was changed to public.
18
+ - OptionPartition method uniq! returns self or nil.
19
+
20
+ ### Fixed
21
+
22
+ - Docker attribute file did not search for nearest config.
23
+ - Project task run did not accept Proc or Method definitions.
24
+ - Gem command options were revalidated to 3.7.2.
25
+ - Bundler command options were revalidated to 2.7.2.
26
+ - Ruby class method bundle did not pass through commands.
27
+ - Ruby task ruby did not separate options and arguments.
28
+ - Pip commands uninstall and freeze did not filter options.
29
+ - Ruby command gem action update did not append packages.
30
+ - OptionPartition did not detect short options with a merged value.
31
+ - Gem commands option version did not use quotes.
32
+ - Git command pull action all used undefined delete_prefix! method.
33
+ - OptionPartition did not delete added values from extras.
34
+ - Python editable projects can override requirements detection.
35
+ - Project session method did delete short options with a merged value.
36
+ - Gem command install did not try to resolve local paths.
37
+ - Ruby commands did not always check for file target exists.
38
+
3
39
  ## [0.5.7] - 2025-09-14
4
40
 
5
41
  ### Fixed
@@ -1047,6 +1083,7 @@
1047
1083
 
1048
1084
  - Changelog was created.
1049
1085
 
1086
+ [0.5.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.8
1050
1087
  [0.5.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.7
1051
1088
  [0.5.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.6
1052
1089
  [0.5.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.5
@@ -1055,6 +1092,7 @@
1055
1092
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1056
1093
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1057
1094
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1095
+ [0.4.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.21
1058
1096
  [0.4.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.20
1059
1097
  [0.4.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.19
1060
1098
  [0.4.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.18
data/README.md CHANGED
@@ -108,9 +108,9 @@ Workspace::Application
108
108
  revbuild(include: %w[src/ framework/ types/]) # Synchronous is recommended
109
109
  end
110
110
  .add("squared/sqd", exclude: :git, pass: [:node, "checkout", "bump"]) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
111
- variable_set :script, "build:sqd" # Override detection
112
- variable_set :depend, false
113
- variable_set :clean, ["build/sqd/"]
111
+ apply :script, "build:sqd" # Override detection
112
+ apply :depend, false #
113
+ apply :clean, ["build/sqd/"] # variable_set (alias)
114
114
  end
115
115
  .with(:docker, only: ["build", "compose"]) do
116
116
  .add("squared", "docker", file: "Dockerfile", context: ".", tag: "latest", registry: "localhost:5000", username: "squared",
@@ -306,7 +306,7 @@ Workspace::Application
306
306
  doc(windows? ? ".\make.bat html" : "make html") # rake android-docs:doc | rake doc:python
307
307
  add("android-docs", "android", venv: "/home/user/.venv") # rake android-docs:depend
308
308
  add("chrome-docs", "chrome", graph: "android", venv: %w[.venv --clear]) do # /workspaces/chrome-docs/.venv
309
- variable_set :dependindex, 1 # Use Poetry for dependencies (optional)
309
+ apply :dependindex, 1 # Use Poetry for dependencies (optional)
310
310
  end
311
311
  end
312
312
  .with(:node) do
@@ -498,21 +498,22 @@ Most project classes will inherit from `Git` which enables these tasks:
498
498
 
499
499
  | Task | Git | Command |
500
500
  | :--------- | :--------------- | :-------------------------------------------- |
501
- | branch | branch | create set delete move copy list edit current |
501
+ | branch | branch | create track delete move copy list current |
502
502
  | checkout | checkout | commit branch track detach path |
503
503
  | commit | commit | add all amend amend-orig fixup |
504
- | diff | diff | head cached branch files between contain |
504
+ | diff | diff | head branch files view between contain |
505
505
  | fetch | fetch | origin remote all |
506
506
  | files | ls-files | cached modified deleted others |
507
- | git | | add blame clean mv rm revert status |
507
+ | git | | add blame clean mv revert rm status |
508
+ | log | log | view between contain |
508
509
  | merge | merge | commit no-commit send |
509
510
  | pull | pull | origin remote all |
510
511
  | rebase | rebase | branch onto send |
511
512
  | refs | ls-remote --refs | heads tags remote |
512
- | reset | reset | commit index patch mode |
513
- | restore | restore | staged worktree |
514
- | rev | rev | commit output |
515
- | show | show | format oneline |
513
+ | reset | reset | commit index patch mode undo |
514
+ | restore | restore | source staged worktree |
515
+ | rev | rev | commit build output |
516
+ | show | show | format oneline textconv |
516
517
  | stash | stash | push pop apply branch drop clear list all |
517
518
  | submodule | submodule | status update branch url sync |
518
519
  | switch | switch | branch create detach |
@@ -599,6 +600,9 @@ BUILD_${NAME}_VERSION=0.1.0 # publish + detection
599
600
  BANNER=0 # hide banner
600
601
  BANNER_${NAME}=0 #
601
602
 
603
+ VERBOSE=0 # console output level
604
+ VERBOSE_${NAME}=0 # 0,1,2,n
605
+
602
606
  REVBUILD_FORCE=1 # Rebuild all targets
603
607
  REVBUILD_FORCE_${NAME}=1 # Rebuild project
604
608
 
@@ -641,7 +645,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
641
645
  | :--------- | :---------------- | :-------------------------------------------------------------------- |
642
646
  | branch | create | TRACK=0,1,s F|FORCE |
643
647
  | branch | move copy | F|FORCE |
644
- | branch | set delete | COUNT=n |
648
+ | branch | delete | COUNT=n |
645
649
  | branch | global | SYNC |
646
650
  | checkout | branch | DETACH TRACK=s COUNT=n |
647
651
  | checkout | detach | REFLOG=1 |
@@ -191,7 +191,7 @@ module Squared
191
191
  emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub, pipe: -1)
192
192
  else
193
193
  msg = [log_title(level, color: color)]
194
- msg << (color ? sub_style(subject, styles: (@theme && @theme[:subject]) || :bold) : subject) if subject
194
+ msg << (color ? sub_style(subject.to_s, styles: (@theme && @theme[:subject]) || :bold) : subject) if subject
195
195
  msg << args.shift if msg.size == 1
196
196
  message(msg.join(' '), *args, hint: hint)
197
197
  end
@@ -225,12 +225,8 @@ module Squared
225
225
  def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
226
226
  border: @theme && @theme[:border])
227
227
  n = 0
228
- max = ->(v) { n = [n, v.max_by(&:size).size].max }
229
- set = lambda do |v|
230
- ret = Array(v).map(&:to_s)
231
- max.call(ret)
232
- ret
233
- end
228
+ max = ->(a) { n = [n, a.max_by(&:size).size].max }
229
+ set = ->(s) { Array(s).map(&:to_s).tap { |a| max.call(a) } }
234
230
  title &&= set.call(title)
235
231
  footer &&= set.call(footer)
236
232
  if val.is_a?(::Array)
@@ -89,8 +89,11 @@ module Squared
89
89
  end
90
90
 
91
91
  def time_since(val, ms: true)
92
- s = ms ? '%s%L' : '%s'
93
- Time.now.utc.strftime(s).to_i - Time.parse(val).utc.strftime(s).to_i
92
+ time_epoch(ms: ms) - time_epoch(Time.parse(val), ms: ms)
93
+ end
94
+
95
+ def time_epoch(val = Time.now, ms: true)
96
+ val.utc.strftime(ms ? '%s%L' : '%s').to_i
94
97
  end
95
98
 
96
99
  def rand_s(size)
@@ -213,7 +213,7 @@ module Squared
213
213
  ext[0] = mime
214
214
  elsif file
215
215
  keys.prepend(file)
216
- alt = basepath("#{main}.{#{ext.join(',')}}")
216
+ alt = basepath "#{main}.{#{ext.join(',')}}"
217
217
  file = Dir[alt].first
218
218
  else
219
219
  alt = main
@@ -347,8 +347,8 @@ module Squared
347
347
  basepath(file = main + @ext).to_s rescue file
348
348
  end
349
349
 
350
- def basepath(file)
351
- project ? project.basepath(file) : Pathname.pwd + file
350
+ def basepath(*args)
351
+ project ? project.basepath(*args) : Pathname.pwd.join(*args)
352
352
  end
353
353
  end
354
354
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.7'
4
+ VERSION = '0.5.8'
5
5
  end
@@ -634,7 +634,9 @@ module Squared
634
634
  end
635
635
 
636
636
  def home?
637
- !(proj = find(home)).nil? && proj.enabled?
637
+ return false unless (proj = find(home))
638
+
639
+ proj.enabled?
638
640
  end
639
641
 
640
642
  def windows?
@@ -9,6 +9,7 @@ module Squared
9
9
  module Workspace
10
10
  module Project
11
11
  class Base
12
+ include Comparable
12
13
  include Common::Format
13
14
  include System
14
15
  include Shell
@@ -16,7 +17,6 @@ module Squared
16
17
  include Utils
17
18
  include Support
18
19
  include Rake::DSL
19
- include ::Comparable
20
20
 
21
21
  VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
22
22
  pass only exclude asdf].freeze
@@ -89,6 +89,7 @@ module Squared
89
89
  @name = name.to_s.freeze
90
90
  @project = @path.basename.to_s.freeze
91
91
  @group = group&.to_s.freeze
92
+ @envname = env_key(@name).freeze
92
93
  @depend = kwargs[:depend]
93
94
  @doc = kwargs[:doc]
94
95
  @lint = kwargs[:lint]
@@ -105,7 +106,6 @@ module Squared
105
106
  @children = []
106
107
  @events = hashobj.update({ first: first, last: last, error: error })
107
108
  @as = hashobj
108
- @envname = env_key(@name).freeze
109
109
  @desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
110
110
  @parent = nil
111
111
  @global = false
@@ -208,7 +208,7 @@ module Squared
208
208
  file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
209
209
  rescue StandardError => e
210
210
  file = nil
211
- warn log_message(Logger::WARN, e) if warning?
211
+ print_error e
212
212
  end
213
213
  log[:progname] ||= @name
214
214
  if (val = env('LOG_LEVEL', ignore: false))
@@ -300,7 +300,7 @@ module Squared
300
300
  end
301
301
 
302
302
  def verbose=(val)
303
- @verbose = case val
303
+ @verbose = case (val = env('VERBOSE', val))
304
304
  when NilClass
305
305
  workspace.verbose
306
306
  when String
@@ -375,7 +375,7 @@ module Squared
375
375
  else
376
376
  force = args.fetch(:force, false)
377
377
  end
378
- unpack(path + dir, uri: tag, digest: digest, ext: ext, force: force)
378
+ unpack(basepath(dir), uri: tag, digest: digest, ext: ext, force: force)
379
379
  end
380
380
  when 'asdf'
381
381
  break unless @asdf
@@ -435,14 +435,13 @@ module Squared
435
435
  name = @name if name == true
436
436
  path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
437
437
  return self
438
- elsif !projectpath?(path = basepath(path)) || !checkdir?(path)
439
- return self
440
438
  end
439
+ return self unless projectpath?(path = basepath(path)) && checkdir?(path)
440
+
441
441
  kwargs = @withargs.yield_self { |data| data.dup.update(kwargs) } if @withargs
442
442
  kwargs[:group] = group unless kwargs.key?(:group)
443
443
  kwargs[:ref] = ref unless kwargs.key?(:ref)
444
444
  parent = self
445
- proj = nil
446
445
  name = case name
447
446
  when String, Symbol
448
447
  name.to_s
@@ -451,10 +450,9 @@ module Squared
451
450
  end
452
451
  workspace.add(path, name, **kwargs) do
453
452
  __send__ :parent_set, parent
454
- proj = self
453
+ @children << self
454
+ instance_eval(&blk) if block_given?
455
455
  end
456
- @children << proj
457
- proj.instance_eval(&blk) if block_given?
458
456
  self
459
457
  end
460
458
 
@@ -468,7 +466,7 @@ module Squared
468
466
 
469
467
  out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
470
468
  if !out
471
- warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
469
+ print_error('link not compatible', subject: obj, hint: name)
472
470
  elsif out.respond_to?(:build)
473
471
  out.build
474
472
  end
@@ -516,6 +514,10 @@ module Squared
516
514
  else
517
515
  cmd, opts, var, flags, extra = args
518
516
  end
517
+ if cmd.is_a?(Proc) || cmd.is_a?(Method)
518
+ run_b(cmd, sync: sync, from: from)
519
+ return
520
+ end
519
521
  if cmd
520
522
  cmd = as_get(cmd, from)
521
523
  opts = compose(opts, script: false) if opts && respond_to?(:compose)
@@ -559,7 +561,7 @@ module Squared
559
561
  on_error(:prereqs, e, exception: true)
560
562
  end
561
563
  end
562
- warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
564
+ print_error(name, 'method not found', subject: 'prereqs', hint: meth)
563
565
  end
564
566
  elsif proj.build?
565
567
  proj.build(sync: sync)
@@ -614,7 +616,7 @@ module Squared
614
616
  else
615
617
  if @clean.is_a?(Enumerable) && !series?(@clean)
616
618
  @clean.each do |val|
617
- entry = path + (val = val.to_s)
619
+ entry = basepath(val = val.to_s)
618
620
  if entry.directory? && val.match?(%r{[\\/]\z})
619
621
  log&.warn "rm -rf #{entry}"
620
622
  rm_rf(entry, verbose: verbose)
@@ -623,11 +625,9 @@ module Squared
623
625
  (val.include?('*') ? Dir[entry] : [entry]).each do |file|
624
626
  next unless File.file?(file)
625
627
 
626
- begin
627
- File.delete(file)
628
- rescue StandardError => e
629
- log&.error e
630
- end
628
+ File.delete(file)
629
+ rescue StandardError => e
630
+ log&.error e
631
631
  end
632
632
  end
633
633
  end
@@ -748,7 +748,7 @@ module Squared
748
748
  delete = true
749
749
  end
750
750
  if create
751
- warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
751
+ print_error('force remove', subject: name, hint: target)
752
752
  target.rmtree
753
753
  target.mkpath
754
754
  end
@@ -866,6 +866,55 @@ module Squared
866
866
  self
867
867
  end
868
868
 
869
+ def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
870
+ interactive: nil, hint: nil, **)
871
+ unless cmd
872
+ print_error('no command given', subject: project, hint: from || 'unknown', pass: true)
873
+ return
874
+ end
875
+ cmd = cmd.target if cmd.is_a?(OptionPartition)
876
+ if interactive && (!@session || !option('y'))
877
+ title, y = case interactive
878
+ when Array
879
+ interactive
880
+ when String
881
+ [interactive, 'N']
882
+ else
883
+ ['Run', 'Y']
884
+ end
885
+ exit 1 unless confirm("#{title}? [#{sub_style(cmd.to_s, styles: theme[:inline])}]", y)
886
+ end
887
+ cmd = session_done cmd
888
+ log&.info cmd
889
+ on :first, from
890
+ begin
891
+ if cmd.start_with?(/[^:]+:[^:]/) && workspace.task_defined?(cmd)
892
+ log&.warn "ENV discarded: #{var}" if var
893
+ task_invoke(cmd, exception: exception, warning: warning?)
894
+ else
895
+ print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
896
+ if var != false && (pre = runenv)
897
+ case pre
898
+ when Hash
899
+ var = var.is_a?(Hash) ? pre.merge(var) : pre
900
+ when Enumerable
901
+ cmd = command(*pre.to_a, cmd)
902
+ else
903
+ cmd = command pre, cmd
904
+ end
905
+ end
906
+ args = var.is_a?(Hash) ? [var, cmd] : [cmd]
907
+ ret = shell(*args, chdir: chdir, exception: exception)
908
+ end
909
+ rescue StandardError => e
910
+ on_error(from, e, exception: true)
911
+ false
912
+ else
913
+ on :last, from
914
+ ret
915
+ end
916
+ end
917
+
869
918
  def variable_set(key, *args, **kwargs, &blk)
870
919
  if block_given?
871
920
  if blocks.include?(key)
@@ -917,6 +966,8 @@ module Squared
917
966
  self
918
967
  end
919
968
 
969
+ alias apply variable_set
970
+
920
971
  def enabled?(ref = nil, **)
921
972
  return false if ref && !ref?(ref)
922
973
 
@@ -1027,7 +1078,7 @@ module Squared
1027
1078
  path.parent.ascend.each do |dir|
1028
1079
  target = dir.join(*args)
1029
1080
  return target if target.exist?
1030
- break if (ascend.is_a?(String) && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1081
+ break if (ascend && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1031
1082
  end
1032
1083
  ret
1033
1084
  end
@@ -1054,55 +1105,6 @@ module Squared
1054
1105
  log_console(*args, pipe: kwargs[:pipe] || pipe)
1055
1106
  end
1056
1107
 
1057
- def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
1058
- interactive: nil, hint: nil, **)
1059
- unless cmd
1060
- warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
1061
- return
1062
- end
1063
- cmd = cmd.target if cmd.is_a?(OptionPartition)
1064
- if interactive && (!@session || !option('y'))
1065
- title, y = case interactive
1066
- when Array
1067
- interactive
1068
- when String
1069
- [interactive, 'N']
1070
- else
1071
- ['Run', 'Y']
1072
- end
1073
- exit 1 unless confirm("#{title}? [#{sub_style(cmd.to_s, styles: theme[:inline])}]", y)
1074
- end
1075
- cmd = session_done cmd
1076
- log&.info cmd
1077
- on :first, from
1078
- begin
1079
- if cmd.start_with?(/[^:]+:[^:]/) && workspace.task_defined?(cmd)
1080
- log&.warn "ENV discarded: #{var}" if var
1081
- task_invoke(cmd, exception: exception, warning: warning?)
1082
- else
1083
- print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
1084
- if var != false && (pre = runenv)
1085
- case pre
1086
- when Hash
1087
- var = var.is_a?(Hash) ? pre.merge(var) : pre
1088
- when Enumerable
1089
- cmd = command(*pre.to_a, cmd)
1090
- else
1091
- cmd = command pre, cmd
1092
- end
1093
- end
1094
- args = var.is_a?(Hash) ? [var, cmd] : [cmd]
1095
- ret = shell(*args, chdir: chdir, exception: exception)
1096
- end
1097
- rescue StandardError => e
1098
- on_error(from, e, exception: true)
1099
- false
1100
- else
1101
- on :last, from
1102
- ret
1103
- end
1104
- end
1105
-
1106
1108
  def run_s(*cmd, env: nil, sync: true, from: nil, banner: verbose != false, **kwargs)
1107
1109
  on :first, from
1108
1110
  begin
@@ -1301,15 +1303,7 @@ module Squared
1301
1303
  end
1302
1304
 
1303
1305
  def session_delete(*args, target: @session)
1304
- ret = []
1305
- args.each do |val|
1306
- pat = /\A#{Regexp.escape(shell_option(val))}(?: |=|\z)/
1307
- if (key = target.find { |opt| opt.match?(pat) })
1308
- target.delete(key)
1309
- ret << key
1310
- end
1311
- end
1312
- ret
1306
+ OptionPartition.delete(target, *args)
1313
1307
  end
1314
1308
 
1315
1309
  def session_output(*cmd, **kwargs)
@@ -1351,8 +1345,8 @@ module Squared
1351
1345
  puts 'Success'
1352
1346
  end
1353
1347
 
1354
- def print_error(err, loglevel: Logger::WARN, pass: false)
1355
- warn log_message(loglevel, err, pass: pass) if warning?
1348
+ def print_error(*args, loglevel: Logger::WARN, **kwargs)
1349
+ warn log_message(loglevel, *args, **kwargs) if warning?
1356
1350
  end
1357
1351
 
1358
1352
  def print_item(*val)
@@ -1410,7 +1404,7 @@ module Squared
1410
1404
  if verbose && kwargs[:start]
1411
1405
  msg = sub_style('completed', styles: theme[:active])
1412
1406
  puts log_message(Logger::INFO, *args, msg, subject: kwargs[:subject],
1413
- hint: time_format(epochtime - kwargs[:start]))
1407
+ hint: time_format(time_epoch - kwargs[:start]))
1414
1408
  end
1415
1409
  end
1416
1410
  end
@@ -1522,7 +1516,7 @@ module Squared
1522
1516
  next if (key = key.to_s).start_with?('__')
1523
1517
 
1524
1518
  if val.nil? || extra || session_arg?(key, target: target)
1525
- session_delete(key, target: target)
1519
+ OptionPartition.delete_key(target, key)
1526
1520
  next if val.nil?
1527
1521
  end
1528
1522
  case val
@@ -1658,7 +1652,7 @@ module Squared
1658
1652
  raise_error("invalid JSON #{kind.name}", val, hint: hint) if kind && !ret.is_a?(kind)
1659
1653
  rescue StandardError => e
1660
1654
  log&.warn e
1661
- warn log_message(Logger::WARN, e, subject: name) if warning?
1655
+ print_error(e, subject: name)
1662
1656
  else
1663
1657
  ret
1664
1658
  end
@@ -1786,7 +1780,7 @@ module Squared
1786
1780
  raise_error 'pathspec not within worktree' unless pass || files.size == proj.size
1787
1781
  files = proj
1788
1782
  end
1789
- files.map { |val| val == '.' ? '.' : shell_quote(path + val) }
1783
+ files.map { |val| val == '.' ? '.' : shell_quote(basepath(val)) }
1790
1784
  end
1791
1785
 
1792
1786
  def matchmap(list, prefix = nil)
@@ -2041,7 +2035,7 @@ module Squared
2041
2035
 
2042
2036
  def dependfile_set(list)
2043
2037
  @dependindex = list.index { |file| basepath(file).exist? }.tap do |index|
2044
- @dependfile = @path + list[index || 0]
2038
+ @dependfile = basepath(list[index || 0])
2045
2039
  end
2046
2040
  end
2047
2041
 
@@ -6,7 +6,7 @@ module Squared
6
6
  class Docker < Base
7
7
  COMPOSEFILE = %w[compose.yaml compose.yml docker-compose.yaml docker-compose.yml].freeze
8
8
  BAKEFILE = %w[docker-bake.json docker-bake.hcl docker-bake.override.json docker-bake.override.hcl].freeze
9
- DIR_DOCKER = (COMPOSEFILE + BAKEFILE).freeze
9
+ DIR_DOCKER = (COMPOSEFILE + BAKEFILE + ['Dockerfile']).freeze
10
10
  OPT_DOCKER = {
11
11
  common: %w[tls tlsverify config=p c|context=b D|debug H|host=q l|log-level=b tlscacert=p tlscert=p
12
12
  tlskey=p].freeze,
@@ -91,7 +91,7 @@ module Squared
91
91
  def config?(val)
92
92
  return false unless (val = as_path(val))
93
93
 
94
- val.join('Dockerfile').exist? || DIR_DOCKER.any? { |file| val.join(file).exist? }
94
+ DIR_DOCKER.any? { |file| val.join(file).exist? }
95
95
  end
96
96
  end
97
97
 
@@ -310,7 +310,7 @@ module Squared
310
310
  append_context
311
311
  when :bake, :compose
312
312
  option(from == :bake ? 'target' : 'service', ignore: false) do |a|
313
- ret.merge(split_escape(a).map! { |b| shell_escape(b) })
313
+ ret.merge(split_escape(a).map! { |b| shell_quote(b) })
314
314
  end
315
315
  end
316
316
  ret
@@ -412,7 +412,7 @@ module Squared
412
412
  args << k
413
413
  next
414
414
  when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
415
- v = path + v
415
+ v = basepath v
416
416
  v = shell_quote(v, option: false, force: false) if q == ''
417
417
  end
418
418
  args << "#{k}=#{q + v + q}"
@@ -586,16 +586,15 @@ module Squared
586
586
  end
587
587
 
588
588
  def dockerfile(val = nil)
589
- if val == 'Dockerfile'
590
- @file = false
591
- elsif val
589
+ if val
592
590
  @file = if val.is_a?(Array)
593
591
  val = val.select { |file| basepath(file).exist? }
594
592
  val.size > 1 ? val : val.first
595
- else
596
- val || DIR_DOCKER.find { |file| basepath(file).exist? }
593
+ elsif val == true
594
+ DIR_DOCKER.find { |file| basepath(file).exist? }
595
+ elsif val != 'Dockerfile'
596
+ val
597
597
  end
598
- @file ||= false
599
598
  end
600
599
  basepath((@file.is_a?(Array) ? @file.first : @file) || 'Dockerfile')
601
600
  end
@@ -604,9 +603,9 @@ module Squared
604
603
 
605
604
  def read_composefile(*keys, target: nil)
606
605
  require 'yaml'
607
- target = ENV['COMPOSE_FILE']&.split(workspace.windows? ? ';' : ':') if !target || target.empty?
606
+ target = ENV['COMPOSE_FILE']&.split(workspace.windows? ? ';' : ':') unless target && !target.empty?
608
607
  Array(target || dockerfile).each do |val|
609
- doc = YAML.load_file(path + val)
608
+ doc = YAML.load_file(basepath(val))
610
609
  if keys.empty?
611
610
  yield doc
612
611
  elsif (data = doc.dig(*keys))
@@ -648,17 +647,17 @@ module Squared
648
647
  end
649
648
 
650
649
  def append_file(type, target: @session)
651
- return if ENV['COMPOSE_FILE'] && compose?(type)
650
+ return if !@file || (ENV['COMPOSE_FILE'] && compose?(type))
652
651
 
653
652
  unless @file.is_a?(Array)
654
653
  case type
655
654
  when 2, 4
656
655
  return
657
656
  when 3
658
- return unless COMPOSEFILE.map { |val| path + val }.select(&:exist?).size > 1
657
+ return unless COMPOSEFILE.map { |val| basepath(val) }.select(&:exist?).size > 1
659
658
  end
660
659
  end
661
- files = Array(@file).map { |val| quote_option('file', path + val) }
660
+ files = Array(@file).map { |val| quote_option('file', basepath(val)) }
662
661
  if target.is_a?(Set)
663
662
  opts = target.to_a.insert(2, *files)
664
663
  target.clear.merge(opts)
@@ -839,7 +838,7 @@ module Squared
839
838
  end
840
839
 
841
840
  def contextdir(val = nil)
842
- val && projectpath?(val) ? shell_quote(path + val) : '.'
841
+ val && projectpath?(val) ? shell_quote(basepath(val)) : '.'
843
842
  end
844
843
 
845
844
  def tagjoin(*args, char: '/')