squared 0.5.4 → 0.5.6

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.
@@ -94,7 +94,7 @@ module Squared
94
94
  PATH.freeze
95
95
  ARG.freeze
96
96
  VAR.each_value(&:freeze)
97
- VAR[:theme].each_value(&:freeze)
97
+ VAR[:theme].each_value { |val| val.freeze.each_value(&:freeze) }
98
98
  VAR.freeze
99
99
  end
100
100
 
@@ -143,11 +143,11 @@ module Squared
143
143
  def apply_style(data, key, args, empty: true)
144
144
  return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
145
145
 
146
- set = ->(k, v) { data[k] = check_style(v, empty: empty) }
146
+ set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
147
147
  if key.is_a?(::Hash)
148
148
  key.each { |k, v| set.call(k, v || args) }
149
149
  else
150
- set.call(key.to_sym, args)
150
+ set.call(key, args)
151
151
  end
152
152
  end
153
153
 
@@ -159,7 +159,8 @@ module Squared
159
159
  when Logger::WARN then :warn
160
160
  when Logger::ERROR then :error
161
161
  when Logger::FATAL then :fatal
162
- else :unknown end
162
+ else :unknown
163
+ end
163
164
  else
164
165
  level.to_s.downcase.to_sym
165
166
  end
@@ -196,7 +197,7 @@ module Squared
196
197
  end
197
198
  end
198
199
 
199
- def puts_oe(*args, pipe: 1)
200
+ def log_console(*args, pipe: 1)
200
201
  return if args.first == false && args.size == 1
201
202
 
202
203
  if pipe.is_a?(Pathname)
@@ -213,6 +214,8 @@ module Squared
213
214
  (pipe == 2 ? $stderr : $stdout).puts(*args)
214
215
  end
215
216
 
217
+ alias puts_oe log_console
218
+
216
219
  module_function
217
220
 
218
221
  def message(*args, hint: nil, empty: false, space: ARG[:SPACE])
@@ -48,7 +48,7 @@ module Squared
48
48
  list.each do |val|
49
49
  next if grep&.none? { |pat| pat.match?(line) }
50
50
 
51
- items << val.chomp
51
+ items << val.to_s.chomp
52
52
  puts '%2d. %s' % [items.size, val]
53
53
  end
54
54
  max = items.size
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rake'
4
+ require 'shellwords'
4
5
 
5
6
  module Squared
6
7
  module Common
@@ -33,7 +34,6 @@ module Squared
33
34
  elsif Rake::Win32.windows?
34
35
  $2
35
36
  else
36
- require 'shellwords'
37
37
  Shellwords.escape($2)
38
38
  end
39
39
  elsif Rake::Win32.windows?
@@ -41,7 +41,6 @@ module Squared
41
41
  elsif val.empty?
42
42
  ''
43
43
  else
44
- require 'shellwords'
45
44
  Shellwords.escape(val)
46
45
  end
47
46
  end
@@ -97,6 +96,12 @@ module Squared
97
96
  ret.join(join.is_a?(::String) ? join : ' ')
98
97
  end
99
98
 
99
+ def shell_bin(name, env: true)
100
+ key = name.upcase
101
+ shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
102
+ option: false, force: false)
103
+ end
104
+
100
105
  def line_width(lines)
101
106
  ret = [lines.max_by(&:size).size, 80].max
102
107
  [ret, Rake.application.terminal_width].min
@@ -24,7 +24,7 @@ module Squared
24
24
  else
25
25
  return Kernel.send(name, *args, **kwargs)
26
26
  end
27
- return ret if ret || !e
27
+ return ret unless e && !ret && name == :system
28
28
 
29
29
  raise $?.to_s
30
30
  end
@@ -41,8 +41,8 @@ module Squared
41
41
  attr_reader :main, :name, :project, :theme
42
42
  attr_accessor :pipe
43
43
 
44
- def initialize(main, name = nil, project: nil, prefix: nil, command: nil, dump: nil, opts: {}, auto: true,
45
- common: ARG[:COMMON], pipe: ARG[:PIPE], **)
44
+ def initialize(main, name = nil, project: nil, command: nil, opts: {}, auto: true,
45
+ common: ARG[:COMMON], pipe: ARG[:PIPE], **kwargs)
46
46
  if project && (project.respond_to?(:workspace) || (project = __get__(:project)[project.to_s]))
47
47
  main = project.basepath(main).to_s
48
48
  @project = project
@@ -50,9 +50,9 @@ module Squared
50
50
  @required = true
51
51
  end
52
52
  @name = name || @project&.name
53
- @prefix = prefix unless @project
53
+ @prefix = kwargs[:prefix] unless @project
54
54
  @ext = File.extname(main)
55
- @dump = dump
55
+ @dump = kwargs[:dump]
56
56
  @mime = {}
57
57
  @theme = common ? __get__(:theme)[:viewer] : {}
58
58
  @pipe = env_pipe(pipe, @project ? @project.pipe : 1)
@@ -86,7 +86,7 @@ module Squared
86
86
  ['path not found', realpath]
87
87
  else
88
88
  @required = true
89
- project ? [project, 'not found'] : ['name', 'missing']
89
+ project ? [project, 'not found'] : %w[name missing]
90
90
  end
91
91
  warn log_message(Logger::WARN, msg, subject: self.class, hint: hint)
92
92
  end
@@ -94,10 +94,10 @@ module Squared
94
94
  def build
95
95
  return unless enabled?
96
96
 
97
- namespace(ns = task_name(name)) do
97
+ namespace task_name(name) do |ns|
98
98
  @mime.each do |type, items|
99
99
  items.each do |command, file, opts|
100
- next if Rake::Task.task_defined?("#{ns}:#{command}:#{type}")
100
+ next if Rake::Task.task_defined?("#{ns.scope.path}:#{command}:#{type}")
101
101
 
102
102
  namespace command do
103
103
  unless (data = @@mime_obj[type])
@@ -196,7 +196,7 @@ module Squared
196
196
  private
197
197
 
198
198
  def puts(*args)
199
- puts_oe(*args, pipe: pipe)
199
+ log_console(*args, pipe: pipe)
200
200
  end
201
201
 
202
202
  def log
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.4'
4
+ VERSION = '0.5.6'
5
5
  end
@@ -95,9 +95,15 @@ module Squared
95
95
  @kind = Support.hashlist
96
96
  @extensions = []
97
97
  @envname = env_key(@main).freeze
98
- @pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
98
+ @pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
99
99
  @exception = env_bool exception
100
- @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
100
+ @verbose = if $VERBOSE.nil?
101
+ false
102
+ elsif verbose.nil?
103
+ @pipe != 0
104
+ else
105
+ env_bool(verbose, verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
106
+ end
101
107
  @warning = @verbose != false
102
108
  @closed = false
103
109
  if common
@@ -173,7 +179,9 @@ module Squared
173
179
  self
174
180
  end
175
181
 
176
- def with(*val, group: nil, **kwargs, &blk)
182
+ def with(*val, pass: false, group: nil, **kwargs, &blk)
183
+ return self if pass == true || (pass && Array(pass).map(&:to_s).any? { |s| respond_to?(s) && __send__(s) })
184
+
177
185
  @group = nil
178
186
  @ref = nil
179
187
  @withargs = kwargs.empty? ? nil : kwargs
@@ -382,7 +390,15 @@ module Squared
382
390
  end
383
391
  end
384
392
  end
385
- apply_style(data || theme, obj, args, empty: empty) unless target && !data
393
+ if obj.is_a?(String)
394
+ begin
395
+ obj = JSON.parse(homepath(obj).read, { symbolize_names: true })
396
+ rescue StandardError => e
397
+ warn log_message(Logger::ERROR, e)
398
+ obj = nil
399
+ end
400
+ end
401
+ apply_style(data || theme, obj, args, empty: empty) if obj && (!target || data)
386
402
  self
387
403
  end
388
404
 
@@ -418,7 +434,7 @@ module Squared
418
434
  ret << proj if proj
419
435
  end
420
436
  end
421
- return (group || ref ? ret : ret[0]) unless block_given?
437
+ return (group || ref ? ret : ret.first) unless block_given?
422
438
 
423
439
  ret.each(&blk)
424
440
  self
@@ -673,6 +689,10 @@ module Squared
673
689
  { exception: exception, warning: warning }
674
690
  end
675
691
 
692
+ def size
693
+ @project.size
694
+ end
695
+
676
696
  def to_s
677
697
  (home? ? home : root).to_s
678
698
  end
@@ -795,8 +815,8 @@ module Squared
795
815
  format_desc key
796
816
  task key do
797
817
  unless failed.empty? && group.empty?
798
- puts log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
799
- subject: 'failed placement', hint: false)
818
+ puts(log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
819
+ subject: 'failed placement', hint: false), pipe: 2)
800
820
  end
801
821
  cols = level.flatten(1).map(&:size).max
802
822
  level.each_with_index do |grp, n|
@@ -812,8 +832,8 @@ module Squared
812
832
  end
813
833
  end
814
834
 
815
- def puts(*args)
816
- puts_oe(*args, pipe: pipe)
835
+ def puts(*args, **kwargs)
836
+ log_console(*args, pipe: kwargs[:pipe] || pipe)
817
837
  end
818
838
 
819
839
  def script_command(task, val, group, ref, on, &blk)
@@ -19,9 +19,9 @@ module Squared
19
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
- pass only exclude].freeze
22
+ pass only exclude asdf].freeze
23
23
  BLK_SET = %i[run depend doc lint test copy clean].freeze
24
- SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?-?(\S+)?\b/.freeze
24
+ SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
25
25
  URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
26
26
  TASK_METADATA = Rake::TaskManager.record_task_metadata
27
27
  private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
@@ -66,11 +66,17 @@ module Squared
66
66
 
67
67
  @@tasks = {}
68
68
  @@graph = { _: [] }
69
+ @@asdf = if File.exist?("#{Dir.home}/.asdf/asdf.sh")
70
+ [Pathname.new("#{Dir.home}/.asdf"), 15]
71
+ elsif ENV['ASDF_DATA_DIR']
72
+ [Pathname.new(ENV['ASDF_DATA_DIR']), 16]
73
+ end
69
74
  @@print_order = 0
70
75
 
71
76
  subtasks({
72
77
  'graph' => %i[run print].freeze,
73
- 'unpack' => %i[zip tar gem ext].freeze
78
+ 'unpack' => %i[zip tar gem ext].freeze,
79
+ 'asdf' => %i[set exec current]
74
80
  })
75
81
 
76
82
  attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
@@ -114,6 +120,7 @@ module Squared
114
120
  only_set kwargs[:only]
115
121
  exclude_set kwargs[:exclude]
116
122
  archive_set kwargs[:archive]
123
+ asdf_set kwargs[:asdf]
117
124
  theme_set common
118
125
  initialize_ref Base.ref
119
126
  end
@@ -267,9 +274,9 @@ module Squared
267
274
  -1
268
275
  elsif h.any? { |val| e.include?(val) }
269
276
  1
270
- elsif e.any? { |val| f.include?(val) }
277
+ elsif e.any? { |val| f.include?(val) } # rubocop:disable Lint/DuplicateBranch
271
278
  -1
272
- elsif f.any? { |val| e.include?(val) }
279
+ elsif f.any? { |val| e.include?(val) } # rubocop:disable Lint/DuplicateBranch
273
280
  1
274
281
  elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
275
282
  @index <=> i
@@ -318,7 +325,7 @@ module Squared
318
325
  flags.each do |flag|
319
326
  case action
320
327
  when 'graph'
321
- next unless graph?
328
+ break unless graph?
322
329
 
323
330
  format_desc action, flag, '(-)project*'
324
331
  task flag do |_, args|
@@ -329,10 +336,10 @@ module Squared
329
336
  out, done = graph(args, out: [])
330
337
  out.map! do |val|
331
338
  done.each_with_index do |proj, i|
332
- if val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
333
- val += " (#{i.succ})"
334
- break
335
- end
339
+ next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
340
+
341
+ val += " (#{i.succ})"
342
+ break
336
343
  end
337
344
  val
338
345
  end
@@ -369,6 +376,34 @@ module Squared
369
376
  end
370
377
  unpack(path + dir, uri: tag, digest: digest, ext: ext, force: force)
371
378
  end
379
+ when 'asdf'
380
+ break unless @asdf
381
+
382
+ case flag
383
+ when :set
384
+ format_desc action, flag, 'version,opts*=u|home,p|parent'
385
+ task flag, [:version] do |_, args|
386
+ args = if (version = args.version)
387
+ args.extras
388
+ else
389
+ version, opts = choice_index('Select a version',
390
+ @asdf[1].children
391
+ .map(&:basename)
392
+ .append('latest', 'system'),
393
+ force: true, accept: [['Confirm?', false, true]],
394
+ values: ['Options'])
395
+ OptionPartition.strip(opts)
396
+ end
397
+ asdf(flag, args, version: version)
398
+ end
399
+ else
400
+ format_desc(action, flag, flag == :exec ? 'command' : nil)
401
+ task flag do |_, args|
402
+ args = args.to_a
403
+ args << readline('Enter command', force: true) if args.empty? && flag == :exec
404
+ asdf flag, args
405
+ end
406
+ end
372
407
  end
373
408
  end
374
409
  end
@@ -451,13 +486,13 @@ module Squared
451
486
  if args.first.is_a?(Struct)
452
487
  f, blk = args.first.to_a
453
488
  args[0] = instance_eval(&blk) || f
454
- return unless args[0]
489
+ return unless args.first
455
490
  end
456
491
  if args.all? { |val| val.is_a?(Array) }
457
492
  cmd = []
458
493
  var = {}
459
494
  args.each do |val|
460
- next instance_exec(*val[1..-1], &val[0]) if val.first.is_a?(Proc)
495
+ next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
461
496
 
462
497
  a, b, c, d, e = val
463
498
  case b
@@ -761,6 +796,33 @@ module Squared
761
796
  end
762
797
  end
763
798
 
799
+ def asdf(flag, opts = [], version: nil)
800
+ return unless @asdf
801
+
802
+ cmd = session 'asdf', flag
803
+ name = @asdf.first
804
+ legacy = @@asdf[1] == 15
805
+ case flag
806
+ when :set
807
+ u = has_value?(opts, %w[u home])
808
+ cmd << if legacy
809
+ cmd.delete(flag)
810
+ u ? 'global' : 'local'
811
+ elsif has_value?(opts, %w[p parent])
812
+ '--parent'
813
+ elsif u
814
+ '--home'
815
+ end
816
+ cmd << name << version
817
+ when :exec
818
+ cmd.merge(opts)
819
+ when :current
820
+ cmd << '--no-header' unless legacy
821
+ cmd << name
822
+ end
823
+ print_success if success?(run(from: :"asdf:#{flag}")) && flag == :set
824
+ end
825
+
764
826
  def first(key, *args, **kwargs, &blk)
765
827
  event(:first, key, *args, **kwargs, &blk)
766
828
  end
@@ -836,6 +898,8 @@ module Squared
836
898
  parent_set val
837
899
  when :archive
838
900
  archive_set val
901
+ when :asdf
902
+ asdf_set val
839
903
  when :run
840
904
  run_set(*args, **kwargs)
841
905
  when :script
@@ -945,7 +1009,7 @@ module Squared
945
1009
  def log
946
1010
  return @log unless @log.is_a?(Array)
947
1011
 
948
- @log = Logger.new(enabled? ? @log[0] : nil, **@log[1])
1012
+ @log = Logger.new(enabled? ? @log.first : nil, **@log.last)
949
1013
  end
950
1014
 
951
1015
  def allref
@@ -986,8 +1050,8 @@ module Squared
986
1050
 
987
1051
  private
988
1052
 
989
- def puts(*args)
990
- puts_oe(*args, pipe: pipe)
1053
+ def puts(*args, **kwargs)
1054
+ log_console(*args, pipe: kwargs[:pipe] || pipe)
991
1055
  end
992
1056
 
993
1057
  def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
@@ -996,10 +1060,8 @@ module Squared
996
1060
  warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
997
1061
  return
998
1062
  end
999
- i = interactive && !(@session && option('y'))
1000
1063
  cmd = cmd.target if cmd.is_a?(OptionPartition)
1001
- cmd = session_done cmd
1002
- if i
1064
+ if interactive && (!@session || !option('y'))
1003
1065
  title, y = case interactive
1004
1066
  when Array
1005
1067
  interactive
@@ -1008,8 +1070,9 @@ module Squared
1008
1070
  else
1009
1071
  ['Run', 'Y']
1010
1072
  end
1011
- exit 1 unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}]", y)
1073
+ exit 1 unless confirm("#{title}? [#{sub_style(cmd.to_s, styles: theme[:inline])}]", y)
1012
1074
  end
1075
+ cmd = session_done cmd
1013
1076
  log&.info cmd
1014
1077
  on :first, from
1015
1078
  begin
@@ -1226,12 +1289,12 @@ module Squared
1226
1289
  end
1227
1290
 
1228
1291
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
1229
- prefix = stripext(prefix.to_s).upcase
1230
- if path && (val = ENV["PATH_#{prefix}"] || PATH[prefix] || PATH[prefix.to_sym])
1292
+ prefix = stripext prefix.to_s
1293
+ if path && (val = shell_bin(prefix))
1231
1294
  cmd[0] = shell_quote(val, force: false)
1232
1295
  end
1233
1296
  ret = JoinSet.new(cmd.flatten(1))
1234
- if options && (val = env("#{prefix}_OPTIONS"))
1297
+ if options && (val = env("#{prefix.upcase}_OPTIONS"))
1235
1298
  split_escape(val).each { |opt| ret.last(fill_option(opt), /\A(--?[^ =]+)[ =].+\z/m) }
1236
1299
  end
1237
1300
  main ? @session = ret : ret
@@ -1410,9 +1473,9 @@ module Squared
1410
1473
  unless items.empty?
1411
1474
  pad = items.size.to_s.size
1412
1475
  items.each_with_index do |val, i|
1413
- next unless matchany?(val[0], reg)
1476
+ next unless matchany?(val.first, reg)
1414
1477
 
1415
- out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val[0]])
1478
+ out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val.first])
1416
1479
  end
1417
1480
  end
1418
1481
  sub = [headerstyle]
@@ -1760,7 +1823,14 @@ module Squared
1760
1823
  return -1 if b.empty?
1761
1824
  return 1 if a.empty?
1762
1825
 
1763
- a, b = [a.first, b.first].map! { |c| [c[0], c[2], c[4] || '0', c[5] ? '-1' : '0'] }
1826
+ a, b = [a.first, b.first].map! do |c|
1827
+ begin
1828
+ d = Integer(c[5]).to_s
1829
+ rescue StandardError
1830
+ d = c[5] ? '-1' : '0'
1831
+ end
1832
+ [c[0], c[2], c[4] || '0', d]
1833
+ end
1764
1834
  a.each_with_index do |c, index|
1765
1835
  next if c == (d = b[index])
1766
1836
 
@@ -1952,6 +2022,13 @@ module Squared
1952
2022
  end
1953
2023
  end
1954
2024
 
2025
+ def asdf_set(val)
2026
+ @asdf = if @@asdf && val
2027
+ dir = @@asdf[0].join('installs', val)
2028
+ [val, dir] if dir.exist? && !dir.empty?
2029
+ end
2030
+ end
2031
+
1955
2032
  def theme_set(common)
1956
2033
  @theme = if !verbose
1957
2034
  {}
@@ -2061,8 +2138,8 @@ module Squared
2061
2138
  workspace.series.name_get(action).yield_self { |name| name != action && invoked_sync?(name) }
2062
2139
  end
2063
2140
 
2064
- def success?(ret)
2065
- ret == true && stdout? && banner?
2141
+ def success?(ret, display = true)
2142
+ ret == true && display && stdout? && banner?
2066
2143
  end
2067
2144
 
2068
2145
  def banner?