squared 0.7.6 → 0.8.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.
@@ -7,10 +7,8 @@ require 'timeout'
7
7
  module Squared
8
8
  module Common
9
9
  module System
10
- class << self
11
- private
12
-
13
- def parse_link(val)
10
+ module Internal
11
+ def self.parse_link(val)
14
12
  case val
15
13
  when 's', true
16
14
  1
@@ -25,26 +23,18 @@ module Squared
25
23
  end
26
24
  end
27
25
  end
26
+ private_constant :Internal
28
27
 
29
28
  module_function
30
29
 
31
30
  def shell(*args, name: :system, **kwargs)
32
- kwargs.delete(:exception) unless name == :system
33
- if RUBY_ENGINE == 'jruby' && Rake::Win32.windows?
34
- ex = kwargs[:exception]
35
- if (dir = kwargs[:chdir]) && Dir.pwd != dir
36
- pwd = Dir.pwd
37
- Dir.chdir(dir)
38
- end
39
- ret = Kernel.send(name, *args)
40
- Dir.chdir(pwd) if pwd
31
+ if name != :system
32
+ kwargs.delete(:exception)
41
33
  elsif RUBY_VERSION < '2.6'
42
34
  ex = kwargs.delete(:exception)
43
- ret = Kernel.send(name, *args, **kwargs)
44
- else
45
- return Kernel.send(name, *args, **kwargs)
46
35
  end
47
- raise $?.to_s if !ret && ex
36
+ ret = Kernel.send(name, *args, **kwargs)
37
+ raise $?.to_s if ex && !ret
48
38
 
49
39
  ret
50
40
  end
@@ -86,7 +76,7 @@ module Squared
86
76
  end
87
77
  count = 0
88
78
  soft = 0
89
- type = System.send :parse_link, link
79
+ type = Internal.parse_link(link)
90
80
  subdir.each do |dir, files|
91
81
  unless type == 0
92
82
  items = files.dup
@@ -133,7 +123,7 @@ module Squared
133
123
  target.map! { |file| [base + file, dir ? dest + File.basename(file) : dest] }
134
124
  return if !force && (target = target.reject { |to| to[1].exist? }).empty?
135
125
 
136
- type = System.send :parse_link, link
126
+ type = Internal.parse_link(link)
137
127
  target.each do |file, to|
138
128
  case type
139
129
  when 0
@@ -11,11 +11,9 @@ module Squared
11
11
 
12
12
  def env_value(key, default = '', name: @envname, suffix: nil, strict: false)
13
13
  if suffix
14
- if (ret = ENV[[key, name, suffix].compact.join('_')])
15
- return ret
16
- elsif strict
17
- return default
18
- end
14
+ ret = ENV[[key, name, suffix].compact.join('_')]
15
+ return ret if ret
16
+ return default if strict
19
17
  end
20
18
  if name
21
19
  return ret if (ret = ENV["#{key}_#{name}"])
@@ -42,10 +40,10 @@ module Squared
42
40
  return [] if obj.nil?
43
41
 
44
42
  unless obj.is_a?(::Array)
45
- obj = if obj.respond_to?(:to_ary)
46
- obj.to_ary
47
- elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
43
+ obj = if obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
48
44
  val
45
+ elsif obj.respond_to?(:to_ary)
46
+ obj.to_ary
49
47
  else
50
48
  [obj]
51
49
  end
@@ -65,12 +63,18 @@ module Squared
65
63
  ret.each_with_index(&blk)
66
64
  end
67
65
 
68
- def task_invoke(*cmd, args: [], exception: true, warning: true)
69
- cmd.each { |name| Rake::Task[name].invoke(*args) }
70
- rescue => e
71
- raise if exception
66
+ def task_invoke(*cmd, args: [], sync: true, exception: true, warning: true)
67
+ cmd.each do |name|
68
+ if sync
69
+ Rake::Task[name].invoke(*args)
70
+ else
71
+ Rake.application.run_with_threads { Rake::Task[name].invoke(*args) }
72
+ end
73
+ rescue => e
74
+ raise if exception
72
75
 
73
- warn e if warning
76
+ warn e if warning
77
+ end
74
78
  end
75
79
 
76
80
  def task_join(*val)
@@ -206,7 +206,7 @@ module Squared
206
206
 
207
207
  def read_keys(reader, type, file, keys, ext: [type], opts: {})
208
208
  if file && (mime = mimetype(file)) && basepath(file).exist?
209
- raise_error file, mime, hint: 'invalid' unless ext.include?(mime)
209
+ raise message(file, mime, hint: 'invalid') unless ext.include?(mime)
210
210
  else
211
211
  if ext.include?(mime)
212
212
  alt = file
@@ -218,12 +218,8 @@ module Squared
218
218
  file = Dir[alt].first
219
219
  else
220
220
  alt = main
221
- args = { hint: 'no keys' }
222
- end
223
- unless file
224
- args ||= { kind: Errno::ENOENT }
225
- raise_error(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", **args)
226
221
  end
222
+ raise Errno::ENOENT, message(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}") unless file
227
223
  end
228
224
  log&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
229
225
  return puts File.read(file) if keys.last == '*'
@@ -273,11 +269,7 @@ module Squared
273
269
  val = Regexp.escape($!.message)
274
270
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
275
271
  s = "<#{$3 || $2 || $1}>"
276
- if $3
277
- s
278
- else
279
- $2 ? ".#{s}" : "#{s}."
280
- end
272
+ $3 ? s : $2 ? ".#{s}" : "#{s}."
281
273
  end
282
274
  out << [key, stdin? ? JSON.dump(nil) : 'undefined']
283
275
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.7.6'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -29,7 +29,7 @@ module Squared
29
29
  end
30
30
  end
31
31
 
32
- def find(ref = nil, path: nil)
32
+ def find(ref: nil, path: nil)
33
33
  if ref && (ret = kind_project.find { |proj| proj.ref == ref })
34
34
  ret
35
35
  elsif path
@@ -109,7 +109,7 @@ module Squared
109
109
  @kind = Support.hashlist
110
110
  @config = {}
111
111
  @extensions = Set.new
112
- @finalize = Set.new([:__chain__])
112
+ @finalize = Set.new(%i[__chain__ __join__])
113
113
  @envname = env_key(@main).freeze
114
114
  @closed = false
115
115
  @stage = Support.hashlist
@@ -127,6 +127,7 @@ module Squared
127
127
  @theme = common ? __get__(:theme)[:workspace] : {}
128
128
  @chain = Support.hashlist
129
129
  @script = Struct::SessionData.new
130
+ @join = Struct::SessionData.new
130
131
  @events = Struct::SessionData.new
131
132
  @pass = Struct::SessionData.new
132
133
  @banner = Struct::SessionData.new
@@ -226,7 +227,7 @@ module Squared
226
227
  when Symbol
227
228
  @ref = val
228
229
  else
229
- raise TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
230
+ raise TypeError, message('not a group/ref', hint: kind || 'nil') if block_given?
230
231
  end
231
232
  if block_given?
232
233
  instance_eval(&blk)
@@ -237,6 +238,15 @@ module Squared
237
238
  self
238
239
  end
239
240
 
241
+ def join(task, *cmd, invoke: nil, args: [], group: @group, ref: @ref, **kwargs, &blk)
242
+ unless block_given?
243
+ invoke ||= cmd.shift
244
+ args = cmd if (args = Array(args)).empty?
245
+ args.unshift(invoke)
246
+ end
247
+ script_command task.to_sym, args, group, ref, @join, kwargs, &blk
248
+ end
249
+
240
250
  def run(script = nil, group: @group, ref: @ref, on: nil, &blk)
241
251
  script_command :run, script, group, ref, on, &blk
242
252
  end
@@ -386,7 +396,7 @@ module Squared
386
396
  end
387
397
  unless ref.is_a?(Symbol) && (proj = @base.find { |item| item.ref == ref })
388
398
  proj = if !ref.is_a?(Class)
389
- require_project(ref) || Application.find(ref, path: path)
399
+ require_project(ref) || Application.find(ref: ref, path: path)
390
400
  elsif Application.extends(ref)
391
401
  ref
392
402
  end || @kind[name]&.last
@@ -569,10 +579,10 @@ module Squared
569
579
  def task_resolve(obj, key)
570
580
  tasks = []
571
581
  if (base = task_base?(key))
572
- tasks << key if obj.has?(key, baseref)
582
+ tasks << key if obj.has?(key, ref: baseref)
573
583
  elsif (batch = series.batch_get(key))
574
584
  obj.allref do |ref|
575
- next unless obj.has?(key, ref, missing: series.missing?(ref, key)) && (data = batch[ref])
585
+ next unless obj.has?(key, ref: ref, missing: series.missing?(ref, key)) && (data = batch[ref])
576
586
 
577
587
  data.each do |val|
578
588
  if (items = task_resolve(obj, val)).empty?
@@ -591,7 +601,7 @@ module Squared
591
601
  return [] if (base && !obj.ref?(baseref)) || !(data = series.alias_get(key))
592
602
 
593
603
  obj.allref do |ref|
594
- next unless obj.has?(key, ref) && (alt = data[ref])
604
+ next unless obj.has?(key, ref: ref) && (alt = data[ref])
595
605
 
596
606
  ret = task_resolve obj, alt
597
607
  break unless ret.empty?
@@ -663,11 +673,7 @@ module Squared
663
673
  if group && @banner.group.key?(group = group.to_sym)
664
674
  @banner.group[group]
665
675
  else
666
- ref.reverse_each do |val|
667
- next unless @banner.ref.key?(val)
668
-
669
- return @banner.ref[val]
670
- end
676
+ ref.reverse_each { |val| return @banner.ref[val] if @banner.ref.key?(val) }
671
677
  @banner.ref[:_] if @banner.ref.key?(:_)
672
678
  end
673
679
  end
@@ -695,10 +701,10 @@ module Squared
695
701
  series.extend?(obj, key)
696
702
  end
697
703
 
698
- def task_include?(obj, key, ref = nil)
704
+ def task_include?(obj, key, ref: nil)
699
705
  return false if series.exclude?(key)
700
706
 
701
- task_base?(key) ? obj.has?(key, ref || baseref) : task_extend?(obj, key)
707
+ task_base?(key) ? obj.has?(key, ref: ref || baseref) : task_extend?(obj, key)
702
708
  end
703
709
 
704
710
  def task_exclude?(key, obj = nil)
@@ -736,14 +742,6 @@ module Squared
736
742
  RUBY_ENGINE == 'ruby'
737
743
  end
738
744
 
739
- def jruby?
740
- RUBY_ENGINE == 'jruby'
741
- end
742
-
743
- def truffleruby?
744
- RUBY_ENGINE == 'truffleruby'
745
- end
746
-
747
745
  def docker?
748
746
  !Dir['/.dockerenv', '/docker-*.{sh,d}'].empty?
749
747
  end
@@ -777,7 +775,7 @@ module Squared
777
775
  end
778
776
 
779
777
  def invokeargs
780
- { exception: exception, warning: warning }
778
+ { exception: exception?, warning: warning }
781
779
  end
782
780
 
783
781
  def size
@@ -946,14 +944,75 @@ module Squared
946
944
  self.closed = 'chain:end'
947
945
  end
948
946
 
947
+ def __join__(*)
948
+ group = @join.group
949
+ ref = @join.ref
950
+ return if group.empty? && ref.empty?
951
+
952
+ self.closed = 'join:begin'
953
+ [group, ref].each do |with|
954
+ with.each do |target, data|
955
+ items = if with == group
956
+ target = target.to_s
957
+ store = @join.store[:group]
958
+ select { |proj| proj.group == target }
959
+ else
960
+ store = @join.store[:ref]
961
+ select { |proj| proj.ref == target }
962
+ end.sort
963
+ next if items.empty?
964
+
965
+ data.each do |name, args|
966
+ key = task_name(task_join(name, target))
967
+ sync = true
968
+ exception = exception?
969
+ if store && (kwargs = store["#{target}:#{name}"])
970
+ sync = kwargs[:sync] if kwargs.key?(:sync)
971
+ exception = kwargs[:exception] if kwargs.key?(:exception)
972
+ end
973
+ case args
974
+ when Struct
975
+ format_desc key
976
+ task key do
977
+ items.each do |proj|
978
+ if sync
979
+ proj.instance_eval(&args.block)
980
+ else
981
+ Rake.application.run_with_threads { proj.instance_eval(&args.block) }
982
+ end
983
+ rescue => e
984
+ raise if exception
985
+
986
+ warn log_message(Logger::ERROR, e, subject: proj.name, hint: key)
987
+ end
988
+ end
989
+ when Array
990
+ cmd = args.first
991
+ cmd = items.map { |proj| "#{proj.name}:#{cmd}" }
992
+ .select { |val| task_defined?(val) }
993
+ next if cmd.empty?
994
+
995
+ args = args.drop(1)
996
+ format_desc(args.empty? ? key : "#{key}[#{args.join(',')}]")
997
+ task key do
998
+ opts = ENV["#{target.upcase}_ARGS"]
999
+ task_invoke(*cmd, args: opts ? split_escape(opts) : args, sync: sync, exception: exception)
1000
+ end
1001
+ end
1002
+ end
1003
+ end
1004
+ end
1005
+ self.closed = 'join:end'
1006
+ end
1007
+
949
1008
  def puts(*args, **kwargs)
950
1009
  log_console(*args, pipe: kwargs[:pipe] || pipe)
951
1010
  end
952
1011
 
953
- def script_command(task, val, group, ref, on = nil, &blk)
1012
+ def script_command(task, val, group, ref, on = nil, store = nil, &blk)
954
1013
  if block_given?
955
1014
  val = Struct::RunData.new(val, blk)
956
- elsif !val
1015
+ elsif !val || (val.is_a?(Array) && val.empty?)
957
1016
  return self
958
1017
  end
959
1018
  if group
@@ -963,8 +1022,15 @@ module Squared
963
1022
  label = :ref
964
1023
  as_a(ref || :_, :to_sym)
965
1024
  end.each do |name|
966
- @script[label][name][task] = val
967
- @events[label][name][task] = on if on.is_a?(Hash)
1025
+ data = @script
1026
+ case on
1027
+ when Struct
1028
+ data = on
1029
+ when Hash
1030
+ @events[label][name][task] = on
1031
+ end
1032
+ data[label][name][task] = val
1033
+ (data.store[label] ||= {})["#{name}:#{task}"] = store if store
968
1034
  end
969
1035
  self
970
1036
  end
@@ -1002,8 +1068,8 @@ module Squared
1002
1068
  end
1003
1069
 
1004
1070
  def data_get(*args, target:, group: nil, ref: nil)
1005
- if group && target[:group].key?(key = group.to_sym)
1006
- target[:group][key]
1071
+ if group && target[:group].key?(g = group.to_sym)
1072
+ target[:group][g]
1007
1073
  elsif ref.is_a?(Enumerable)
1008
1074
  ref.each do |key|
1009
1075
  next unless target[:ref].key?(key)
@@ -1057,6 +1123,10 @@ module Squared
1057
1123
  target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
1058
1124
  end
1059
1125
 
1126
+ def exception?
1127
+ exception != false && exception != Logger::INFO
1128
+ end
1129
+
1060
1130
  def banner_include?(val)
1061
1131
  Application.attr_banner.include?(val) || @banner.items.include?(val)
1062
1132
  end