squared 0.0.6 → 0.0.7

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.
@@ -36,7 +36,7 @@ module Squared
36
36
 
37
37
  def find(path: nil, ref: nil)
38
38
  if ref.is_a?(::Symbol) || ref.is_a?(::String)
39
- ret = project_kind.find { |proj| proj.to_sym == ref.to_sym }
39
+ ret = project_kind.find { |proj| proj.ref == ref.to_sym }
40
40
  return ret if ret
41
41
  end
42
42
  project_kind.find { |proj| proj.is_a?(path) } if path
@@ -51,14 +51,14 @@ module Squared
51
51
 
52
52
  @project_kind = []
53
53
 
54
- attr_reader :main, :root, :home, :series, :theme, :warning
55
- attr_accessor :exception, :pipe, :verbose
54
+ attr_reader :main, :root, :home, :series, :theme
55
+ attr_accessor :exception, :warning, :pipe, :verbose
56
56
 
57
- def initialize(main, *, common: true, exception: false, pipe: false, verbose: nil, **)
57
+ def initialize(main, *, exception: false, pipe: false, verbose: nil, **kwargs)
58
58
  @main = main.to_s
59
59
  @home = Pathname.pwd
60
60
  @root = @home.parent
61
- @series = Series.new(TASK_BASE, self)
61
+ @series = Series.new(TASK_BASE)
62
62
  @project = {}
63
63
  @extensions = []
64
64
  @script = {
@@ -68,11 +68,12 @@ module Squared
68
68
  dev: nil,
69
69
  prod: nil
70
70
  }
71
- @theme = common && @verbose ? __get__(:theme)[:workspace] : {}
71
+ @theme = kwargs.key?(:common) && !kwargs[:common] ? {} : __get__(:theme)[:workspace]
72
72
  @exception = exception.is_a?(String) ? !env(exception, ignore: '0').nil? : exception
73
73
  @pipe = pipe.is_a?(String) ? !env(pipe, ignore: '0').nil? : pipe
74
74
  @verbose = verbose.nil? ? !@pipe : verbose
75
- @warning = true
75
+ @warning = @verbose
76
+ __set__(:no_color, true) if @pipe
76
77
  end
77
78
 
78
79
  def build(**kwargs)
@@ -81,82 +82,84 @@ module Squared
81
82
  @project.each_value do |proj|
82
83
  next unless proj.enabled?
83
84
 
84
- series.populate(proj)
85
85
  proj.populate(**kwargs)
86
+ series.populate(proj)
86
87
  end
87
88
 
88
89
  Application.project_kind.each { |obj| obj.populate(self, **kwargs) }
89
90
  @extensions.each { |ext| __send__(ext, **kwargs) }
90
91
 
91
- series[:refresh].clear if series[:refresh].all? { |val| val.end_with?(':build') }
92
-
93
- task default: kwargs[:default] if series.has?(kwargs[:default]) && !task_defined?('default')
94
-
95
- if series.has?('build')
96
- init = ['depend', dev? && series.has?('refresh') ? 'refresh' : 'build']
92
+ __build__(**kwargs)
93
+ series.build(**kwargs)
97
94
 
98
- task default: init[1] unless task_defined?('default')
95
+ yield self if block_given?
96
+ end
99
97
 
100
- if series.has?(init[0]) && !task_defined?('init')
101
- desc 'init'
102
- task init: init
103
- end
98
+ def with(group: nil, ref: nil)
99
+ @group = nil
100
+ @ref = nil
101
+ if group
102
+ @group = group
103
+ elsif ref
104
+ @ref = ref
104
105
  end
105
- series.finalize!(kwargs.fetch(:parallel, []))
106
-
107
- yield self if block_given?
106
+ self
108
107
  end
109
108
 
110
- def run(script, group: nil, ref: nil)
109
+ def run(script, group: @group, ref: @ref)
111
110
  script_command :run, script, group, ref
112
111
  end
113
112
 
114
- def depend(script, group: nil, ref: nil)
113
+ def depend(script, group: @group, ref: @ref)
115
114
  script_command :depend, script, group, ref
116
115
  end
117
116
 
118
- def clean(script, group: nil, ref: nil)
117
+ def clean(script, group: @group, ref: @ref)
119
118
  script_command :clean, script, group, ref
120
119
  end
121
120
 
122
- def doc(script, group: nil, ref: nil)
121
+ def doc(script, group: @group, ref: @ref)
123
122
  script_command :doc, script, group, ref
124
123
  end
125
124
 
126
- def test(script, group: nil, ref: nil)
125
+ def test(script, group: @group, ref: @ref)
127
126
  script_command :test, script, group, ref
128
127
  end
129
128
 
130
- def add(name, path = nil, ref: nil, **kwargs)
131
- path = root_path((path || name).to_s)
132
- project = if !ref.is_a?(::Class)
133
- Application.find(path: path, ref: ref)
134
- elsif ref < Project::Base
135
- ref
136
- end
137
- instance = (project || Project::Base).new(name, path, self, **kwargs)
138
- @project[n = name.to_sym] = instance
139
- __get__(:project)[n] = instance unless kwargs[:private]
129
+ def add(name, path = nil, **kwargs)
130
+ ref = if kwargs.key?(:ref)
131
+ kwargs.delete(:ref)
132
+ elsif !@ref.is_a?(::Array)
133
+ @ref
134
+ end
135
+ kwargs[:group] = @group if !kwargs.key?(:group) && !@group.is_a?(::Array)
136
+ path = root_path(path || name.to_s)
137
+ proj = ((if !ref.is_a?(::Class)
138
+ Application.find(path: path, ref: ref)
139
+ elsif ref < Project::Base
140
+ ref
141
+ end) || Project::Base).new(name, path, self, **kwargs)
142
+ @project[name = name.to_sym] = proj
143
+ __get__(:project)[name] = proj unless kwargs[:private]
140
144
  self
141
145
  end
142
146
 
143
- def group(name, path, **kwargs)
147
+ def group(name, path, override: {}, **kwargs)
144
148
  root_path(path).children.map do |ent|
145
149
  next unless (dir = Pathname.new(ent)).directory?
146
150
 
147
151
  index = 0
148
152
  basename = dir.basename.to_s.to_sym
149
- override = kwargs.delete(basename)
150
153
  while @project[basename]
151
154
  index += 1
152
155
  basename = :"#{basename}-#{index}"
153
156
  end
154
- [basename, dir, override]
157
+ [basename, dir, override[basename]]
155
158
  end
156
- .each do |basename, dir, override|
157
- opts = kwargs.dup
158
- opts.merge!(override) if override
159
- add(basename, dir, group: name, **opts)
159
+ .each do |basename, dir, opts|
160
+ args = kwargs.dup
161
+ args.merge!(opts) if opts
162
+ add(basename, dir, group: name, **args)
160
163
  end
161
164
  self
162
165
  end
@@ -188,15 +191,17 @@ module Squared
188
191
  end
189
192
 
190
193
  def script(group: nil, ref: nil)
191
- if group || ref
192
- (group && @script[:group][group.to_sym]) || (ref && @script[:ref][ref.to_sym])
194
+ if group
195
+ @script[:group][group.to_sym]
196
+ elsif ref
197
+ @script[:ref][ref.to_sym]
193
198
  else
194
199
  @script[:build]
195
200
  end
196
201
  end
197
202
 
198
- def env(key, equals: nil, ignore: nil, default: nil)
199
- ret = ENV.fetch("#{key}_#{main.gsub(/[^\w]/, '_').upcase}", ENV[key]).to_s
203
+ def env(key, default = nil, equals: nil, ignore: nil)
204
+ ret = ENV.fetch("#{key}_#{main.gsub(/[^\w]+/, '_').upcase}", ENV[key]).to_s
200
205
  return ret == equals.to_s unless equals.nil?
201
206
 
202
207
  ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
@@ -240,47 +245,36 @@ module Squared
240
245
  ::Rake::Task.task_defined?(key)
241
246
  end
242
247
 
243
- def dev?(script: nil, pat: nil, global: nil)
244
- with?(:dev, script: script, pat: pat, global: global || (pat.nil? && global.nil?))
248
+ def dev?(global: nil, **kwargs)
249
+ script?(:dev, global: global.nil? ? kwargs[:pat].nil? : global, **kwargs)
245
250
  end
246
251
 
247
- def prod?(script: nil, pat: nil, global: false)
252
+ def prod?(global: false, **kwargs)
248
253
  return false if global && (@script[:dev] == true || !@script[:prod])
249
254
 
250
- with?(:prod, script: script, pat: pat, global: global)
255
+ script?(:prod, global: global, **kwargs)
251
256
  end
252
257
 
253
- protected
254
-
255
- def confirm(msg, agree: 'Y', cancel: 'N', default: nil, attempts: 5, timeout: 15)
256
- require 'readline'
257
- require 'timeout'
258
- agree = /^#{agree}$/i if agree.is_a?(String)
259
- cancel = /^#{cancel}$/i if cancel.is_a?(String)
260
- Timeout.timeout(timeout) do
261
- begin
262
- while (ch = Readline.readline(msg, true))
263
- ch = ch.chomp
264
- ch = default if ch.empty?
265
- case ch
266
- when agree
267
- return true
268
- when cancel
269
- return false
270
- end
271
- attempts -= 1
272
- exit 1 unless attempts >= 0
273
- end
274
- rescue Interrupt
275
- puts
276
- exit 0
277
- else
278
- false
279
- end
258
+ private
259
+
260
+ def __build__(**kwargs)
261
+ if !task_defined?('default') && (default = kwargs[:default]) && !series.has?(default)
262
+ task default: default
280
263
  end
281
- end
264
+ return unless series.has?('build')
282
265
 
283
- private
266
+ if (refresh = series[:refresh]).all? { |val| val.end_with?(':build') }
267
+ refresh.clear
268
+ end
269
+ init = ['depend', dev? && series.has?('refresh') ? 'refresh' : 'build']
270
+
271
+ task default: init[1] unless task_defined?('default')
272
+
273
+ return if task_defined?('init') || !series.has?(init[0])
274
+
275
+ desc 'init'
276
+ task init: init
277
+ end
284
278
 
285
279
  def script_command(task, val, group, ref)
286
280
  if group
@@ -294,8 +288,10 @@ module Squared
294
288
  self
295
289
  end
296
290
 
297
- def with?(state, script: nil, pat: nil, global: false)
298
- if global
291
+ def script?(state, script: nil, pat: nil, ref: nil, group: nil, global: false)
292
+ gr = @script[:ref][:_]
293
+ gg = @script[:group][:_]
294
+ if global && ((!ref && !group) || (!gr && !gg) || (ref && ref == gr) || (group && group == gg))
299
295
  pat = @script[state] if pat.nil?
300
296
  script ||= @script[:build]
301
297
  end
@@ -13,12 +13,9 @@ module Squared
13
13
  include Task
14
14
  include ::Rake::DSL
15
15
 
16
- SEM_VER = /^(\d+)(\.)(\d+)(?:(\.)(\d+))?$/.freeze
16
+ SEM_VER = /(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?/.freeze
17
17
 
18
18
  class << self
19
- include Common::Task
20
- include ::Rake::DSL
21
-
22
19
  def populate(*); end
23
20
 
24
21
  def tasks
@@ -34,24 +31,24 @@ module Squared
34
31
  end
35
32
  end
36
33
 
37
- def to_s
38
- super.to_s.match(/[^:]+$/)[0]
34
+ def ref
35
+ @ref ||= to_s.downcase.to_sym
39
36
  end
40
37
 
41
- def to_sym
42
- to_s.downcase.to_sym
38
+ def to_s
39
+ super.to_s.match(/[^:]+$/)[0]
43
40
  end
44
41
  end
45
42
 
46
43
  @@print_order = 0
47
44
  @@tasks = {}
48
45
 
49
- attr_reader :name, :project, :workspace, :group, :path, :log, :theme
46
+ attr_reader :name, :project, :workspace, :group, :path, :theme
50
47
  attr_accessor :warning
51
48
 
52
- def initialize(name, path, workspace, *, group: nil, log: nil, common: true, **kwargs)
49
+ def initialize(name, path, workspace, *, group: nil, **kwargs)
53
50
  @name = name.to_s
54
- @path = workspace.root_path(path.to_s)
51
+ @path = path
55
52
  @project = @path.basename.to_s
56
53
  @workspace = workspace
57
54
  @group = group&.to_s
@@ -61,40 +58,50 @@ module Squared
61
58
  @output = [kwargs[:run], nil]
62
59
  @copy = kwargs[:copy]
63
60
  @clean = kwargs[:clean]
61
+ @exclude = as_a(kwargs[:exclude])
64
62
  @warning = workspace.warning
65
63
  @theme = if !workspace.verbose
66
64
  {}
67
- elsif common
65
+ elsif kwargs.fetch(:common, true)
68
66
  workspace.theme
69
67
  else
70
68
  __get__(:theme)[:project][to_sym] ||= {}
71
69
  end
72
- log = { file: log } unless log.is_a?(::Hash)
73
- if (logfile = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
74
- logfile = case auto
75
- when 'y', 'year'
76
- "#{@name}-#{Date.today.year}.log"
77
- when 'm', 'month'
78
- "#{@name}-#{Date.today.strftime('%Y-%m')}.log"
79
- when 'd', 'day', '1'
80
- "#{@name}-#{Date.today}.log"
81
- end
70
+ initialize_logger(**kwargs)
71
+ end
72
+
73
+ def initialize_logger(log: nil, **)
74
+ log = log.is_a?(::Hash) ? log.dup : { file: log }
75
+ if (file = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
76
+ file = case auto
77
+ when 'y', 'year'
78
+ "#{@name}-#{Date.today.year}.log"
79
+ when 'm', 'month'
80
+ "#{@name}-#{Date.today.strftime('%Y-%m')}.log"
81
+ when 'd', 'day', '1'
82
+ "#{@name}-#{Date.today}.log"
83
+ end
82
84
  end
83
- if logfile ||= log[:file]
84
- logfile = Date.today.strftime(logfile)
85
- logfile = (dir = env('LOG_DIR')) ? Pathname.new(dir).join(logfile) : Pathname.new(logfile)
85
+ if file ||= log[:file]
86
+ file = Date.today.strftime(file)
87
+ file = (dir = env('LOG_DIR')) ? Pathname.new(dir).join(file) : Pathname.new(file)
86
88
  begin
87
- logfile.realdirpath
89
+ file = file.realdirpath
88
90
  rescue StandardError => e
89
- logfile = nil
91
+ raise if @workspace.exception
92
+
93
+ file = nil
90
94
  warn e if @warning
91
95
  end
92
96
  end
93
- @log = Logger.new(logfile, progname: @name, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
97
+ log[:progname] = @name
98
+ log[:level] = env('LOG_LEVEL', log[:level] || Logger::INFO, ignore: nil)
99
+ log.delete(:file)
100
+ @log = [file, log]
94
101
  end
95
102
 
96
103
  def initialize_build(ref, **kwargs)
97
- initialize_script(ref)
104
+ initialize_script(ref, **kwargs)
98
105
  if (val = env('BUILD', strict: true))
99
106
  @output[0] = val
100
107
  elsif @script && @output[0] != false
@@ -106,11 +113,11 @@ module Squared
106
113
  elsif env('BUILD', suffix: 'DEV')
107
114
  @dev = true
108
115
  elsif @dev.nil?
109
- @dev = workspace.dev?
116
+ @dev = !group.nil? && workspace.dev?(group: group, global: true)
110
117
  end
111
118
  end
112
119
 
113
- def initialize_script(ref)
120
+ def initialize_script(ref, **)
114
121
  return unless (script = workspace.script(group: group, ref: ref))
115
122
 
116
123
  @depend = script[:depend] if @depend.nil?
@@ -121,6 +128,8 @@ module Squared
121
128
  end
122
129
 
123
130
  def populate(*)
131
+ return if @exclude.include?(Base.ref)
132
+
124
133
  namespace name do
125
134
  workspace.series.each_key do |key|
126
135
  next unless Application::WORKSPACE_KEYS.include?(key) ? has?(key) : workspace.task_include?(self, key)
@@ -154,7 +163,7 @@ module Squared
154
163
  cmd = compose(opts)
155
164
  banner = env('REPO_BUILD') == 'verbose'
156
165
  end
157
- run(cmd, exception: workspace.exception, banner: banner, sync: sync)
166
+ run(cmd, banner: banner, sync: sync)
158
167
  end
159
168
 
160
169
  def refresh(*)
@@ -168,11 +177,11 @@ module Squared
168
177
  end
169
178
 
170
179
  def depend(*)
171
- run(@depend, exception: workspace.exception, sync: invoked_sync?('depend')) if @depend
180
+ run(@depend, sync: invoked_sync?('depend')) if @depend
172
181
  end
173
182
 
174
183
  def copy(*)
175
- run_s(@copy, sync: invoked_sync?('copy'))
184
+ run_s(@copy, sync: invoked_sync?('copy')) if @copy
176
185
  end
177
186
 
178
187
  def doc
@@ -212,6 +221,12 @@ module Squared
212
221
  end
213
222
  end
214
223
 
224
+ def log
225
+ return @log unless @log.is_a?(::Array)
226
+
227
+ @log = Logger.new(enabled? ? @log[0] : nil, **@log[1])
228
+ end
229
+
215
230
  def base_path(*args)
216
231
  path.join(*args)
217
232
  end
@@ -245,7 +260,7 @@ module Squared
245
260
  end
246
261
 
247
262
  def depend?
248
- !!@depend
263
+ @depend != false && (!@depend.nil? || has?('outdated'))
249
264
  end
250
265
 
251
266
  def doc?
@@ -264,16 +279,25 @@ module Squared
264
279
  !!@clean
265
280
  end
266
281
 
282
+ def dev?
283
+ !!@dev
284
+ end
285
+
267
286
  protected
268
287
 
269
- def run(cmd = @session, exception: false, banner: true, sync: true, req: nil)
288
+ def run(cmd = @session, exception: workspace.exception, banner: true, sync: true, req: nil, **)
270
289
  return if req && !base_path(req).exist?
271
290
 
272
291
  cmd = close_session(cmd)
273
292
  log.info cmd
274
- print_item format_banner(cmd, banner: banner) if sync
275
293
  begin
276
- shell(cmd, chdir: path, exception: exception)
294
+ if cmd =~ /^\S+:(\S+:?)+$/ && workspace.task_defined?(cmd)
295
+ print_item if sync
296
+ invoke(cmd, exception: exception)
297
+ else
298
+ print_item format_banner(cmd, banner: banner) if sync
299
+ shell(cmd, chdir: path, exception: exception)
300
+ end
277
301
  rescue StandardError => e
278
302
  log.error e
279
303
  raise
@@ -281,11 +305,11 @@ module Squared
281
305
  end
282
306
 
283
307
  def run_s(cmd, **kwargs)
284
- run(cmd, exception: workspace.exception, banner: verbose?, **kwargs) if cmd.is_a?(::String)
308
+ run(cmd, banner: verbose?, **kwargs) if cmd.is_a?(::String)
285
309
  end
286
310
 
287
- def env(key, equals: nil, ignore: ['0'].freeze, default: nil, suffix: nil, strict: false)
288
- a = "#{key}_#{name.upcase}"
311
+ def env(key, default = nil, equals: nil, ignore: ['0'].freeze, suffix: nil, strict: false)
312
+ a = "#{key}_#{name.gsub(/[^\w]+/, '_').upcase}"
289
313
  b = ''
290
314
  if suffix
291
315
  a = [a, suffix].flatten.join('_')
@@ -328,7 +352,7 @@ module Squared
328
352
  styles = [:bold] + styles
329
353
  end
330
354
  end
331
- n = max_width(lines)
355
+ n = Project.max_width(lines)
332
356
  ch = ' ' * pad
333
357
  index = -1
334
358
  out = lines.map do |val|
@@ -344,15 +368,17 @@ module Squared
344
368
  out.join("\n")
345
369
  end
346
370
 
347
- def print_footer(*lines, sub: nil, border: theme[:border])
348
- n = max_width(lines)
371
+ def print_footer(*lines, sub: nil, border: theme[:border], reverse: false)
372
+ n = Project.max_width(lines)
349
373
  sub = as_a(sub)
350
374
  lines.map! do |val|
351
375
  s = val.ljust(n)
352
376
  sub.each { |h| s = sub_style(s, **h) }
353
377
  s
354
378
  end
355
- [sub_style('-' * n, styles: border), *lines].join("\n")
379
+ ret = [sub_style('-' * n, styles: border), *lines]
380
+ ret.reverse! if reverse
381
+ ret.join("\n")
356
382
  end
357
383
 
358
384
  def format_desc(action, flag, opts = nil, req: 'opts*')
@@ -374,8 +400,8 @@ module Squared
374
400
  end
375
401
  end
376
402
 
377
- def empty_status(msg, title, obj)
378
- "#{msg}#{!obj || obj == 0 || obj.to_s.empty? ? '' : message(hint: message(title, obj.to_s))}"
403
+ def empty_status(msg, title, obj, always: false)
404
+ "#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
379
405
  end
380
406
 
381
407
  def append_nocolor
@@ -394,10 +420,33 @@ module Squared
394
420
  @session = nil
395
421
  raise_error(action, "#{flag}[]", hint: 'empty')
396
422
  end
397
- return unless action.to_s.empty?
423
+ end
398
424
 
399
- @session = nil
400
- raise_error('parameter', flag, hint: 'missing')
425
+ def store_pwd(done = nil)
426
+ if @pwd
427
+ Dir.chdir(@pwd)
428
+ @pwd = nil
429
+ elsif !done && Dir.pwd != path.to_s
430
+ @pwd = Dir.pwd
431
+ Dir.chdir(path)
432
+ @pwd
433
+ end
434
+ end
435
+
436
+ def semver(val)
437
+ unless val[3]
438
+ val[3] = '.'
439
+ val[4] = '0'
440
+ end
441
+ unless val[1]
442
+ val[1] = '.'
443
+ val[2] = '0'
444
+ end
445
+ val
446
+ end
447
+
448
+ def semmajor(cur, want)
449
+ cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]
401
450
  end
402
451
 
403
452
  def verbose?
@@ -423,17 +472,11 @@ module Squared
423
472
  return ret unless ret.nil?
424
473
  end
425
474
  if (base = workspace.find_base(self))
426
- ret = check.("#{action}:#{base.to_sym}")
475
+ ret = check.("#{action}:#{base.ref}")
427
476
  return ret unless ret.nil?
428
477
  end
429
478
  invoked?("#{name}:#{action}") && (!invoked?(action) || !workspace.task_defined?("#{action}:sync"))
430
479
  end
431
-
432
- private
433
-
434
- def max_width(lines)
435
- [lines.max_by(&:size).size, Project.line_width].max
436
- end
437
480
  end
438
481
  end
439
482
  end