squared 0.4.8 → 0.4.9

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: 483002a469a23461dcee07ded3610011d831f2c737142cd4b464899fbdf70cde
4
- data.tar.gz: 4601b03b61f6270e8b3841777effd420b47c752ddbe96924ca329ee92c98ee4c
3
+ metadata.gz: 81e1fa9c773a59c8cb351dec47eb27b4c858c6266c83bd14be02c621cf68ad57
4
+ data.tar.gz: 23ccad44a3f5fbc1ade8d5950692fd401566f862b0131debebdd9d5d1a4d6dab
5
5
  SHA512:
6
- metadata.gz: 5767519e7f0150a753c0cbf97aa59292ad59a29b4f78c6e7596e5bd369b035258339d062b896c59d37496ccdcd4224179a745065f1dc41a35f876a507f30e171
7
- data.tar.gz: c457cbd60b4865aea1e218ce9609c4094f618cc4b404eac309c8235b3bc116599487d1c641151cd99bceab6d28a03b48abd1774e447017afb2d28439aca40298
6
+ metadata.gz: '00945ddcf48ae0482bdb40f143117ae464a03491fadf6c33b2e34c9f50b4d628c4b72b43c1a388e2c8c175067f62970c7ac60721330c1340a48103c4b972b560'
7
+ data.tar.gz: d3846c85547ee3acb6d040703d21b7a61630f502c17da71f8d0ddf9032c67930819b933b3c3896a0e2b23c2664bfc2ed5454d95313849a9885c429d0cfacb5f1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,76 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.9] - 2025-04-27
4
+
5
+ ### Added
6
+
7
+ - Git command reset action commit is interactive.
8
+ - Git command commit action all is interactive.
9
+ - Git command log and diff commit based actions are interactive.
10
+ - Git command branch action move and copy are interactive.
11
+ - Git command rebase and merge are interactive.
12
+ - Git command checkout action detach is interactive.
13
+ - Git command branch action delete for remotes is interactive.
14
+ - Git command restore action source was created.
15
+ - Git command tag actions can choose a remote to push.
16
+ - Git command switch was implemented.
17
+ - Git command branch action create is interactive.
18
+ - Git command reset action mode and patch are interactive.
19
+ - Git command restore action staged and worktree are interactive.
20
+ - Git command log and checkout commit based actions are interactive.
21
+ - Ruby command ruby action script is interactive.
22
+ - Ruby command irb is interactive.
23
+ - Git command commit action fixup was implemented.
24
+ - Git command commit action all can accept add command options.
25
+ - Git command branch action create and track can upload tracking.
26
+ - Git command add was implemented.
27
+ - Python command venv action run is interactive.
28
+
29
+ ### Changed
30
+
31
+ - Ruby depend with bundler excludes development group in production.
32
+ - OptionPartition class first and pass parameters were combined.
33
+ - Git command stash action list can accept log options.
34
+ - Git command branch action set was renamed track.
35
+ - Ruby autodetect can specify version manager for local project.
36
+ - Git pattern matching for HEAD was revised.
37
+
38
+ ### Removed
39
+
40
+ - Git command branch action edit is not commonly used.
41
+ - Git command rev action branch only echoed valid branches.
42
+ - Git command rev action parseopt is not relevant to a workspace.
43
+
44
+ ## [0.3.10] - 2025-04-27
45
+
46
+ ### Fixed
47
+
48
+ - Git command reset action commit used invalid delimeter.
49
+ - Git single option values were not merged as per specification.
50
+ - Project script task did not fire first and last callbacks.
51
+ - Git checkout action commit did not include options.
52
+
53
+ ### Removed
54
+
55
+ - Git command files action ignored could not be used alone.
56
+
57
+ ## [0.2.10] - 2025-04-27
58
+
59
+ ### Fixed
60
+
61
+ - Project run and script tasks did not fire first and last callbacks.
62
+ - Git command clone did not read booleans for recurse-submodules.
63
+
64
+ ## [0.1.7] - 2025-04-27
65
+
66
+ ### Fixed
67
+
68
+ - Project directory context method option pass was inverted.
69
+ - Shell options with spaces and without quotes were not escaped.
70
+ - Git task status did not display branch information.
71
+ - Ruby copy method argument include was ignored when used directly.
72
+ - Git commit could not push branch without same name as remote.
73
+
3
74
  ## [0.4.8] - 2025-04-21
4
75
 
5
76
  ### Added
@@ -483,7 +554,7 @@
483
554
  - Node tasks without any action are not displayed.
484
555
  - Git fetch commands that do not apply to pull are rejected.
485
556
 
486
- ## [0.1.3] - 2024-01-02
557
+ ## [0.1.3] - 2025-01-02
487
558
 
488
559
  ### Fixed
489
560
 
@@ -562,6 +633,7 @@
562
633
 
563
634
  - Changelog was created.
564
635
 
636
+ [0.4.9]: https://github.com/anpham6/squared/releases/tag/v0.4.9-ruby
565
637
  [0.4.8]: https://github.com/anpham6/squared/releases/tag/v0.4.8-ruby
566
638
  [0.4.7]: https://github.com/anpham6/squared/releases/tag/v0.4.7-ruby
567
639
  [0.4.6]: https://github.com/anpham6/squared/releases/tag/v0.4.6-ruby
@@ -571,6 +643,7 @@
571
643
  [0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
572
644
  [0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
573
645
  [0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
646
+ [0.3.10]: https://github.com/anpham6/squared/releases/tag/v0.3.10-ruby
574
647
  [0.3.9]: https://github.com/anpham6/squared/releases/tag/v0.3.9-ruby
575
648
  [0.3.8]: https://github.com/anpham6/squared/releases/tag/v0.3.8-ruby
576
649
  [0.3.7]: https://github.com/anpham6/squared/releases/tag/v0.3.7-ruby
@@ -581,6 +654,7 @@
581
654
  [0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
582
655
  [0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
583
656
  [0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
657
+ [0.2.10]: https://github.com/anpham6/squared/releases/tag/v0.2.10-ruby
584
658
  [0.2.9]: https://github.com/anpham6/squared/releases/tag/v0.2.9-ruby
585
659
  [0.2.8]: https://github.com/anpham6/squared/releases/tag/v0.2.8-ruby
586
660
  [0.2.7]: https://github.com/anpham6/squared/releases/tag/v0.2.7-ruby
@@ -591,6 +665,7 @@
591
665
  [0.2.2]: https://github.com/anpham6/squared/releases/tag/v0.2.2-ruby
592
666
  [0.2.1]: https://github.com/anpham6/squared/releases/tag/v0.2.1-ruby
593
667
  [0.2.0]: https://github.com/anpham6/squared/releases/tag/v0.2.0-ruby
668
+ [0.1.7]: https://github.com/anpham6/squared/releases/tag/v0.1.7-ruby
594
669
  [0.1.6]: https://github.com/anpham6/squared/releases/tag/v0.1.6-ruby
595
670
  [0.1.5]: https://github.com/anpham6/squared/releases/tag/v0.1.5-ruby
596
671
  [0.1.4]: https://github.com/anpham6/squared/releases/tag/v0.1.4-ruby
data/README.ruby.md CHANGED
@@ -83,7 +83,7 @@ Workspace::Application
83
83
  "CFLAGS" => "-fPIC -O1"
84
84
  })
85
85
  .add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
86
- .add("logger", copy: { from: "lib", glob: "**/*.rb", into: "~/.rvm/gems/ruby-3.4.0/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
86
+ .add("logger", copy: { from: "lib", glob: "**/*.rb", into: "~/.rvm/gems/ruby-3.4.0/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true | "rvm" | "rbenv" | "asdf" | "bundler"
87
87
  .add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
88
88
  .add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
89
89
  .add("squared", script: ["build:stage1", "build:stage2"], group: "app") do # Copy target (main)
@@ -282,6 +282,10 @@ Workspace::Application
282
282
  p "1"
283
283
  end
284
284
  # OR
285
+ run(on: { first: -> { p "pass" }, last: -> { p "pass" } }) do
286
+ p "1"
287
+ end
288
+ # OR
285
289
  run(["gem build", "--force", { "RUBY_VERSION" => "3.4.0" }]) # RUBY_VERSION="3.4.0" gem build --force
286
290
  # OR
287
291
  run({ #
@@ -433,20 +437,21 @@ Most project classes will inherit from `Git` which enables these tasks:
433
437
  | :--------- | :--------------- | :-------------------------------------------- |
434
438
  | branch | branch | create set delete move copy list edit current |
435
439
  | checkout | checkout | commit branch track detach path |
436
- | commit | commit | add all amend amend-orig |
440
+ | commit | commit | add all amend amend-orig fixup |
437
441
  | diff | diff | head cached branch files between contain |
438
442
  | fetch | fetch | origin remote |
439
- | files | ls-files | cached modified deleted others ignored |
440
- | git | | clean mv rm |
443
+ | files | ls-files | cached modified deleted others |
444
+ | git | | add clean mv rm revert |
441
445
  | merge | merge | commit no-commit send |
442
446
  | pull | pull | origin remote |
443
447
  | rebase | rebase | branch onto send |
444
448
  | refs | ls-remote --refs | heads tags remote |
445
449
  | reset | reset | commit index patch mode |
446
450
  | restore | restore | staged worktree |
447
- | rev | rev | commit branch output parseopt |
451
+ | rev | rev | commit output |
448
452
  | show | show | format oneline |
449
453
  | stash | stash | push pop apply drop list |
454
+ | switch | switch | create detach merge |
450
455
  | tag | tag | add sign delete list |
451
456
 
452
457
  You can disable all of them at once using the `exclude` property.
@@ -470,11 +475,12 @@ Workspace::Application
470
475
 
471
476
  ### Commit Hash
472
477
 
473
- Commands which use commit hashes are parsed using string interpolation format as to not be confused for an option.
478
+ Commands which use commit hashes are parsed using a ":" prefix as to not be confused for an option.
474
479
 
475
480
  ```sh
476
- rake squared:log:view[#{af012345}] # git log af012345
477
- rake squared:log:view[H1,H5,all,lib,./H12345] # git log --all HEAD~1 HEAD~5 -- 'lib' 'H12345'
481
+ rake squared:log:view[:af012345] # git log af012345
482
+ rake squared:log:view[#{af012345}] # deprecated
483
+ rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- 'lib' 'H12345'
478
484
  ```
479
485
 
480
486
  ## Environment
@@ -566,39 +572,46 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
566
572
 
567
573
  | Command | Flag | ENV |
568
574
  | :--------- | :---------------- | :-------------------------------------------------------------------- |
575
+ | branch | create | TRACK=0,1,s FORCE |
576
+ | branch | move copy | FORCE |
577
+ | branch | set delete | COUNT=n |
578
+ | branch | global | SYNC |
579
+ | checkout | branch | DETACH TRACK=s COUNT=n |
580
+ | checkout | detach | REFLOG=1 |
581
+ | checkout | track | COUNT=n |
582
+ | checkout | global path | HEAD=s PATHSPEC=s |
583
+ | checkout | * | FORCE MERGE |
584
+ | clone | * | DEPTH=n ORIGIN=s BRANCH=s LOCAL=0,1 |
585
+ | commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
586
+ | diff | -between -contain | MERGE_BASE |
587
+ | diff | head branch | INDEX=n |
588
+ | diff | * | PATHSPEC=s |
589
+ | fetch | -remote | ALL |
590
+ | fetch | remote | REFSPEC=s |
591
+ | fetch | * | FORCE RECURSE_SUBMODULES=0,1,s |
592
+ | git | rm | PATHSPEC=s |
593
+ | log | * | PATHSPEC=s |
569
594
  | pull | rebase | AUTOSTASH |
570
595
  | pull | remote | REFSPEC=s |
571
596
  | pull | * | REBASE=0,1 FORCE RECURSE_SUBMODULES=0,1,s |
572
597
  | rebase | branch | HEAD=s |
573
598
  | rebase | onto | INTERACTIVE I HEAD=s |
574
- | fetch | -remote | ALL |
575
- | fetch | remote | REFSPEC=s |
576
- | fetch | * | FORCE RECURSE_SUBMODULES=0,1,s |
577
- | clone | * | DEPTH=n ORIGIN=s BRANCH=s LOCAL=0,1 |
578
- | stash | push | PATHSPEC=s |
579
- | stash | global | ALL=0,1 KEEP_INDEX=0,1 INCLUDE_UNTRACKED=0,1 STAGED=0,1 MESSAGE=s M=s |
580
- | status | global | LONG IGNORE_SUBMODULES=s,0-3 PATHSPEC=s |
581
- | revbuild | global | UNTRACKED_FILES=s IGNORE_SUBMODULES=s IGNORED=s (status) |
582
599
  | reset | mode (mixed) | N REFRESH=0 |
583
600
  | reset | index | PATHSPEC=s |
601
+ | reset | commit | COUNT=n REFLOG=1 |
584
602
  | reset | -commit | HEAD=s |
585
- | checkout | branch | DETACH TRACK=s |
586
- | checkout | global path | HEAD=s PATHSPEC=s |
587
- | checkout | * | FORCE MERGE |
588
- | tag | add | SIGN FORCE HEAD=s |
589
- | tag | sign | FORCE HEAD=s |
590
- | log | * | PATHSPEC=s |
591
- | diff | -between -contain | MERGE_BASE |
592
- | diff | head branch | INDEX=n |
593
- | diff | * | PATHSPEC=s |
594
- | commit | * | MESSAGE=s M=s REPOSITORY=s DRY_RUN EDIT=0 |
595
- | branch | create | TRACK=0,1,s FORCE |
596
- | branch | move copy | FORCE |
597
- | branch | global | SYNC |
598
603
  | restore | * | PATHSPEC=s |
599
- | show | -online | ABBREV=n |
604
+ | revbuild | global | UNTRACKED_FILES=s IGNORE_SUBMODULES=s IGNORED=s (status) |
605
+ | stash | push | PATHSPEC=s |
606
+ | stash | global | ALL=0,1 KEEP_INDEX=0,1 INCLUDE_UNTRACKED=0,1 STAGED=0,1 M|MESSAGE=s |
607
+ | status | global | BRANCH LONG IGNORE_SUBMODULES=s,0-3 PATHSPEC=s |
608
+ | switch | detach | REFLOG=1 |
609
+ | switch | -detach | HEAD=s |
610
+ | switch | * | FORCE |
611
+ | tag | add | SIGN FORCE HEAD=s M|MESSAGE=s |
612
+ | tag | sign | FORCE HEAD=s M|MESSAGE=s |
613
+ | tag | delete | COUNT=n |
600
614
  | rev | commit branch | HEAD=s |
601
- | git | rm | PATHSPEC=s |
602
615
 
603
616
  ### Docker
604
617
 
@@ -61,7 +61,7 @@ module Squared
61
61
  end
62
62
  wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
63
63
  code = []
64
- args.concat(as_a(styles)).each_with_index do |type, i|
64
+ args.concat(as_a(styles)).flatten.each_with_index do |type, i|
65
65
  next unless type
66
66
 
67
67
  if index == -1
@@ -146,19 +146,12 @@ module Squared
146
146
  def log_sym(level)
147
147
  if level.is_a?(::Numeric)
148
148
  case level
149
- when Logger::DEBUG
150
- :debug
151
- when Logger::INFO
152
- :info
153
- when Logger::WARN
154
- :warn
155
- when Logger::ERROR
156
- :error
157
- when Logger::FATAL
158
- :fatal
159
- else
160
- :unknown
161
- end
149
+ when Logger::DEBUG then :debug
150
+ when Logger::INFO then :info
151
+ when Logger::WARN then :warn
152
+ when Logger::ERROR then :error
153
+ when Logger::FATAL then :fatal
154
+ else :unknown end
162
155
  else
163
156
  level.to_s.downcase.to_sym
164
157
  end
@@ -185,7 +178,7 @@ module Squared
185
178
  end
186
179
  if args.size > 1 && !hint
187
180
  title = log_title(level, color: false)
188
- sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
181
+ sub = { pat: /\A(#{Regexp.escape(title)})(.*)\z/m, styles: __get__(:theme)[:logger][log_sym(level)] } if color
189
182
  emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
190
183
  else
191
184
  msg = [log_title(level, color: color)]
@@ -246,7 +239,7 @@ module Squared
246
239
  ret = sub_style(ret, styles: border) if border
247
240
  ret
248
241
  end
249
- sub = as_a(sub)
242
+ sub = as_a sub
250
243
  pr = lambda do |line|
251
244
  s = line.ljust(n)
252
245
  sub.each { |h| s = sub_style(s, **h) }
@@ -296,7 +289,7 @@ module Squared
296
289
  end
297
290
 
298
291
  def stripext(val)
299
- File.basename(val, File.extname(val))
292
+ File.basename(val, '.*')
300
293
  end
301
294
 
302
295
  def raise_error(*args, hint: nil, kind: ArgumentError)
@@ -5,14 +5,14 @@ module Squared
5
5
  module Prompt
6
6
  module_function
7
7
 
8
- def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
8
+ def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 30)
9
9
  require 'readline'
10
10
  require 'timeout'
11
11
  agree = /^#{agree}$/i if agree.is_a?(::String)
12
12
  cancel = /^#{cancel}$/i if cancel.is_a?(::String)
13
13
  Timeout.timeout(timeout) do
14
14
  begin
15
- while (ch = Readline.readline(msg, true))
15
+ while (ch = Readline.readline(msg))
16
16
  ch = ch.chomp
17
17
  case (ch.empty? ? default : ch)
18
18
  when agree
@@ -32,7 +32,7 @@ module Squared
32
32
  end
33
33
  end
34
34
 
35
- def choice(msg, list = nil, min: 1, max: 1, multiple: false, attempts: 5, timeout: 60)
35
+ def choice(msg, list = nil, min: 1, max: 1, multiple: false, auto: true, force: true, attempts: 5, timeout: 60)
36
36
  require 'readline'
37
37
  require 'timeout'
38
38
  if list
@@ -42,24 +42,36 @@ module Squared
42
42
  items << val.chomp
43
43
  end
44
44
  max = items.size
45
- msg = "#{msg}: [1-#{max}#{multiple ? '|,' : ''}] "
45
+ if auto
46
+ msg = "#{msg}: [1-#{max}#{if multiple
47
+ "|,#{multiple.is_a?(Numeric) ? "{#{multiple}}" : ''}"
48
+ end}] "
49
+ end
46
50
  end
47
51
  return unless max >= min
48
52
 
49
53
  valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max) }
50
54
  Timeout.timeout(timeout) do
51
55
  begin
52
- while (ch = Readline.readline(msg, true))
53
- ch = ch.strip
54
- if multiple
55
- a = ch.split(/\s*,\s*/)
56
- b = a.select { |s| valid.call(s) }.map!(&:to_i)
57
- return items ? b.map! { |i| items[i - 1] } : b if a.size == b.size
58
- elsif valid.call(ch)
59
- return items ? items[ch.to_i - 1] : ch.to_i
56
+ while (ch = Readline.readline(msg))
57
+ unless (ch = ch.strip).empty?
58
+ if multiple
59
+ a = ch.split(/\s*,\s*/)
60
+ b = a.select { |s| valid.call(s) }.map!(&:to_i).sort
61
+ next unless a.size == b.size
62
+ return b unless items
63
+ next if multiple.is_a?(::Numeric) && multiple != b.size
64
+
65
+ return b.map! { |i| items[i - 1] }
66
+ elsif valid.call(ch)
67
+ return items ? items[ch.to_i - 1] : ch.to_i
68
+ end
60
69
  end
61
70
  attempts -= 1
62
- exit 1 unless attempts > 0
71
+ next if attempts > 0
72
+ break unless force
73
+
74
+ exit 1
63
75
  end
64
76
  rescue Interrupt
65
77
  puts
@@ -69,6 +81,19 @@ module Squared
69
81
  end
70
82
  end
71
83
  end
84
+
85
+ def readline(msg, history = false, force: nil)
86
+ require 'readline'
87
+ case force
88
+ when ::TrueClass, ::FalseClass
89
+ msg = "#{msg} (#{force ? 'required' : 'optional'}): "
90
+ ret = Readline.readline(msg, history)&.strip || ''
91
+ raise_error 'user cancelled' if force && ret.empty?
92
+ ret
93
+ else
94
+ Readline.readline(msg, history)
95
+ end
96
+ end
72
97
  end
73
98
  end
74
99
  end
@@ -8,12 +8,12 @@ module Squared
8
8
  module Shell
9
9
  module_function
10
10
 
11
- def shell_escape(val, quote: false, force: false, double: false, override: false)
11
+ def shell_escape(val, quote: false, force: false, double: false, option: false, override: false)
12
12
  if (r = /\A(--?)([^= ]+)((=|\s+)(["'])?(.+?)(["'])?)?\z/m.match(val = val.to_s))
13
- return val if !r[3] || (!r[5] && r[6].match?(/\s/))
13
+ return val if !r[3] || (!r[5] && !r[6].match?(/\s/))
14
14
 
15
15
  combine = lambda do |opt|
16
- if r[2] =~ /\A(["'])(.+)\1\z/
16
+ if r[2] =~ /\A(["'])(.+)\1\z/m
17
17
  double = $1 == '"'
18
18
  r[2] = $2
19
19
  override = true
@@ -26,19 +26,28 @@ module Squared
26
26
  force = true
27
27
  combine.call(r[5] + r[6] + r[7])
28
28
  end
29
- elsif val.empty?
30
- ''
29
+ elsif option && val =~ /\A([^=]+)=(.+)\z/m
30
+ return val if $2.match?(/\A(["']).+\1\z/m)
31
+
32
+ "#{$1}=%s" % if $2.include?(' ')
33
+ shell_quote($2, option: false)
34
+ else
35
+ Rake::Win32.windows? ? $2 : Shellwords.escape($2)
36
+ end
31
37
  elsif Rake::Win32.windows?
32
38
  quote ? shell_quote(val, double: double, force: force) : val
33
39
  else
34
- Shellwords.escape(val)
40
+ val.empty? ? '' : Shellwords.escape(val)
35
41
  end
36
42
  end
37
43
 
38
44
  def shell_quote(val, option: true, force: true, double: false, override: false)
39
45
  val = val.to_s
40
- return val if val.empty? || (!force && !val.include?(' '))
41
- return val if option && val.match?(/(?:\A|\S=|[^=]\s+|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/m)
46
+ return val if (!force && !val.include?(' ')) || val.empty?
47
+
48
+ if option && val.match?(/(?:\A|\A[^=\s]+(?:=|\s+)|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/m)
49
+ return val
50
+ end
42
51
 
43
52
  if double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
44
53
  "\"#{val.gsub(/(?<!\\)"/, '\\"')}\""
@@ -76,18 +85,16 @@ module Squared
76
85
  end}"
77
86
  end
78
87
 
79
- def shell_split(val, escape: true, quote: false, join: nil)
80
- ret = Shellwords.split(val)
81
- return ret if join == false
82
-
83
- ret.map! { |opt| shell_escape(opt, quote: quote) } if escape
88
+ def shell_split(val, quote: false, force: false, join: nil)
89
+ ret = val.shellsplit
90
+ ret.map! { |opt| shell_escape(opt, quote: quote, force: force, double: true, option: true) }
84
91
  return ret unless join
85
92
 
86
93
  ret.join(join.is_a?(::String) ? join : ' ')
87
94
  end
88
95
 
89
96
  def fill_option(val, double: false)
90
- return "-#{val}" if val.match?(/^[a-z]\d*$/i)
97
+ return "-#{val}" if val.match?(/\A(?:[a-z]\d*|\d)\z/i)
91
98
 
92
99
  shell_escape(val.start_with?('-') ? val : "--#{val}", double: double)
93
100
  end
@@ -30,10 +30,10 @@ module Squared
30
30
  if pass
31
31
  exclude = []
32
32
  pass = [pass] unless pass.is_a?(::Array)
33
- pass.each { |val| exclude.concat(Dir.glob(src.join(val))) }
33
+ pass.each { |val| exclude.concat(Dir.glob(src + val)) }
34
34
  end
35
35
  (glob.is_a?(::Array) ? glob : [glob]).each do |val|
36
- Dir.glob(src.join(val)) do |path|
36
+ Dir.glob(src + val) do |path|
37
37
  next if exclude&.include?(path) || (path = Pathname.new(path)).directory?
38
38
 
39
39
  dir = dest.join(path.relative_path_from(src)).dirname
@@ -159,7 +159,7 @@ module Squared
159
159
  end
160
160
  begin
161
161
  if default.is_a?(::String)
162
- default = (root ? Pathname.new(root).join(default) : Pathname.new(default)).realdirpath
162
+ default = (root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
163
163
  end
164
164
  rescue StandardError => e
165
165
  warn e
@@ -14,7 +14,7 @@ module Squared
14
14
  class << self
15
15
  def parse(gem, namespace, ext = [pkg])
16
16
  require gem
17
- obj = eval(namespace)
17
+ obj = eval namespace
18
18
  ext = [ext] unless ext.is_a?(Array)
19
19
  ext.each { |val| @@mime_obj[val] = [obj, ext] }
20
20
  rescue LoadError, NameError => e
@@ -127,7 +127,7 @@ module Squared
127
127
  if enabled?
128
128
  if namespace
129
129
  require(gem || type)
130
- obj = eval(namespace)
130
+ obj = eval namespace
131
131
  else
132
132
  as_a(ext).each do |val|
133
133
  next unless (data = @@mime_obj[val])
@@ -163,7 +163,7 @@ module Squared
163
163
  def also(path, type = nil, name: nil, **kwargs)
164
164
  return self if @mime.frozen? || !(file = basepath(path)).exist?
165
165
 
166
- ext = mimetype(file)
166
+ ext = mimetype file
167
167
  type ||= ext
168
168
  name ||= file.basename.to_s.chomp(File.extname(file))
169
169
  add(type, ext: ext, command: name, file: file, **kwargs)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.8'
4
+ VERSION = '0.4.9'
5
5
  end
@@ -83,7 +83,7 @@ module Squared
83
83
  basename = @home.basename.to_s
84
84
  if main
85
85
  @main = main.to_s.freeze
86
- @home = @home.join(@main) unless @main == basename || (windows? && @main.downcase == basename.downcase)
86
+ @home += @main unless @main == basename || (windows? && @main.downcase == basename.downcase)
87
87
  else
88
88
  @main = basename.freeze
89
89
  end
@@ -96,7 +96,7 @@ module Squared
96
96
  @extensions = []
97
97
  @envname = @main.gsub(/[^\w]+/, '_').upcase.freeze
98
98
  @pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
99
- @exception = env_bool(exception)
99
+ @exception = env_bool exception
100
100
  @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
101
101
  @warning = @verbose != false
102
102
  @closed = false
@@ -274,7 +274,7 @@ module Squared
274
274
  data = {} if !command && data[:order].empty?
275
275
  if group
276
276
  label = :group
277
- items = as_a(group)
277
+ items = as_a group
278
278
  else
279
279
  label = :ref
280
280
  items = ref ? as_a(ref) : [:_]
@@ -299,9 +299,9 @@ module Squared
299
299
  kwargs = kwargs.dup unless @withargs
300
300
  kwargs[:group] = @group
301
301
  end
302
- path = rootpath(path)
302
+ path = root + path
303
303
  project = (project || path.basename).to_s
304
- name = task_name(project)
304
+ name = task_name project
305
305
  index = 0
306
306
  while @project[name]
307
307
  index += 1
@@ -499,7 +499,7 @@ module Squared
499
499
  end
500
500
 
501
501
  def task_sync(key)
502
- key = task_name(key)
502
+ key = task_name key
503
503
  task_defined?(ret = task_join(key, 'sync')) ? ret : key
504
504
  end
505
505
 
@@ -561,7 +561,7 @@ module Squared
561
561
  end
562
562
 
563
563
  def task_include?(obj, key, ref = nil)
564
- return false if @series.exclude.include?(key)
564
+ return false if @series.exclude?(key)
565
565
 
566
566
  task_base?(key) ? obj.has?(key, ref || baseref) : task_extend?(obj, key)
567
567
  end
@@ -598,7 +598,7 @@ module Squared
598
598
  end
599
599
 
600
600
  def docker?
601
- File.exist?('/.dockerenv')
601
+ !Dir['/.dockerenv', '/docker-*.{sh,d}'].empty?
602
602
  end
603
603
 
604
604
  def powershell?
@@ -608,7 +608,7 @@ module Squared
608
608
  when 'powershell.exe', 'vscode'
609
609
  true
610
610
  else
611
- ENV.fetch('PSModulePath', '').split(';').size > 1
611
+ ENV.fetch('PSModulePath', '').split(';', 2).size > 1
612
612
  end
613
613
  end
614
614
 
@@ -686,12 +686,8 @@ module Squared
686
686
  end
687
687
 
688
688
  def data_get(*args, group: nil, ref: nil, target: nil)
689
- if group
690
- target[:group][group.to_sym]
691
- elsif ref.is_a?(Array)
692
- ref = ref.each
693
- end
694
- if ref.instance_of?(Enumerator)
689
+ target[:group][group.to_sym] if group
690
+ if ref.is_a?(Enumerable)
695
691
  ref.each do |key|
696
692
  next unless (ret = target[:ref][key])
697
693