squared 0.1.1 → 0.1.3

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: e2fd23c5964fe7c987966b8d237b569883b2dae5b70d9c120a924e2cc0227873
4
- data.tar.gz: 8ef09d80e13c53fda678aa6a7194e33abf04728fb9d1c17739a5dc6c814e3b03
3
+ metadata.gz: 11c047668befa13733be4f81fbac270909c72be73754f70b464e804c11f8204e
4
+ data.tar.gz: fac920aa92d55210e48c2f780ea366b58f0c9ed870d524b5bf19eeeeb2628ab1
5
5
  SHA512:
6
- metadata.gz: c41b98512dfc370a056716c3af2a599321b6113fa4883ab1f9c6b1418332f6b973560ce2cb1550c3813521eaa326150371ef3e60906cb694d6a6fd41ac1e0f05
7
- data.tar.gz: cedbdcb188a6fb4a8407fc36836ffbeb4b93893217cec168d291845ce9a4f3f4dede9936022b8c950efa48ec21e2f93d013dc7e6fa929397ac80df7d6e3b099a
6
+ metadata.gz: 78b3346cbf690fa4ce9a36431eaad0ffb24d464a46700810c19f6938b5e020c94c1ede8709f61e448f75443f3b8c9df8a00877e380e81beb7ce37732dc244289
7
+ data.tar.gz: ee6b18f73590b38fa91a2f73852cbc6ccc467255bed2c5c540731d565dc43e15b1b6c103866003979518ef416fcb450beb5c58f5f1ad1c20119437d5f795aa84
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.3] - 2024-01-02
4
+
5
+ ### Fixed
6
+
7
+ - Output lines from IO were missing theme styling.
8
+ - Node did not apply build options when stored as Array.
9
+ - Git commit push did not send origin and branch.
10
+
11
+ ## [0.1.2] - 2024-12-23
12
+
13
+ ### Added
14
+
15
+ - Git command tag was implemented.
16
+
17
+ ### Deprecated
18
+
19
+ - Repo static method empty? was relocated into Application.
20
+
21
+ ### Fixed
22
+
23
+ - Namespace prefix was sometimes missing or duplicated.
24
+ - Silent operation used undefined variable.
25
+ - Unnecessary shell option escapes were removed.
26
+ - Ruby command outdated did not display in order when threaded.
27
+ - Regexp uses \A|\z format and not ^|$ for standard matches.
28
+ - Rake being called by a project did not escape options.
29
+ - Workspace did not check base project for Windows filename.
30
+ - Regexp for SemVer did not recognize package names.
31
+
3
32
  ## [0.1.1] - 2024-12-14
4
33
 
5
34
  ### Added
@@ -50,6 +79,8 @@
50
79
 
51
80
  - Changelog was created.
52
81
 
82
+ [0.1.3]: https://github.com/anpham6/squared/releases/tag/v0.1.3-ruby
83
+ [0.1.2]: https://github.com/anpham6/squared/releases/tag/v0.1.2-ruby
53
84
  [0.1.1]: https://github.com/anpham6/squared/releases/tag/v0.1.1-ruby
54
85
  [0.1.0]: https://github.com/anpham6/squared/releases/tag/v0.1.0-ruby
55
86
  [0.0.12]: https://github.com/anpham6/squared/releases/tag/v0.0.12-ruby
data/README.ruby.md CHANGED
@@ -37,17 +37,23 @@ Projects from any accessible folder can be added relative to the parent director
37
37
  require "squared"
38
38
 
39
39
  require "squared/workspace"
40
- require "squared/workspace/repo" # Optional
41
- require "squared/workspace/project/node" #
42
- require "squared/workspace/project/python" #
43
- require "squared/workspace/project/ruby" #
40
+ require "squared/workspace/repo" # Optional
41
+ require "squared/workspace/project/node" #
42
+ require "squared/workspace/project/python" #
43
+ require "squared/workspace/project/ruby" #
44
44
  # OR
45
- require "squared/app" # All workspace related modules
45
+ require "squared/app" # All workspace related modules
46
46
 
47
47
  # NODE_ENV = production
48
- # REPO_ROOT = /workspaces
49
- # REPO_HOME = /workspaces/squared
50
- # rake = /workspaces/squared/Rakefile
48
+
49
+ # REPO_ROOT = /workspaces #
50
+ # REPO_HOME = /workspaces/squared # Dir.pwd
51
+ # rake = /workspaces/squared/Rakefile # main?
52
+ # OR
53
+ # REPO_ROOT = /workspaces # Dir.pwd
54
+ # rake = /workspaces/Rakefile #
55
+ # REPO_HOME = /workspaces/squared # main: "squared"
56
+
51
57
  # pathname = /workspaces/pathname
52
58
  # optparse = /workspaces/optparse
53
59
  # log = /workspaces/logger
@@ -9,7 +9,7 @@ module Squared
9
9
  extend Forwardable
10
10
 
11
11
  def self.to_s
12
- super.match(/[^:]+$/)[0]
12
+ super.match(/[^:]+\z/)[0]
13
13
  end
14
14
 
15
15
  def_delegators :@data, :+, :each, :each_with_index, :entries, :to_a, :include?
@@ -31,7 +31,7 @@ module Squared
31
31
 
32
32
  class JoinSet < Set
33
33
  def self.to_s
34
- super.match(/[^:]+$/)[0]
34
+ super.match(/[^:]+\z/)[0]
35
35
  end
36
36
 
37
37
  def initialize(data = [], delim: ' ')
@@ -46,7 +46,7 @@ module Squared
46
46
  if pat && index != 0
47
47
  return val unless (data = pat.match(val))
48
48
 
49
- ret = index == -1 ? data.to_a[1..-1] : data[index]
49
+ ret = index == -1 ? data.to_a.drop(1) : data[index]
50
50
  else
51
51
  ret = val
52
52
  index = 0
@@ -235,8 +235,8 @@ module Squared
235
235
  sub.each { |h| s = sub_style(s, **h) }
236
236
  s = "| #{s} |"
237
237
  if border
238
- s = sub_style(s, pat: /^(\|)(.+)$/m, styles: border)
239
- s = sub_style(s, pat: /^(.+)(\|)$/m, styles: border, index: 2)
238
+ s = sub_style(s, pat: /\A(\|)(.+)\z/m, styles: border)
239
+ s = sub_style(s, pat: /\A(.+)(\|)\z/m, styles: border, index: 2)
240
240
  end
241
241
  s
242
242
  end
@@ -8,8 +8,8 @@ module Squared
8
8
  def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
9
9
  require 'readline'
10
10
  require 'timeout'
11
- agree = /^#{agree}$/i if agree.is_a?(::String)
12
- cancel = /^#{cancel}$/i if cancel.is_a?(::String)
11
+ agree = /\A#{agree}\z/i if agree.is_a?(::String)
12
+ cancel = /\A#{cancel}\z/i if cancel.is_a?(::String)
13
13
  Timeout.timeout(timeout) do
14
14
  begin
15
15
  while (ch = Readline.readline(msg, true))
@@ -8,38 +8,51 @@ module Squared
8
8
  module Shell
9
9
  module_function
10
10
 
11
- def shell_escape(val, quote: false)
12
- val = val.to_s
13
- return ::Shellwords.escape(val) unless ::Rake::Win32.windows?
11
+ def shell_escape(val, quote: false, force: false)
12
+ if (data = /\A(--?[^= ]+)((=|\s+)(["'])?(.+?)(["'])?)?\z/m.match(val = val.to_s))
13
+ return val unless data[2]
14
14
 
15
- quote ? shell_quote(val, force: false) : val
15
+ join = ->(opt) { data[1] + data[3] + shell_quote(opt) }
16
+ if data[4] == data[6]
17
+ data[4] ? val : join.(data[5])
18
+ else
19
+ join.("#{data[4]}#{data[5]}#{data[6]}")
20
+ end
21
+ elsif Rake::Win32.windows?
22
+ quote ? shell_quote(val, force: force) : val
23
+ else
24
+ Shellwords.escape(val)
25
+ end
16
26
  end
17
27
 
18
28
  def shell_quote(val, force: true)
19
- ret = val.to_s.strip
20
- return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|\S=|[^=]\s+)(["']).+\1$/m
29
+ val = val.to_s
30
+ return val if (!force && !val.include?(' ')) || val =~ /(?:^|\S=|[^=]\s+)(["']).+\1\z/m
21
31
 
22
- ::Rake::Win32.windows? ? "\"#{double_quote(ret)}\"" : "'#{single_quote(ret)}'"
32
+ Rake::Win32.windows? ? "\"#{double_quote(val)}\"" : "'#{single_quote(val)}'"
23
33
  end
24
34
 
25
- def shell_split(val, quote: false, join: false)
26
- ret = ::Shellwords.split(val).map do |opt|
27
- if (data = /^(--?[^= ]+)(=|\s+)?(["'])?(.+?)\3?$/m.match(opt))
28
- next opt unless data[2] && !data[3]
35
+ def shell_split(val, quote: false, join: nil)
36
+ val = Shellwords.split(val).map { |opt| shell_escape(opt, quote: quote) }
37
+ return val unless join
29
38
 
30
- data[1] + data[2] + shell_quote(data[4], force: !::Rake::Win32.windows?)
31
- else
32
- shell_escape(opt, quote: quote)
33
- end
34
- end
35
- join ? ret.join(' ') : ret
39
+ val.join(join.is_a?(::String) ? join : ' ')
40
+ end
41
+
42
+ def shell_option(flag, val = nil, quote: false, escape: true)
43
+ "--#{flag}#{if val
44
+ "=#{if escape
45
+ shell_escape(val, quote: quote)
46
+ else
47
+ quote ? shell_quote(val) : val
48
+ end}"
49
+ end}"
36
50
  end
37
51
 
38
52
  def fill_option(val)
39
- return "-#{val}" if val.size == 1 || val =~ /^[a-z]\d+$/i
53
+ return "-#{val}" if val =~ /\A[a-z](?:\d*)\z/i
40
54
 
41
- val = "--#{val}" unless val.start_with?('-')
42
- shell_escape(val).sub('\\=', '=')
55
+ shell_escape(val.start_with?('-') ? val : "--#{val}")
43
56
  end
44
57
 
45
58
  def single_quote(val)
@@ -9,7 +9,7 @@ module Squared
9
9
  module_function
10
10
 
11
11
  def shell(*args, **kwargs)
12
- if RUBY_VERSION =~ /^2\.[0-5]\./
12
+ if RUBY_VERSION < '2.6'
13
13
  exception = kwargs.delete(:exception)
14
14
  ret = system(*args, **kwargs)
15
15
  return ret if ret || !exception
@@ -12,7 +12,7 @@ module Squared
12
12
  include Rake::DSL
13
13
 
14
14
  def self.to_s
15
- super.match(/[^:]+$/)[0]
15
+ super.match(/[^:]+\z/)[0]
16
16
  end
17
17
 
18
18
  attr_reader :main, :name, :project, :theme
@@ -199,17 +199,18 @@ module Squared
199
199
  title = Pathname.new(file)
200
200
  .realpath
201
201
  .to_s
202
- .sub(Regexp.new("^#{Regexp.escape(File.join(Dir.pwd, ''))}"), '')
202
+ .sub(Regexp.new("\\A#{Regexp.escape(File.join(Dir.pwd, ''))}"), '')
203
203
  emphasize(lines, title: title, sub: unless stdin?
204
204
  [
205
- { pat: /^((?:[^:]|(?<! ):(?! ))+)$/, styles: theme[:banner] },
206
- { pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: theme[:undefined], index: 2 },
207
- { pat: /^(.+)( : (?!undefined).+)$/m, styles: theme[:key] },
208
- { pat: /^(.+ : )(-?[\d.]+)(\s*)$/m, styles: theme[:number], index: 2 },
209
- { pat: /^(.+ : ")(.+)("\s*)$/m, styles: theme[:string], index: 2 },
210
- { pat: /^(.+ : \{)(.+)(\}\s*)$/m, styles: theme[:hash], index: 2 },
211
- { pat: /^(.+ : \[)(.+)(\]\s*)$/m, styles: theme[:array], index: 2 },
212
- { pat: /^(.+ : (?!undefined))([^"\[{].*)$/m, styles: theme[:value],
205
+ { pat: /\A((?:[^:]|(?<! ):(?! ))+)\z/, styles: theme[:banner] },
206
+ { pat: /\A(.*?)(<[^>]+>)(.+)\z/m, styles: theme[:undefined], index: 2 },
207
+ { pat: /\A(.+)( : (?!undefined).+)\z/m, styles: theme[:key] },
208
+ { pat: /\A(.+ : )(-?[\d.]+)(\s*)\z/m, styles: theme[:number],
209
+ index: 2 },
210
+ { pat: /\A(.+ : ")(.+)("\s*)\z/m, styles: theme[:string], index: 2 },
211
+ { pat: /\A(.+ : \{)(.+)(\}\s*)\z/m, styles: theme[:hash], index: 2 },
212
+ { pat: /\A(.+ : \[)(.+)(\]\s*)\z/m, styles: theme[:array], index: 2 },
213
+ { pat: /\A(.+ : (?!undefined))([^"\[{].*)\z/m, styles: theme[:value],
213
214
  index: 2 }
214
215
  ]
215
216
  end)
@@ -261,6 +262,8 @@ module Squared
261
262
  end
262
263
 
263
264
  def format_desc(command, *ext, exist: exist?)
265
+ return unless Rake::TaskManager.record_task_metadata
266
+
264
267
  val = "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
265
268
  message(@prefix, *name.split(':'), command, val, empty: true)
266
269
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.3'
5
5
  end
@@ -56,7 +56,7 @@ module Squared
56
56
  end
57
57
 
58
58
  def to_s
59
- super.match(/[^:]+$/)[0]
59
+ super.match(/[^:]+\z/)[0]
60
60
  end
61
61
 
62
62
  attr_reader :kind_project
@@ -70,8 +70,14 @@ module Squared
70
70
  def initialize(home = Dir.pwd, *, main: nil, prefix: nil,
71
71
  verbose: ARG[:VERBOSE], common: ARG[:COMMON], pipe: ARG[:PIPE], exception: ARG[:FAIL], **)
72
72
  @home = Pathname.new(home).realdirpath
73
+ basename = @home.basename.to_s
74
+ if main
75
+ @main = main.to_s.freeze
76
+ @home = @home.join(@main) unless @main == basename || (windows? && @main.downcase == basename.downcase)
77
+ else
78
+ @main = basename.freeze
79
+ end
73
80
  @root = @home.parent
74
- @main = (main || @home.basename).to_s.freeze
75
81
  @prefix = prefix
76
82
  @series = Application.impl_series.new(self)
77
83
  @project = {}
@@ -322,7 +328,7 @@ module Squared
322
328
 
323
329
  def task_name(val, desc: false)
324
330
  ret = @prefix ? task_join(@prefix, val) : val.to_s
325
- desc ? ret.split(':').join(ARG[:SPACE]) : ret
331
+ desc ? message(*ret.split(':')) : ret
326
332
  end
327
333
 
328
334
  def task_namespace(val, first: false)
@@ -383,7 +389,7 @@ module Squared
383
389
 
384
390
  return ret
385
391
  end
386
- @script[:ref!][:_] || SCRIPT_OBJ
392
+ @script[:ref!][:''] || SCRIPT_OBJ
387
393
  end
388
394
 
389
395
  def script_get(*args, group: nil, ref: nil)
@@ -409,7 +415,7 @@ module Squared
409
415
  return ret if group && (ret = @banner[:group][group.to_sym])
410
416
 
411
417
  ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
412
- @banner[:ref][:_]
418
+ @banner[:ref][:'']
413
419
  end
414
420
 
415
421
  def enabled?
@@ -444,6 +450,10 @@ module Squared
444
450
  !(proj = find(home)).nil? && proj.enabled?
445
451
  end
446
452
 
453
+ def windows?
454
+ Rake::Win32.windows?
455
+ end
456
+
447
457
  def rootpath(*args)
448
458
  root.join(*args)
449
459
  end
@@ -505,7 +515,21 @@ module Squared
505
515
  elsif ref
506
516
  as_a(ref).each { |val| @script[:ref!][val.to_sym] = data }
507
517
  else
508
- @script[:ref!][:_] = data
518
+ @script[:ref!][:''] = data
519
+ end
520
+ end
521
+
522
+ def root?(path, pass: [])
523
+ return false unless path.directory?
524
+
525
+ case path.children.size
526
+ when 0
527
+ true
528
+ when 1
529
+ target = path.children.first
530
+ target.to_s == __FILE__ || pass.any? { |val| val == target.basename.to_s }
531
+ else
532
+ false
509
533
  end
510
534
  end
511
535
 
@@ -15,7 +15,7 @@ module Squared
15
15
  include Rake::DSL
16
16
 
17
17
  VAR_SET = %i[parent global envname dependfile theme run script env].freeze
18
- SEM_VER = /(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?/.freeze
18
+ SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
19
19
  private_constant :VAR_SET, :SEM_VER
20
20
 
21
21
  class << self
@@ -46,7 +46,7 @@ module Squared
46
46
  end
47
47
 
48
48
  def to_s
49
- super.match(/[^:]+$/)[0]
49
+ super.match(/[^:]+\z/)[0]
50
50
  end
51
51
  end
52
52
 
@@ -264,9 +264,9 @@ module Squared
264
264
  val
265
265
  end
266
266
  emphasize(out, title: path, right: true, border: borderstyle, sub: [
267
- { pat: /^(#{Regexp.escape(path.to_s)})(.*)$/, styles: theme[:header] },
268
- { pat: /^(#{Regexp.escape(name)})(.*)$/, styles: theme[:active] },
269
- { pat: /^(.+ )(\()(\d+)(\))(.*)$/, styles: theme[:inline], index: 3 }
267
+ { pat: /\A(#{Regexp.escape(path.to_s)})(.*)\z/, styles: theme[:header] },
268
+ { pat: /\A(#{Regexp.escape(name)})(.*)\z/, styles: theme[:active] },
269
+ { pat: /\A(.+ )(\()(\d+)(\))(.*)\z/, styles: theme[:inline], index: 3 }
270
270
  ])
271
271
  end
272
272
  end
@@ -550,7 +550,7 @@ module Squared
550
550
  cmd = session_done(cmd)
551
551
  log.info cmd
552
552
  begin
553
- if cmd =~ /^[^:]+:[^:]/ && workspace.task_defined?(cmd)
553
+ if cmd =~ /\A[^:]+:[^:]/ && workspace.task_defined?(cmd)
554
554
  log.warn "ENV was discarded: #{var}" if var
555
555
  task_invoke(cmd, exception: exception, warning: warning?)
556
556
  else
@@ -749,6 +749,8 @@ module Squared
749
749
  end
750
750
 
751
751
  def format_desc(action, flag, opts = nil, req: nil, arg: 'opts*')
752
+ return unless Rake::TaskManager.record_task_metadata
753
+
752
754
  opts = "#{arg}=#{opts.join(',')}" if opts.is_a?(Array)
753
755
  out = [@desc]
754
756
  if flag
@@ -771,7 +773,7 @@ module Squared
771
773
  end
772
774
  if verbose
773
775
  out = []
774
- out << cmd.sub(/^\S+/, &:upcase) if data[:command]
776
+ out << cmd.sub(/\A\S+/, &:upcase) if data[:command]
775
777
  data[:order].each do |val|
776
778
  if val.is_a?(Array)
777
779
  s = ' '
@@ -793,7 +795,7 @@ module Squared
793
795
  out << val.to_s
794
796
  end
795
797
  print_banner(*out, styles: data[:styles], border: data[:border], client: client)
796
- elsif multiple && workspace.series.multiple?
798
+ elsif workspace.series.multiple?
797
799
  "## #{__send__(data[:order].first || :path)} ##"
798
800
  end
799
801
  end
@@ -818,10 +820,10 @@ module Squared
818
820
  end
819
821
  if from
820
822
  out << from
821
- pat = /^(#{Regexp.escape(out.last)})(.*)$/
823
+ pat = /\A(#{Regexp.escape(out.last)})(.*)\z/m
822
824
  end
823
825
  else
824
- pat = /^(\s*\d+\.)(.+)$/
826
+ pat = /\A(\s*\d+\.)(.+)\z/m
825
827
  end
826
828
  sub = [headerstyle]
827
829
  sub << { pat: pat, styles: theme[:active] } if pat
@@ -833,16 +835,32 @@ module Squared
833
835
  end
834
836
 
835
837
  def append_repeat(flag, opts)
836
- opts.each { |val| @session << "--#{flag}=#{shell_escape(val, quote: true)}" }
838
+ opts.each { |val| @session << shell_option(flag, val, quote: true) }
837
839
  end
838
840
 
839
- def append_value(opts, delim: false)
841
+ def append_value(opts, delim: false, escape: true)
840
842
  @session << '--' if delim && !opts.empty?
841
- opts.each { |val| @session << shell_escape(val) }
843
+ opts.each { |val| @session << (escape ? shell_escape(val) : shell_quote(val)) }
842
844
  end
843
845
 
844
- def append_option(list, **kwargs)
845
- list.each { |val| @session << "--#{val}" if option(val, **kwargs) }
846
+ def append_first(list, flag: true, equals: false, quote: false, **kwargs)
847
+ list.each do |opt|
848
+ next unless (val = option(opt, **kwargs))
849
+
850
+ return @session << (if flag
851
+ shell_option(opt, equals ? val : nil, quote: quote)
852
+ else
853
+ shell_quote(val)
854
+ end)
855
+ end
856
+ end
857
+
858
+ def append_option(list, equals: false, quote: false, **kwargs)
859
+ list.each do |flag|
860
+ next unless (val = option(flag, **kwargs))
861
+
862
+ @session << shell_option(flag, equals ? val : nil, quote: quote)
863
+ end
846
864
  end
847
865
 
848
866
  def append_nocolor(flag = nil)