squared 0.5.18 → 0.6.0

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.
@@ -9,21 +9,44 @@ module Squared
9
9
  module Utils
10
10
  module_function
11
11
 
12
- def split_escape(val, char: ',')
13
- val.split(/\s*(?<!\\)#{char}\s*/)
12
+ def as_a(obj, *meth, flat: nil, compact: false, &blk)
13
+ return [] if obj.nil?
14
+
15
+ unless obj.is_a?(::Array)
16
+ obj = if obj.respond_to?(:to_ary)
17
+ obj.to_ary
18
+ elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
19
+ val
20
+ else
21
+ [obj]
22
+ end
23
+ end
24
+ obj = flat.is_a?(::Numeric) ? obj.flatten(flat) : obj.flatten if flat
25
+ obj = obj.compact if compact
26
+ obj = obj.map(&meth.shift) until meth.empty?
27
+ return obj unless block_given?
28
+
29
+ obj.select(&blk)
30
+ end
31
+
32
+ def split_escape(val, char: ',', &blk)
33
+ ret = val.split(/\s*(?<!\\)#{char}\s*/)
34
+ return ret unless block_given?
35
+
36
+ ret.each(&blk)
14
37
  end
15
38
 
16
39
  def split_option(val)
17
40
  val = val.strip
18
41
  return [val, '', ''] unless (i = val.index('='))
19
42
 
20
- last = val[(i + 1)..-1].strip
43
+ last = val[i.succ..-1].strip
21
44
  quote = ''
22
45
  if last =~ /\A(["'])(.+)\1\z/
23
46
  last = $2
24
47
  quote = $1
25
48
  end
26
- [val[0..(i - 1)], last, quote]
49
+ [val[0..i.pred], last, quote]
27
50
  end
28
51
 
29
52
  def task_invoke(*cmd, args: [], exception: true, warning: true)
@@ -105,9 +128,9 @@ module Squared
105
128
  end
106
129
  end
107
130
 
108
- def env(key, default = nil, suffix: nil, strict: false, equals: nil, ignore: nil)
131
+ def env(key, default = nil, suffix: nil, strict: false, equals: nil, ignore: nil, **)
109
132
  ret = env_value(key, suffix: suffix, strict: strict)
110
- return ret == equals.to_s unless equals.nil?
133
+ return Array(equals).any? { |val| val.to_s == ret } unless equals.nil?
111
134
 
112
135
  ret.empty? || (ignore && Array(ignore).any? { |val| val.to_s == ret }) ? default : ret
113
136
  end
@@ -12,18 +12,19 @@ module Squared
12
12
  include Rake::DSL
13
13
 
14
14
  class << self
15
- def parse(gem, namespace, ext = [gem])
15
+ def parse(gem, namespace, ext = [pkg])
16
16
  require gem
17
- [eval(namespace), Array(ext)].tap do |data|
18
- data.last.each { |key| @@mime_obj[key] = data }
19
- end
17
+ obj = eval namespace
18
+ Array(ext).each { |val| @@mime_obj[val] = [obj, ext] }
20
19
  rescue LoadError, NameError => e
21
20
  warn e
22
21
  nil
22
+ else
23
+ @@mime_obj[ext.first]
23
24
  end
24
25
 
25
- def link(project, main = project.dependfile&.basename, name = nil, **kwargs, &blk)
26
- return unless project.enabled? && main
26
+ def link(project, main = project.dependfile.basename, name = nil, **kwargs, &blk)
27
+ return unless project.enabled?
27
28
 
28
29
  ret = new(main, name, project: project, **kwargs)
29
30
  ret.instance_eval(&blk) if block_given?
@@ -85,7 +86,7 @@ module Squared
85
86
  ['path not found', realpath]
86
87
  else
87
88
  @required = true
88
- project ? [project, 'not found'] : %w[name missing]
89
+ project ? [project, 'missing'] : %w[name missing]
89
90
  end
90
91
  warn log_message(Logger::WARN, msg, subject: self.class, hint: hint)
91
92
  end
@@ -105,7 +106,7 @@ module Squared
105
106
  next unless (data = Viewer.parse(type, type.upcase, ext))
106
107
  end
107
108
  obj, ext = data
108
- target = file || target? ? file || realpath : nil
109
+ target = file || (realpath if target?)
109
110
 
110
111
  task_desc(command, *ext, target: target)
111
112
  task type, [:keys] do |_, args|
@@ -159,7 +160,7 @@ module Squared
159
160
  end
160
161
 
161
162
  def also(path, type = nil, name: nil, **kwargs)
162
- return self unless (file = basepath(path)).exist? && !@mime.frozen?
163
+ return self if @mime.frozen? || !(file = basepath(path)).exist?
163
164
 
164
165
  ext = mimetype file
165
166
  type ||= ext
@@ -204,7 +205,7 @@ module Squared
204
205
 
205
206
  def read_keys(reader, type, file, keys, ext: [type], opts: {})
206
207
  if file && (mime = mimetype(file)) && basepath(file).exist?
207
- raise_error(file, mime, hint: 'invalid') unless ext.include?(mime)
208
+ raise_error file, mime, hint: 'invalid' unless ext.include?(mime)
208
209
  else
209
210
  if ext.include?(mime)
210
211
  alt = file
@@ -219,7 +220,7 @@ module Squared
219
220
  args = { hint: 'no keys' }
220
221
  end
221
222
  unless file
222
- args ||= { hint: 'not found', kind: LoadError }
223
+ args ||= { kind: Errno::ENOENT }
223
224
  raise_error(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", **args)
224
225
  end
225
226
  end
@@ -236,22 +237,18 @@ module Squared
236
237
  title = Pathname.new(file)
237
238
  .realpath
238
239
  .to_s
239
- .sub(/\A#{Regexp.escape(File.join(Dir.pwd, ''))}/, '')
240
+ .sub(/^#{Regexp.escape(File.join(Dir.pwd, ''))}/, '')
240
241
  emphasize(lines, title: title, sub: unless stdin?
241
242
  [
242
- { pat: /\A((?:[^:]|(?<! ):(?! ))+)\z/, styles: theme[:banner] },
243
- { pat: /\A(.*?)(<[^>]+>)(.+)\z/m, styles: theme[:undefined], index: 2 },
244
- { pat: /\A((?~ : ))( : (?!undefined).+)\z/m, styles: theme[:key] },
245
- { pat: /\A((?~: ): )(-?[\d.]+)(\s*)\z/m, styles: theme[:number],
246
- index: 2 },
247
- { pat: /\A((?~: ): ")(.+)("\s*)\z/m, styles: theme[:string], index: 2 },
248
- { pat: /\A((?~: ): \{)(.+)(}\s*)\z/m, styles: theme[:hash], index: 2 },
249
- { pat: /\A((?~: ): \[)(.+)(\]\s*)\z/m, styles: theme[:array],
250
- index: 2 },
251
- { pat: /\A((?~: ): )(true|false)(\s*)\z/m, styles: theme[:boolean],
252
- index: 2 },
253
- { pat: /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, styles: theme[:value],
254
- index: 2 }
243
+ opt_style(theme[:banner], /\A((?:[^:]|(?<! ):(?! ))+)\z/),
244
+ opt_style(theme[:undefined], /\A(.*?)(<[^>]+>)(.+)\z/m, 2),
245
+ opt_style(theme[:key], /\A((?~ : ))( : (?!undefined).+)\z/m),
246
+ opt_style(theme[:number], /\A((?~: ): )(-?[\d.]+)(\s*)\z/m, 2),
247
+ opt_style(theme[:string], /\A((?~: ): ")(.+)("\s*)\z/m, 2),
248
+ opt_style(theme[:hash], /\A((?~: ): \{)(.+)(\}\s*)\z/m, 2),
249
+ opt_style(theme[:array], /\A((?~: ): \[)(.+)(\]\s*)\z/m, 2),
250
+ opt_style(theme[:boolean], /\A((?~: ): )(true|false)(\s*)\z/m, 2),
251
+ opt_style(theme[:value], /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, 2)
255
252
  ]
256
253
  end, border: theme[:border])
257
254
  end
@@ -262,7 +259,7 @@ module Squared
262
259
  symbolize = opts[:symbolize_names]
263
260
  keys.each do |key|
264
261
  begin
265
- items = key.split('.').flat_map { |name| name =~ /^(.+)\[(\d+)\]$/ ? [$1, $2.to_i] : name }
262
+ items = key.split('.')
266
263
  items = items.map(&:to_sym) if symbolize
267
264
  val = data.dig(*items)
268
265
  if val.nil?
@@ -293,7 +290,7 @@ module Squared
293
290
  if stdin?
294
291
  puts out.map!(&:last).join("\n")
295
292
  else
296
- out.map! { |a, b| '%-*s : %s' % [pad, a, b] }
293
+ out.map! { |item| '%-*s : %s' % [pad, item[0], item[1]] }
297
294
  end
298
295
  end
299
296
 
@@ -308,7 +305,7 @@ module Squared
308
305
  def task_desc(command, *ext, target: nil)
309
306
  return unless Rake::TaskManager.record_task_metadata
310
307
 
311
- val = "#{ext.first}[#{target ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
308
+ val = "#{ext.first}[#{"file?=#{File.basename(main)}.#{ext.last}," if target}keys+]"
312
309
  args = *name.split(':').push(command, val)
313
310
  if project
314
311
  project.workspace.task_desc(*args)
@@ -322,9 +319,7 @@ module Squared
322
319
  end
323
320
 
324
321
  def warning?
325
- return true unless project
326
-
327
- project.workspace.warning
322
+ project ? project.workspace.warning : true
328
323
  end
329
324
 
330
325
  def stdin?
@@ -349,9 +344,7 @@ module Squared
349
344
  end
350
345
 
351
346
  def basepath(*args)
352
- return Pathname.pwd.join(*args) unless project
353
-
354
- project.basepath(*args)
347
+ project ? project.basepath(*args) : Pathname.pwd.join(*args)
355
348
  end
356
349
  end
357
350
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.18'
4
+ VERSION = '0.6.0'
5
5
  end
@@ -5,18 +5,11 @@ module Squared
5
5
  class Application
6
6
  include Common::Format
7
7
  include Utils
8
+ include Support::Variables
8
9
  include Rake::DSL
9
10
 
10
- SCRIPT_OBJ = {
11
- run: nil,
12
- script: nil,
13
- dev: nil,
14
- prod: nil,
15
- global: false,
16
- env: false
17
- }.freeze
18
11
  TASK_METADATA = Rake::TaskManager.record_task_metadata
19
- private_constant :SCRIPT_OBJ, :TASK_METADATA
12
+ private_constant :TASK_METADATA
20
13
 
21
14
  class << self
22
15
  def implement(*objs, base: false)
@@ -75,7 +68,8 @@ module Squared
75
68
  @kind_project = []
76
69
  @task_exclude = Set.new
77
70
 
78
- attr_reader :root, :home, :main, :prefix, :exception, :warning, :pipe, :verbose, :theme, :series, :closed
71
+ attr_reader :root, :home, :main, :prefix, :theme, :series, :closed
72
+ attr_accessor :exception, :pipe, :verbose, :warning
79
73
 
80
74
  def initialize(home = (ARG[:HOME] && ENV[ARG[:HOME]]) || Dir.pwd, *, main: nil, prefix: nil,
81
75
  verbose: ARG[:VERBOSE], common: ARG[:COMMON], pipe: ARG[:PIPE], exception: ARG[:FAIL], **)
@@ -92,40 +86,40 @@ module Squared
92
86
  @prefix = prefix
93
87
  @series = Application.series_wrap(self)
94
88
  @project = {}
95
- @kind = Support.hashlist
89
+ @kind = hashlist
96
90
  @extensions = []
97
91
  @envname = env_key(@main).freeze
98
- @pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
99
- @exception = env_bool exception
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
107
- @warning = @verbose != false
92
+ self.exception = env_bool exception
93
+ self.pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
94
+ self.verbose = if $VERBOSE.nil?
95
+ false
96
+ elsif verbose.nil?
97
+ @pipe != 0
98
+ else
99
+ env_bool(verbose, verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
100
+ end
101
+ self.warning = @verbose != false
108
102
  @closed = false
109
- if common
110
- @theme = __get__(:theme)[:workspace]
111
- ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(Pathname)
112
- else
113
- @theme = {}
114
- end
115
- @chain = Support.hashlist
103
+ @theme = if common
104
+ ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(Pathname)
105
+ __get__(:theme)[:workspace]
106
+ else
107
+ {}
108
+ end
109
+ @chain = hashlist
116
110
  @script = {
117
- group: Support.hashobj,
118
- ref: Support.hashobj,
111
+ group: hashobj,
112
+ ref: hashobj,
119
113
  group!: {},
120
114
  ref!: {}
121
115
  }.freeze
122
116
  @events = {
123
- group: Support.hashobj,
124
- ref: Support.hashobj
117
+ group: hashobj,
118
+ ref: hashobj
125
119
  }.freeze
126
120
  @pass = {
127
- group: Support.hashobj,
128
- ref: Support.hashobj,
121
+ group: hashobj,
122
+ ref: hashobj,
129
123
  global: {},
130
124
  pattern: []
131
125
  }.freeze
@@ -179,11 +173,14 @@ module Squared
179
173
  end
180
174
 
181
175
  def with(*val, pass: false, group: nil, **kwargs, &blk)
182
- return self if pass == true || (pass && Array(pass).map(&:to_s).any? { |s| respond_to?(s) && __send__(s) })
176
+ return self if pass == true || (pass && as_a(pass, :to_s).any? { |s| respond_to?(s) && __send__(s) })
183
177
 
184
178
  @group = nil
185
179
  @ref = nil
186
- @withargs = kwargs.empty? ? nil : kwargs
180
+ @withargs = unless kwargs.empty?
181
+ kwargs.delete(:parent)
182
+ kwargs
183
+ end
187
184
  val = as_a(group || kwargs[:ref], flat: true, compact: true) if val.empty?
188
185
  kind = val.first
189
186
  val = kind if val.size == 1
@@ -193,7 +190,7 @@ module Squared
193
190
  when Symbol
194
191
  @ref = val
195
192
  else
196
- raise_error 'missing group or ref' if block_given?
193
+ raise_error ArgumentError, 'missing group or ref' if block_given?
197
194
  end
198
195
  if block_given?
199
196
  instance_eval(&blk)
@@ -218,7 +215,7 @@ module Squared
218
215
  nil
219
216
  else
220
217
  action.map! { |val| task_name(val) }
221
- prefix ? nil : @project.keys
218
+ @project.keys unless prefix
222
219
  end
223
220
  ns = lambda do |val|
224
221
  next if (ret = as_a(val, :to_s, flat: true)).empty?
@@ -310,22 +307,21 @@ module Squared
310
307
  end
311
308
  data.order << meth
312
309
  end
313
- if group
314
- label = :group
315
- items = Array(group)
316
- else
317
- label = :ref
318
- items = Array(ref || :_)
319
- end
320
- items.each { |val| @banner[label][val.to_sym] = data }
310
+ Array(if group
311
+ label = :group
312
+ group
313
+ else
314
+ label = :ref
315
+ ref || :_
316
+ end).each { |val| @banner[label][val.to_sym] = data }
321
317
  self
322
318
  end
323
319
 
324
320
  def add(path, project = nil, **kwargs, &blk)
325
- kwargs = Support.hashdup(@withargs).update(kwargs) if @withargs
321
+ kwargs = hashdup(@withargs).update(kwargs) if @withargs
326
322
  ref = kwargs.key?(:ref) ? kwargs.delete(:ref) : @ref
327
323
  kwargs[:group] = @group if @group && !kwargs.key?(:group)
328
- path = root + path
324
+ path = rootpath path
329
325
  project = (project || path.basename).to_s
330
326
  name = task_name project
331
327
  index = 0
@@ -382,11 +378,10 @@ module Squared
382
378
  end
383
379
  end
384
380
  if obj.is_a?(String)
385
- begin
386
- obj = JSON.parse(homepath(obj).read, { symbolize_names: true })
381
+ obj = begin
382
+ JSON.parse(homepath(obj).read, { symbolize_names: true })
387
383
  rescue StandardError => e
388
384
  warn log_message(Logger::ERROR, e)
389
- obj = nil
390
385
  end
391
386
  end
392
387
  apply_style(data || theme, obj, args, empty: empty) if obj && (!target || data)
@@ -448,7 +443,7 @@ module Squared
448
443
  end
449
444
 
450
445
  def task_localname(val)
451
- prefix && val.is_a?(String) ? val.sub(/\A#{Regexp.escape(prefix)}:/, '') : val.to_s
446
+ prefix && val.is_a?(String) ? val.sub(/^#{Regexp.escape(prefix)}:/, '') : val.to_s
452
447
  end
453
448
 
454
449
  def task_desc(*args, **kwargs)
@@ -497,7 +492,7 @@ module Squared
497
492
  if (base = task_base?(key))
498
493
  tasks << key if obj.has?(key, baseref)
499
494
  elsif (batch = series.batch_get(key))
500
- obj.allref do |ref|
495
+ obj.allref.each do |ref|
501
496
  next unless obj.has?(key, ref) && (data = batch[ref])
502
497
 
503
498
  data.each do |val|
@@ -516,7 +511,7 @@ module Squared
516
511
  if tasks.empty?
517
512
  return [] if (base && !obj.ref?(baseref)) || !(data = series.alias_get(key))
518
513
 
519
- obj.allref do |ref|
514
+ obj.allref.each do |ref|
520
515
  next unless obj.has?(key, ref) && (alt = data[ref])
521
516
 
522
517
  ret = task_resolve obj, alt
@@ -564,7 +559,7 @@ module Squared
564
559
 
565
560
  return ret
566
561
  end
567
- @script[:ref!][:''] || SCRIPT_OBJ
562
+ @script[:ref!][:''] ||= scriptobj
568
563
  end
569
564
 
570
565
  def script_get(*args, group: nil, ref: nil)
@@ -740,23 +735,23 @@ module Squared
740
735
  index = k if w && has.call(w, v1)
741
736
  if a && has.call(a, v1)
742
737
  if index
743
- with.call(l + 1)
738
+ with.call(l.succ)
744
739
  throw :found
745
740
  else
746
- index = k + 1
741
+ index = k.succ
747
742
  end
748
743
  elsif b && has.call(b, v1)
749
744
  if index
750
745
  with.call(l)
751
746
  throw :found
752
747
  else
753
- index = k - 1
748
+ index = k.pred
754
749
  end
755
750
  elsif index
756
751
  if a || b
757
752
  tasks.each_with_index do |v2, m|
758
753
  if a && has.call(a, v2)
759
- with.call(m + 1)
754
+ with.call(m.succ)
760
755
  throw :found
761
756
  elsif b && has.call(b, v2)
762
757
  with.call(m)
@@ -766,7 +761,7 @@ module Squared
766
761
  if !pass
767
762
  pass = [i, data]
768
763
  elsif pass.include?(data)
769
- if i == pass.first + 1
764
+ if i == pass.first.succ
770
765
  pass.delete(data)
771
766
  pass = nil if pass.size == 1
772
767
  end
@@ -778,7 +773,7 @@ module Squared
778
773
  else
779
774
  next
780
775
  end
781
- step = index == -1 ? -1 : index + 1
776
+ step = index == -1 ? -1 : index.succ
782
777
  throw :found
783
778
  end
784
779
  end
@@ -806,18 +801,15 @@ module Squared
806
801
  format_desc key
807
802
  task key do
808
803
  unless failed.empty? && group.empty?
809
- puts(log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
810
- subject: 'failed placement', hint: false), pipe: 2)
804
+ group.each { |val| failed += val.action }
805
+ puts log_message(Logger::ERROR, *failed, subject: 'failed placement', hint: false), pipe: 2
811
806
  end
812
- cols = level.flatten(1).map(&:size).max
813
- level.each_with_index do |grp, n|
814
- title = "Step #{n.succ}#{if !sync.include?(grp) || (grp.size == 1 && series.parallel.include?(grp.first))
815
- ''
816
- else
807
+ level.each_with_index do |grp, i|
808
+ title = "Step #{i.succ}#{if sync.include?(grp) && !(grp.size == 1 && series.parallel.include?(grp.first))
817
809
  ' (sync)'
818
810
  end}"
819
- emphasize(grp, title: title, cols: [cols, title.size].max, border: theme[:border],
820
- sub: [pat: /\A(Step \d+)(.*)\z/, styles: theme[:header]])
811
+ emphasize(grp, title: title, cols: level.flatten(1).push(title), border: theme[:border],
812
+ sub: opt_style(theme[:header], /\A(Step \d+)(.*)\z/))
821
813
  end
822
814
  end
823
815
  end
@@ -835,12 +827,11 @@ module Squared
835
827
  end
836
828
  if group
837
829
  label = :group
838
- items = as_a(group, :to_sym)
830
+ as_a group, :to_sym
839
831
  else
840
832
  label = :ref
841
- items = as_a(ref, :to_sym)
842
- end
843
- items.each do |name|
833
+ as_a ref, :to_sym
834
+ end.each do |name|
844
835
  @script[label][name][task] = val
845
836
  @events[label][name][task] = on if on.is_a?(Hash)
846
837
  end
@@ -879,26 +870,34 @@ module Squared
879
870
 
880
871
  path.each_child do |c|
881
872
  name = c.basename.to_s
882
- next if c.to_s == __FILE__ || (@main == name && c.directory? && c.empty?) || pass.any? { |val| val == name }
883
-
884
- return false
873
+ unless c.to_s == __FILE__ || (@main == name && c.directory? && c.empty?) || pass.any? { |val| val == name }
874
+ return false
875
+ end
885
876
  end
886
877
  true
887
878
  end
888
879
 
889
- def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false)
880
+ def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false, script: true)
890
881
  data = script_find ref, group
882
+ type = script ? :script : :run
891
883
  if global
892
- target = data[:script] || data[:run] if target.nil?
884
+ target = data[type] if target.nil?
893
885
  pat = data[state] if pat.nil?
894
886
  end
895
- return false if state == :prod && data[:dev] == true && data[:global]
887
+ return false if state == :prod && data[:dev] == true && data[:global][type]
896
888
 
897
889
  target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
898
890
  end
899
891
 
900
892
  def scriptobj
901
- SCRIPT_OBJ.dup
893
+ {
894
+ run: nil,
895
+ script: nil,
896
+ dev: nil,
897
+ prod: nil,
898
+ global: {},
899
+ env: {}
900
+ }
902
901
  end
903
902
  end
904
903
  end