squared 0.5.0 → 0.5.1

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: 46ea608e0b2d67acb3d15eaf67d7c70fc4c301c1c7ebf0dbfa9fba2e9ccabe0b
4
- data.tar.gz: 806aeee453718e1ff75f1f83c3f2ac763fd989cdddeca18b570a1d383c90484c
3
+ metadata.gz: 3aeb7a32f99a22618e2c6c497d6de2f911df5d126232c63ed986324fc5b31aa7
4
+ data.tar.gz: fb144ac3238fcaf22f1c8bf4218847f547db9d03904a45ef8f040501df1ecc9b
5
5
  SHA512:
6
- metadata.gz: bcde780730f2426af5561183d7d33d172f7dc7a096f9b21b3098593e18758a6a5bdb26e40ccabfaf7e0cf2e6963f067289c304e2e7626b85c15dd2c589e907e0
7
- data.tar.gz: efcae50c9cfd39b72c013035df135533fee434e7985c3896d409a3d2d1850f16c2c7d2dd811e89431ddc46e2fbc64f752ece5bc8f1205d79d052bcec59fb7749
6
+ metadata.gz: 6c026101681bf8869138b6882044b60dd3b515d2f61feee9529c4ed70f048c1ceca39538ebe4ac3985c974aeff36b22506d4f5429f9b6eb7ac7d5400a14e737b
7
+ data.tar.gz: c53bc01a5dbdb5653d67eab02b3bd93229b8cda4fef6d97da16826d70069ab03c085086c49a045281e2da732957a1e920595abd52374bbf76c898f7e63dfe39b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,77 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.1] - 2025-07-05
4
+
5
+ ### Changed
6
+
7
+ - Common method confirm will automatically append hint with defaults.
8
+
9
+ ### Fixed
10
+
11
+ - Gem command push did not prompt for gem to publish.
12
+
13
+ ## [0.4.14] - 2025-07-05
14
+
15
+ ### Added
16
+
17
+ - Python command run for project scripts was implemented.
18
+ - Python command build and publish with PDM was implemented.
19
+ - Python command run detects program tool scripts.
20
+ - Git command stash action branch was implemented.
21
+ - Docker command compose action exec and run are interactive.
22
+ - Double dash can be used to end parsing for options.
23
+ - Python command outdated tasks with semver was implemented.
24
+
25
+ ### Changed
26
+
27
+ - Ruby command rake supports running multiple indexes.
28
+ - Ruby private method rakefile when nil returns empty string.
29
+ - Ruby private method gempwd and rakepwd ignores current directory.
30
+ - Ruby command gem action update parameters are optional.
31
+ - Gem command install and uninstall can parse name and version.
32
+ - Kernel method Array is used in place of common method as_a.
33
+ - Ruby public method irb parameter load was renamed args.
34
+
35
+ ### Fixed
36
+
37
+ - Box border did not print corners on Windows.
38
+ - Index character was not captured on Windows.
39
+ - Node command publish did not prompt for package to publish.
40
+ - Python command publish did not prompt for package to publish.
41
+ - Project confirmation accept dialog did not always quit.
42
+ - Git command add did not detect when no files were changed.
43
+
44
+ ## [0.3.12] - 2025-07-05
45
+
46
+ ### Fixed
47
+
48
+ - Gem command exec did not include gem option flag.
49
+ - Project graph did not print first level border.
50
+ - Node command update did not use correct event name.
51
+ - Gem command push did not validate gem file to publish.
52
+ - Node command publish did not publish when silent.
53
+
54
+ ## [0.2.12] - 2025-07-05
55
+
56
+ ### Fixed
57
+
58
+ - See `0.1.9`.
59
+
60
+ ## [0.1.9] - 2025-07-05
61
+
62
+ ### Added
63
+
64
+ - Initial support for using JRuby.
65
+ - Config viewer theme color for boolean was implemented.
66
+
67
+ ### Fixed
68
+
69
+ - Project output divider was not printed when not verbose.
70
+ - Directory context was not threaded using JRuby.
71
+ - Index character was not captured on Windows.
72
+ - Common method is used for Kernel shell commands.
73
+ - Git did not highlight output for single commands.
74
+
3
75
  ## [0.5.0] - 2025-06-16
4
76
 
5
77
  ### Added
@@ -78,6 +150,8 @@
78
150
 
79
151
  ## [0.3.11] - 2025-05-15
80
152
 
153
+ ### Fixed
154
+
81
155
  - See `0.2.11`.
82
156
 
83
157
  ## [0.2.11] - 2025-05-15
@@ -340,6 +414,8 @@
340
414
 
341
415
  ## [0.3.7] - 2025-04-08
342
416
 
417
+ ### Fixed
418
+
343
419
  - See `0.2.7`.
344
420
 
345
421
  ## [0.2.7] - 2025-04-08
@@ -761,7 +837,9 @@
761
837
 
762
838
  - Changelog was created.
763
839
 
840
+ [0.5.1]: https://github.com/anpham6/squared/releases/tag/v0.5.1-ruby
764
841
  [0.5.0]: https://github.com/anpham6/squared/releases/tag/v0.5.0-ruby
842
+ [0.4.14]: https://github.com/anpham6/squared/releases/tag/v0.4.14-ruby
765
843
  [0.4.13]: https://github.com/anpham6/squared/releases/tag/v0.4.13-ruby
766
844
  [0.4.12]: https://github.com/anpham6/squared/releases/tag/v0.4.12-ruby
767
845
  [0.4.11]: https://github.com/anpham6/squared/releases/tag/v0.4.11-ruby
@@ -776,6 +854,7 @@
776
854
  [0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
777
855
  [0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
778
856
  [0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
857
+ [0.3.12]: https://github.com/anpham6/squared/releases/tag/v0.3.12-ruby
779
858
  [0.3.11]: https://github.com/anpham6/squared/releases/tag/v0.3.11-ruby
780
859
  [0.3.10]: https://github.com/anpham6/squared/releases/tag/v0.3.10-ruby
781
860
  [0.3.9]: https://github.com/anpham6/squared/releases/tag/v0.3.9-ruby
@@ -788,6 +867,7 @@
788
867
  [0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
789
868
  [0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
790
869
  [0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
870
+ [0.2.12]: https://github.com/anpham6/squared/releases/tag/v0.2.12-ruby
791
871
  [0.2.11]: https://github.com/anpham6/squared/releases/tag/v0.2.11-ruby
792
872
  [0.2.10]: https://github.com/anpham6/squared/releases/tag/v0.2.10-ruby
793
873
  [0.2.9]: https://github.com/anpham6/squared/releases/tag/v0.2.9-ruby
@@ -800,6 +880,7 @@
800
880
  [0.2.2]: https://github.com/anpham6/squared/releases/tag/v0.2.2-ruby
801
881
  [0.2.1]: https://github.com/anpham6/squared/releases/tag/v0.2.1-ruby
802
882
  [0.2.0]: https://github.com/anpham6/squared/releases/tag/v0.2.0-ruby
883
+ [0.1.9]: https://github.com/anpham6/squared/releases/tag/v0.1.9-ruby
803
884
  [0.1.8]: https://github.com/anpham6/squared/releases/tag/v0.1.8-ruby
804
885
  [0.1.7]: https://github.com/anpham6/squared/releases/tag/v0.1.7-ruby
805
886
  [0.1.6]: https://github.com/anpham6/squared/releases/tag/v0.1.6-ruby
data/README.ruby.md CHANGED
@@ -509,7 +509,7 @@ Most project classes will inherit from `Git` which enables these tasks:
509
509
  | restore | restore | staged worktree |
510
510
  | rev | rev | commit output |
511
511
  | show | show | format oneline |
512
- | stash | stash | push pop apply drop list |
512
+ | stash | stash | push pop apply branch drop clear list |
513
513
  | switch | switch | create detach merge |
514
514
  | tag | tag | add sign delete list |
515
515
 
@@ -63,6 +63,7 @@ module Squared
63
63
  hash: %i[green black!],
64
64
  array: %i[blue black!],
65
65
  number: [:magenta],
66
+ boolean: [:magenta],
66
67
  undefined: %i[red italic]
67
68
  },
68
69
  logger: {
@@ -103,13 +104,15 @@ module Squared
103
104
  return [] if obj.nil?
104
105
 
105
106
  unless obj.is_a?(::Array)
106
- obj = if obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
107
+ obj = if obj.respond_to?(:to_ary)
108
+ obj.to_ary
109
+ elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
107
110
  val
108
111
  else
109
112
  [obj]
110
113
  end
111
114
  end
112
- obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
115
+ obj = flat.is_a?(::Numeric) ? obj.flatten(flat) : obj.flatten if flat
113
116
  obj = obj.compact if compact
114
117
  obj = obj.map(&meth.shift) until meth.empty?
115
118
  return obj unless block_given?
@@ -29,7 +29,13 @@ module Squared
29
29
  bright_white!: '107'
30
30
  }.freeze
31
31
  BOX_GRAPH = ['│', '─', '├', '└', '┬'].freeze
32
- BOX_BORDER = ['│', '─', '', '', '', '', '├', '┤', '┬', '┴'].freeze
32
+ BOX_BORDER = ['│', '─', '', '', '', '', '├', '┤', '┬', '┴'].tap do |val|
33
+ if ENV['TERM']&.end_with?('256color')
34
+ val.slice!(2, 4)
35
+ val.insert(2, '╭', '╮', '╯', '╰')
36
+ end
37
+ val.freeze
38
+ end
33
39
  TEXT_STYLE = [:bold, :dim, :italic, :underline, :blinking, nil, :inverse, :hidden, :strikethrough].freeze
34
40
  private_constant :AIX_TERM, :BOX_GRAPH, :BOX_BORDER, :TEXT_STYLE
35
41
 
@@ -61,7 +67,7 @@ module Squared
61
67
  end
62
68
  wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
63
69
  code = []
64
- args.concat(as_a(styles)).flatten.each_with_index do |type, i|
70
+ args.concat(Array(styles)).flatten.each_with_index do |type, i|
65
71
  next unless type
66
72
 
67
73
  if index == -1
@@ -8,6 +8,14 @@ module Squared
8
8
  def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 30)
9
9
  require 'readline'
10
10
  require 'timeout'
11
+ if agree == 'Y' && cancel == 'N' && !msg.match?(%r{\[(?:Yn|nY|Y/n|y/N)\]})
12
+ case default
13
+ when 'Y'
14
+ msg = "#{msg} [Y/n] "
15
+ when 'N'
16
+ msg = "#{msg} [y/N] "
17
+ end
18
+ end
11
19
  agree = /^#{Regexp.escape(agree)}$/i if agree.is_a?(::String)
12
20
  cancel = /^#{Regexp.escape(cancel)}$/i if cancel.is_a?(::String)
13
21
  Timeout.timeout(timeout) do
@@ -35,13 +43,13 @@ module Squared
35
43
  require 'readline'
36
44
  require 'timeout'
37
45
  if list
38
- grep &&= (grep.is_a?(::Enumerable) ? grep : [grep]).map { |val| Regexp.new(val) }
46
+ grep &&= Array(grep).map { |val| Regexp.new(val) }
39
47
  items = []
40
48
  list.each do |val|
41
49
  next if grep&.none? { |pat| pat.match?(line) }
42
50
 
43
51
  items << val.chomp
44
- puts "#{items.size.to_s.rjust(2)}. #{val}"
52
+ puts '%2d. %s' % [items.size, val]
45
53
  end
46
54
  max = items.size
47
55
  raise_error 'empty selection list' if max == 0
@@ -1,23 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
- require 'fileutils'
4
+ require 'rake'
5
5
 
6
6
  module Squared
7
7
  module Common
8
8
  module System
9
9
  module_function
10
10
 
11
- def shell(*args, **kwargs)
12
- if RUBY_VERSION < '2.6'
13
- exception = kwargs.delete(:exception)
14
- ret = Kernel.system(*args, **kwargs)
15
- return ret if ret || !exception
16
-
17
- raise $?.to_s
11
+ def shell(*args, name: :system, **kwargs)
12
+ if RUBY_ENGINE == 'jruby' && Rake::Win32.windows?
13
+ e = kwargs[:exception]
14
+ if (dir = kwargs[:chdir]) && ((pwd = Dir.pwd) != dir)
15
+ Dir.chdir(dir)
16
+ ret = Kernel.send(name, *args)
17
+ Dir.chdir(pwd)
18
+ else
19
+ ret = Kernel.send(name, *args)
20
+ end
21
+ elsif RUBY_VERSION < '2.6'
22
+ e = kwargs.delete(:exception)
23
+ ret = Kernel.send(name, *args, **kwargs)
18
24
  else
19
- Kernel.system(*args, **kwargs)
25
+ return Kernel.send(name, *args, **kwargs)
20
26
  end
27
+ return ret if ret || !e
28
+
29
+ raise $?.to_s
21
30
  end
22
31
 
23
32
  def copy_dir(src, dest, glob = ['**/*'], create: false, link: nil, force: false, pass: nil, hidden: false,
@@ -31,10 +40,9 @@ module Squared
31
40
  flags = hidden ? [File::FNM_DOTMATCH] : []
32
41
  if pass
33
42
  exclude = []
34
- pass = [pass] unless pass.is_a?(::Array)
35
- pass.each { |val| exclude.concat(Dir.glob(val, *flags, base: base)) }
43
+ Array(pass).each { |val| exclude.concat(Dir.glob(val, *flags, base: base)) }
36
44
  end
37
- (glob.is_a?(::Enumerable) ? glob : [glob]).each do |val|
45
+ Array(glob).each do |val|
38
46
  Dir.glob(val, *flags, base: base) do |file|
39
47
  next if exclude&.include?(file) || (entry = base + file).directory?
40
48
 
@@ -83,8 +91,7 @@ module Squared
83
91
  unless force
84
92
  target = Pathname.new(dest)
85
93
  if target.directory?
86
- src = [src] unless src.is_a?(::Enumerable)
87
- src = src.reject { |val| target.join(File.basename(val)).exist? }
94
+ src = Array(src).reject { |val| target.join(File.basename(val)).exist? }
88
95
  return if src.empty?
89
96
  elsif target.exist?
90
97
  return
@@ -17,13 +17,13 @@ module Squared
17
17
  val = val.strip
18
18
  return [val, '', ''] unless (i = val.index('='))
19
19
 
20
- last = val[i + 1..-1].strip
20
+ last = val[(i + 1)..-1].strip
21
21
  quote = ''
22
22
  if last =~ /\A(["'])(.+)\1\z/
23
23
  last = $2
24
24
  quote = $1
25
25
  end
26
- [val[0..i - 1], last, quote]
26
+ [val[0..(i - 1)], last, quote]
27
27
  end
28
28
 
29
29
  def task_invoke(*cmd, args: [], exception: true, warning: true)
@@ -97,7 +97,11 @@ module Squared
97
97
  ret = env_value(key, suffix: suffix, strict: strict)
98
98
  return ret == equals.to_s unless equals.nil?
99
99
 
100
- ret.empty? || (ignore && as_a(ignore).any? { |val| val.to_s == ret }) ? default : ret
100
+ ret.empty? || (ignore && Array(ignore).any? { |val| val.to_s == ret }) ? default : ret
101
+ end
102
+
103
+ def env_key(*val)
104
+ val.join('_').gsub(/\W+/, '_').upcase
101
105
  end
102
106
 
103
107
  def env_value(key, default = '', suffix: nil, strict: false)
@@ -15,8 +15,7 @@ module Squared
15
15
  def parse(gem, namespace, ext = [pkg])
16
16
  require gem
17
17
  obj = eval namespace
18
- ext = [ext] unless ext.is_a?(Array)
19
- ext.each { |val| @@mime_obj[val] = [obj, ext] }
18
+ Array(ext).each { |val| @@mime_obj[val] = [obj, ext] }
20
19
  rescue LoadError, NameError => e
21
20
  warn e
22
21
  nil
@@ -89,7 +88,7 @@ module Squared
89
88
  @required = true
90
89
  project ? [project, 'not found'] : ['name', 'missing']
91
90
  end
92
- warn log_message(Logger::WARN, msg, subject: self.class, hint: hint, pass: true)
91
+ warn log_message(Logger::WARN, msg, subject: self.class, hint: hint)
93
92
  end
94
93
 
95
94
  def build
@@ -129,7 +128,7 @@ module Squared
129
128
  require(gem || type)
130
129
  obj = eval namespace
131
130
  else
132
- as_a(ext).each do |val|
131
+ Array(ext).each do |val|
133
132
  next unless (data = @@mime_obj[val])
134
133
 
135
134
  obj = data.first
@@ -137,7 +136,7 @@ module Squared
137
136
  end
138
137
  end
139
138
  if obj
140
- ext << type if (ext = as_a(ext)).empty?
139
+ ext << type if (ext = Array(ext)).empty?
141
140
  if !file && target?
142
141
  ext.each do |val|
143
142
  next unless (out = basepath("#{main}.#{val}")).exist?
@@ -250,6 +249,8 @@ module Squared
250
249
  { pat: /\A((?~: ): \{)(.+)(\}\s*)\z/m, styles: theme[:hash], index: 2 },
251
250
  { pat: /\A((?~: ): \[)(.+)(\]\s*)\z/m, styles: theme[:array],
252
251
  index: 2 },
252
+ { pat: /\A((?~: ): )(true|false)(\s*)\z/m, styles: theme[:boolean],
253
+ index: 2 },
253
254
  { pat: /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, styles: theme[:value],
254
255
  index: 2 }
255
256
  ]
@@ -293,7 +294,7 @@ module Squared
293
294
  if stdin?
294
295
  puts out.map!(&:last).join("\n")
295
296
  else
296
- out.map! { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
297
+ out.map! { |item| '%-*s : %s' % [pad, item[0], item[1]] }
297
298
  end
298
299
  end
299
300
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.1'
5
5
  end
@@ -94,7 +94,7 @@ module Squared
94
94
  @project = {}
95
95
  @kind = {}
96
96
  @extensions = []
97
- @envname = @main.gsub(/[^\w]+/, '_').upcase.freeze
97
+ @envname = env_key(@main).freeze
98
98
  @pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
99
99
  @exception = env_bool exception
100
100
  @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
@@ -224,7 +224,7 @@ module Squared
224
224
  end
225
225
  end
226
226
  end
227
- data = Support::ChainData.new(action, step, ns.call(with), ns.call(before), ns.call(after), sync)
227
+ data = Struct::ChainData.new(action, step, ns.call(with), ns.call(before), ns.call(after), sync)
228
228
  (@chain[task_name(task.to_s)] ||= []) << data
229
229
  self
230
230
  end
@@ -278,7 +278,7 @@ module Squared
278
278
  end
279
279
 
280
280
  def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
281
- data = Support::BannerData.new(command, [], check_style(styles, empty: false), check_style(border))
281
+ data = Struct::BannerData.new(command, [], check_style(styles, empty: false), check_style(border))
282
282
  args.each do |meth|
283
283
  if meth.is_a?(Array)
284
284
  found = false
@@ -305,10 +305,10 @@ module Squared
305
305
  end
306
306
  if group
307
307
  label = :group
308
- items = as_a group
308
+ items = Array(group)
309
309
  else
310
310
  label = :ref
311
- items = ref ? as_a(ref) : [:_]
311
+ items = Array(ref || :_)
312
312
  end
313
313
  items.each { |val| @banner[label][val.to_sym] = data }
314
314
  self
@@ -362,7 +362,7 @@ module Squared
362
362
  end
363
363
 
364
364
  def compose(name, &blk)
365
- namespace(task_name(name), &blk) if block_given?
365
+ namespace(task_name(name), &blk)
366
366
  self
367
367
  end
368
368
 
@@ -374,7 +374,7 @@ module Squared
374
374
  def style(obj, *args, target: nil, empty: false)
375
375
  data = nil
376
376
  if target
377
- as_a(target).each_with_index do |key, i|
377
+ Array(target).each_with_index do |key, i|
378
378
  if i == 0
379
379
  break unless (data = __get__(:theme)[key.to_sym])
380
380
  else
@@ -480,7 +480,7 @@ module Squared
480
480
  end
481
481
 
482
482
  def task_namespace(val, first: false)
483
- return nil unless (ret = val.to_s.split(':')).size > 1
483
+ return unless (ret = val.to_s.split(':')).size > 1
484
484
 
485
485
  first ? ret.first : task_join(*ret[0..-2])
486
486
  end
@@ -625,6 +625,14 @@ module Squared
625
625
  Rake::Win32.windows?
626
626
  end
627
627
 
628
+ def jruby?
629
+ RUBY_ENGINE == 'jruby'
630
+ end
631
+
632
+ def jruby_win?
633
+ jruby? && windows?
634
+ end
635
+
628
636
  def docker?
629
637
  !Dir['/.dockerenv', '/docker-*.{sh,d}'].empty?
630
638
  end
@@ -779,7 +787,7 @@ module Squared
779
787
  task key do
780
788
  unless failed.empty? && group.empty?
781
789
  puts log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
782
- subject: 'failed placement', hint: false, pass: true)
790
+ subject: 'failed placement', hint: false)
783
791
  end
784
792
  cols = level.flatten(1).map(&:size).max
785
793
  level.each_with_index do |grp, n|
@@ -801,7 +809,7 @@ module Squared
801
809
 
802
810
  def script_command(task, val, group, ref, on, &blk)
803
811
  if block_given?
804
- val = Support::RunData.new(val, blk)
812
+ val = Struct::RunData.new(val, blk)
805
813
  elsif !val
806
814
  return self
807
815
  end
@@ -822,9 +830,9 @@ module Squared
822
830
  def script_set(data, group: nil, ref: nil)
823
831
  data.freeze
824
832
  if group
825
- as_a(group).each { |val| @script[:group!][val.to_sym] = data }
833
+ Array(group).each { |val| @script[:group!][val.to_sym] = data }
826
834
  elsif ref
827
- as_a(ref).each { |val| @script[:ref!][val.to_sym] = data }
835
+ Array(ref).each { |val| @script[:ref!][val.to_sym] = data }
828
836
  else
829
837
  @script[:ref!][:''] = data
830
838
  end
@@ -864,7 +872,7 @@ module Squared
864
872
  end
865
873
  return false if state == :prod && data[:dev] == true && data[:global]
866
874
 
867
- target && pat.is_a?(Regexp) ? as_a(target).any?(pat) : pat == true
875
+ target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
868
876
  end
869
877
 
870
878
  def scriptobj