squared 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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)