squared 0.0.4 → 0.0.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.
- checksums.yaml +4 -4
- data/README.ruby.md +26 -3
- data/lib/squared/common/base.rb +91 -0
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +16 -9
- data/lib/squared/common/shell.rb +9 -9
- data/lib/squared/common/system.rb +4 -1
- data/lib/squared/common/task.rb +6 -2
- data/lib/squared/common.rb +1 -78
- data/lib/squared/config.rb +10 -10
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +306 -0
- data/lib/squared/{repo → workspace}/project/base.rb +86 -86
- data/lib/squared/{repo → workspace}/project/git.rb +98 -80
- data/lib/squared/{repo → workspace}/project/node.rb +22 -26
- data/lib/squared/workspace/project/python.rb +150 -0
- data/lib/squared/{repo → workspace}/project/ruby.rb +33 -28
- data/lib/squared/{repo → workspace}/project.rb +1 -1
- data/lib/squared/workspace/repo.rb +201 -0
- data/lib/squared/workspace/series.rb +125 -0
- data/lib/squared/{repo.rb → workspace.rb} +6 -3
- data/lib/squared.rb +9 -8
- metadata +13 -10
- data/lib/squared/repo/project/python.rb +0 -123
- data/lib/squared/repo/workspace.rb +0 -501
@@ -0,0 +1,306 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Workspace
|
5
|
+
class Application
|
6
|
+
include Common
|
7
|
+
include Format
|
8
|
+
include ::Rake::DSL
|
9
|
+
|
10
|
+
TASK_BASE = {
|
11
|
+
build: [],
|
12
|
+
refresh: [],
|
13
|
+
depend: [],
|
14
|
+
outdated: [],
|
15
|
+
doc: [],
|
16
|
+
test: [],
|
17
|
+
copy: [],
|
18
|
+
clean: []
|
19
|
+
}
|
20
|
+
TASK_EXTEND = {}
|
21
|
+
WORKSPACE_KEYS = TASK_BASE.keys.freeze
|
22
|
+
private_constant :TASK_BASE, :TASK_EXTEND
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def implement(*objs)
|
26
|
+
objs.each do |obj|
|
27
|
+
next unless obj < Project::Base
|
28
|
+
|
29
|
+
project_kind.unshift(obj)
|
30
|
+
obj.tasks&.each do |val|
|
31
|
+
TASK_BASE[val] ||= []
|
32
|
+
(TASK_EXTEND[val] ||= []).push(obj)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def find(path: nil, ref: nil)
|
38
|
+
if ref.is_a?(::Symbol) || ref.is_a?(::String)
|
39
|
+
ret = project_kind.find { |proj| proj.to_sym == ref.to_sym }
|
40
|
+
return ret if ret
|
41
|
+
end
|
42
|
+
project_kind.find { |proj| proj.is_a?(path) } if path
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
super.to_s.match(/[^:]+$/)[0]
|
47
|
+
end
|
48
|
+
|
49
|
+
attr_reader :project_kind
|
50
|
+
end
|
51
|
+
|
52
|
+
@project_kind = []
|
53
|
+
|
54
|
+
attr_reader :main, :root, :home, :series, :theme, :warning
|
55
|
+
attr_accessor :exception, :pipe, :verbose
|
56
|
+
|
57
|
+
def initialize(main, *, common: true, exception: false, pipe: false, verbose: nil, **)
|
58
|
+
@main = main.to_s
|
59
|
+
@home = Pathname.pwd
|
60
|
+
@root = @home.parent
|
61
|
+
@series = Series.new(TASK_BASE, self)
|
62
|
+
@project = {}
|
63
|
+
@extensions = []
|
64
|
+
@script = {
|
65
|
+
group: {},
|
66
|
+
ref: {},
|
67
|
+
build: nil,
|
68
|
+
dev: nil,
|
69
|
+
prod: nil
|
70
|
+
}
|
71
|
+
@theme = common && @verbose ? __get__(:theme)[:workspace] : {}
|
72
|
+
@exception = exception.is_a?(String) ? !env(exception, ignore: '0').nil? : exception
|
73
|
+
@pipe = pipe.is_a?(String) ? !env(pipe, ignore: '0').nil? : pipe
|
74
|
+
@verbose = verbose.nil? ? !@pipe : verbose
|
75
|
+
@warning = true
|
76
|
+
end
|
77
|
+
|
78
|
+
def build(**kwargs)
|
79
|
+
return unless enabled?
|
80
|
+
|
81
|
+
@project.each_value do |proj|
|
82
|
+
next unless proj.enabled?
|
83
|
+
|
84
|
+
series.populate(proj)
|
85
|
+
proj.populate(**kwargs)
|
86
|
+
end
|
87
|
+
|
88
|
+
Application.project_kind.each { |obj| obj.populate(self, **kwargs) }
|
89
|
+
@extensions.each { |ext| __send__(ext, **kwargs) }
|
90
|
+
|
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']
|
97
|
+
|
98
|
+
task default: init[1] unless task_defined?('default')
|
99
|
+
|
100
|
+
if series.has?(init[0]) && !task_defined?('init')
|
101
|
+
desc 'init'
|
102
|
+
task init: init
|
103
|
+
end
|
104
|
+
end
|
105
|
+
series.finalize!(kwargs.fetch(:parallel, []))
|
106
|
+
|
107
|
+
yield self if block_given?
|
108
|
+
end
|
109
|
+
|
110
|
+
def run(script, group: nil, ref: nil)
|
111
|
+
script_command :run, script, group, ref
|
112
|
+
end
|
113
|
+
|
114
|
+
def depend(script, group: nil, ref: nil)
|
115
|
+
script_command :depend, script, group, ref
|
116
|
+
end
|
117
|
+
|
118
|
+
def clean(script, group: nil, ref: nil)
|
119
|
+
script_command :clean, script, group, ref
|
120
|
+
end
|
121
|
+
|
122
|
+
def doc(script, group: nil, ref: nil)
|
123
|
+
script_command :doc, script, group, ref
|
124
|
+
end
|
125
|
+
|
126
|
+
def test(script, group: nil, ref: nil)
|
127
|
+
script_command :test, script, group, ref
|
128
|
+
end
|
129
|
+
|
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]
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
def group(name, path, **kwargs)
|
144
|
+
root_path(path).children.map do |ent|
|
145
|
+
next unless (dir = Pathname.new(ent)).directory?
|
146
|
+
|
147
|
+
index = 0
|
148
|
+
basename = dir.basename.to_s.to_sym
|
149
|
+
override = kwargs.delete(basename)
|
150
|
+
while @project[basename]
|
151
|
+
index += 1
|
152
|
+
basename = :"#{basename}-#{index}"
|
153
|
+
end
|
154
|
+
[basename, dir, override]
|
155
|
+
end
|
156
|
+
.each do |basename, dir, override|
|
157
|
+
opts = kwargs.dup
|
158
|
+
opts.merge!(override) if override
|
159
|
+
add(basename, dir, group: name, **opts)
|
160
|
+
end
|
161
|
+
self
|
162
|
+
end
|
163
|
+
|
164
|
+
def compose(name, &blk)
|
165
|
+
namespace(name, &blk)
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
def apply(&blk)
|
170
|
+
instance_eval(&blk)
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
def style(name, *args, target: nil, empty: false)
|
175
|
+
data = nil
|
176
|
+
if target
|
177
|
+
as_a(target).each_with_index do |val, i|
|
178
|
+
if i == 0
|
179
|
+
break unless (data = __get__(:theme)[val.to_sym])
|
180
|
+
else
|
181
|
+
data = data[val.to_sym] ||= {}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
return unless data
|
185
|
+
end
|
186
|
+
apply_style(data || theme, name, *args, empty: empty)
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
def script(group: nil, ref: nil)
|
191
|
+
if group || ref
|
192
|
+
(group && @script[:group][group.to_sym]) || (ref && @script[:ref][ref.to_sym])
|
193
|
+
else
|
194
|
+
@script[:build]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def env(key, equals: nil, ignore: nil, default: nil)
|
199
|
+
ret = ENV.fetch("#{key}_#{main.gsub(/[^\w]/, '_').upcase}", ENV[key]).to_s
|
200
|
+
return ret == equals.to_s unless equals.nil?
|
201
|
+
|
202
|
+
ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
|
203
|
+
end
|
204
|
+
|
205
|
+
def root_path(*args)
|
206
|
+
root.join(*args)
|
207
|
+
end
|
208
|
+
|
209
|
+
def home_path(*args)
|
210
|
+
home.join(*args)
|
211
|
+
end
|
212
|
+
|
213
|
+
def find_base(obj)
|
214
|
+
Application.project_kind.find { |proj| obj.instance_of?(proj) }
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_s
|
218
|
+
root.to_s
|
219
|
+
end
|
220
|
+
|
221
|
+
def inspect
|
222
|
+
"#<#{self.class}: #{main} => #{self}>"
|
223
|
+
end
|
224
|
+
|
225
|
+
def enabled?
|
226
|
+
!@extensions.empty? || @project.any? { |_, proj| proj.enabled? }
|
227
|
+
end
|
228
|
+
|
229
|
+
def task_base?(key, val)
|
230
|
+
return val if task_defined?(key)
|
231
|
+
|
232
|
+
val if key == :refresh && series[:build].include?(val = "#{val.split(':').first}:build")
|
233
|
+
end
|
234
|
+
|
235
|
+
def task_include?(obj, key)
|
236
|
+
TASK_EXTEND.fetch(key, []).any? { |item| obj.is_a?(item) }
|
237
|
+
end
|
238
|
+
|
239
|
+
def task_defined?(key)
|
240
|
+
::Rake::Task.task_defined?(key)
|
241
|
+
end
|
242
|
+
|
243
|
+
def dev?(script: nil, pat: nil, global: nil)
|
244
|
+
with?(:dev, script: script, pat: pat, global: global || (pat.nil? && global.nil?))
|
245
|
+
end
|
246
|
+
|
247
|
+
def prod?(script: nil, pat: nil, global: false)
|
248
|
+
return false if global && (@script[:dev] == true || !@script[:prod])
|
249
|
+
|
250
|
+
with?(:prod, script: script, pat: pat, global: global)
|
251
|
+
end
|
252
|
+
|
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
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
private
|
284
|
+
|
285
|
+
def script_command(task, val, group, ref)
|
286
|
+
if group
|
287
|
+
label = :group
|
288
|
+
items = as_a(group)
|
289
|
+
else
|
290
|
+
label = :ref
|
291
|
+
items = as_a(ref)
|
292
|
+
end
|
293
|
+
items.each { |name| (@script[label][name.to_sym] ||= {})[task] = val }
|
294
|
+
self
|
295
|
+
end
|
296
|
+
|
297
|
+
def with?(state, script: nil, pat: nil, global: false)
|
298
|
+
if global
|
299
|
+
pat = @script[state] if pat.nil?
|
300
|
+
script ||= @script[:build]
|
301
|
+
end
|
302
|
+
pat.is_a?(::Regexp) ? pat.match?(script) : pat == true
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'forwardable'
|
4
3
|
require 'date'
|
4
|
+
require 'logger'
|
5
5
|
|
6
6
|
module Squared
|
7
|
-
module
|
7
|
+
module Workspace
|
8
8
|
module Project
|
9
9
|
class Base
|
10
10
|
include Common
|
@@ -12,7 +12,8 @@ module Squared
|
|
12
12
|
include Shell
|
13
13
|
include Task
|
14
14
|
include ::Rake::DSL
|
15
|
-
|
15
|
+
|
16
|
+
SEM_VER = /^(\d+)(\.)(\d+)(?:(\.)(\d+))?$/.freeze
|
16
17
|
|
17
18
|
class << self
|
18
19
|
include Common::Task
|
@@ -25,13 +26,16 @@ module Squared
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def as_path(val)
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
case val
|
30
|
+
when ::Pathname
|
31
|
+
val
|
32
|
+
when ::String
|
33
|
+
Pathname.new(val)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
37
|
def to_s
|
34
|
-
/[^:]
|
38
|
+
super.to_s.match(/[^:]+$/)[0]
|
35
39
|
end
|
36
40
|
|
37
41
|
def to_sym
|
@@ -42,15 +46,9 @@ module Squared
|
|
42
46
|
@@print_order = 0
|
43
47
|
@@tasks = {}
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
attr_reader :name, :project, :workspace, :group, :path, :logger, :theme
|
49
|
+
attr_reader :name, :project, :workspace, :group, :path, :log, :theme
|
48
50
|
attr_accessor :warning
|
49
51
|
|
50
|
-
protected :logger
|
51
|
-
|
52
|
-
def_delegators :logger, :log, :<<, :debug, :info, :warn, :error, :fatal, :unknown
|
53
|
-
|
54
52
|
def initialize(name, path, workspace, *, group: nil, log: nil, common: true, **kwargs)
|
55
53
|
@name = name.to_s
|
56
54
|
@path = workspace.root_path(path.to_s)
|
@@ -63,12 +61,14 @@ module Squared
|
|
63
61
|
@output = [kwargs[:run], nil]
|
64
62
|
@copy = kwargs[:copy]
|
65
63
|
@clean = kwargs[:clean]
|
66
|
-
@
|
64
|
+
@warning = workspace.warning
|
65
|
+
@theme = if !workspace.verbose
|
66
|
+
{}
|
67
|
+
elsif common
|
67
68
|
workspace.theme
|
68
69
|
else
|
69
70
|
__get__(:theme)[:project][to_sym] ||= {}
|
70
71
|
end
|
71
|
-
@warning = workspace.warning
|
72
72
|
log = { file: log } unless log.is_a?(::Hash)
|
73
73
|
if (logfile = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
|
74
74
|
logfile = case auto
|
@@ -87,10 +87,10 @@ module Squared
|
|
87
87
|
logfile.realdirpath
|
88
88
|
rescue StandardError => e
|
89
89
|
logfile = nil
|
90
|
-
|
90
|
+
warn e if @warning
|
91
91
|
end
|
92
92
|
end
|
93
|
-
@
|
93
|
+
@log = Logger.new(logfile, progname: @name, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
|
94
94
|
end
|
95
95
|
|
96
96
|
def initialize_build(ref, **kwargs)
|
@@ -100,15 +100,13 @@ module Squared
|
|
100
100
|
elsif @script && @output[0] != false
|
101
101
|
@output[0] ||= @script[:run]
|
102
102
|
end
|
103
|
+
@dev = kwargs.delete(:dev)
|
103
104
|
if env('BUILD', suffix: 'DEV', equals: '0')
|
104
105
|
@dev = false
|
105
|
-
|
106
|
-
@dev =
|
107
|
-
|
108
|
-
|
109
|
-
elsif @dev.nil?
|
110
|
-
@dev = workspace.dev?
|
111
|
-
end
|
106
|
+
elsif env('BUILD', suffix: 'DEV')
|
107
|
+
@dev = true
|
108
|
+
elsif @dev.nil?
|
109
|
+
@dev = workspace.dev?
|
112
110
|
end
|
113
111
|
end
|
114
112
|
|
@@ -125,12 +123,8 @@ module Squared
|
|
125
123
|
def populate(*)
|
126
124
|
namespace name do
|
127
125
|
workspace.series.each_key do |key|
|
128
|
-
|
129
|
-
|
130
|
-
next unless has?(key)
|
131
|
-
else
|
132
|
-
next unless workspace.task_defined?(self, key)
|
133
|
-
end
|
126
|
+
next unless Application::WORKSPACE_KEYS.include?(key) ? has?(key) : workspace.task_include?(self, key)
|
127
|
+
|
134
128
|
desc message(name, key)
|
135
129
|
task key do
|
136
130
|
__send__(key)
|
@@ -139,7 +133,7 @@ module Squared
|
|
139
133
|
end
|
140
134
|
end
|
141
135
|
|
142
|
-
def build(*args)
|
136
|
+
def build(*args, sync: true)
|
143
137
|
if args.empty?
|
144
138
|
cmd, opts = @output
|
145
139
|
opts &&= shell_escape(opts)
|
@@ -160,13 +154,13 @@ module Squared
|
|
160
154
|
cmd = compose(opts)
|
161
155
|
banner = env('REPO_BUILD') == 'verbose'
|
162
156
|
end
|
163
|
-
run(cmd, exception: workspace.exception, banner: banner)
|
157
|
+
run(cmd, exception: workspace.exception, banner: banner, sync: sync)
|
164
158
|
end
|
165
159
|
|
166
160
|
def refresh(*)
|
167
|
-
build
|
161
|
+
build(sync: invoked_sync?('depend'))
|
168
162
|
key = "#{name}:copy"
|
169
|
-
if
|
163
|
+
if workspace.task_defined?(key)
|
170
164
|
invoke key
|
171
165
|
else
|
172
166
|
copy
|
@@ -174,34 +168,35 @@ module Squared
|
|
174
168
|
end
|
175
169
|
|
176
170
|
def depend(*)
|
177
|
-
run(@depend, exception: workspace.exception) if @depend
|
171
|
+
run(@depend, exception: workspace.exception, sync: invoked_sync?('depend')) if @depend
|
178
172
|
end
|
179
173
|
|
180
174
|
def copy(*)
|
181
|
-
run_s
|
175
|
+
run_s(@copy, sync: invoked_sync?('copy'))
|
182
176
|
end
|
183
177
|
|
184
178
|
def doc
|
185
|
-
build
|
179
|
+
build(@doc, sync: invoked_sync?('doc')) if @doc
|
186
180
|
end
|
187
181
|
|
188
182
|
def test
|
189
|
-
build
|
183
|
+
build(@test, sync: invoked_sync?('test')) if @test
|
190
184
|
end
|
191
185
|
|
192
186
|
def clean
|
193
187
|
return unless @clean
|
194
188
|
|
195
189
|
if @clean.is_a?(::String)
|
196
|
-
run_s
|
190
|
+
run_s(@clean, sync: invoked_sync?('clean'))
|
197
191
|
else
|
198
192
|
@clean.each do |val|
|
199
|
-
|
193
|
+
val = val.to_s
|
194
|
+
if val =~ %r{[\\/]$}
|
200
195
|
dir = Pathname.new(val)
|
201
196
|
dir = base_path(dir) unless dir.absolute?
|
202
197
|
next unless dir.directory?
|
203
198
|
|
204
|
-
warn "rm -rf #{dir}"
|
199
|
+
log.warn "rm -rf #{dir}"
|
205
200
|
dir.rmtree(verbose: true)
|
206
201
|
else
|
207
202
|
files = val.include?('*') ? Dir[base_path(val)] : [base_path(val)]
|
@@ -209,7 +204,7 @@ module Squared
|
|
209
204
|
begin
|
210
205
|
File.delete(file) if File.file?(file)
|
211
206
|
rescue StandardError => e
|
212
|
-
error e
|
207
|
+
log.error e
|
213
208
|
end
|
214
209
|
end
|
215
210
|
end
|
@@ -246,7 +241,7 @@ module Squared
|
|
246
241
|
end
|
247
242
|
|
248
243
|
def refresh?
|
249
|
-
build? && (copy? ||
|
244
|
+
build? && (copy? || workspace.task_defined?("#{name}:copy"))
|
250
245
|
end
|
251
246
|
|
252
247
|
def depend?
|
@@ -271,36 +266,36 @@ module Squared
|
|
271
266
|
|
272
267
|
protected
|
273
268
|
|
274
|
-
def run(cmd = @session, exception: false, banner: true, req: nil)
|
269
|
+
def run(cmd = @session, exception: false, banner: true, sync: true, req: nil)
|
275
270
|
return if req && !base_path(req).exist?
|
276
271
|
|
277
272
|
cmd = close_session(cmd)
|
278
|
-
info cmd
|
279
|
-
print_item format_banner(cmd, banner: banner)
|
273
|
+
log.info cmd
|
274
|
+
print_item format_banner(cmd, banner: banner) if sync
|
280
275
|
begin
|
281
276
|
shell(cmd, chdir: path, exception: exception)
|
282
277
|
rescue StandardError => e
|
283
|
-
error e
|
278
|
+
log.error e
|
284
279
|
raise
|
285
280
|
end
|
286
281
|
end
|
287
282
|
|
288
|
-
def run_s(cmd)
|
289
|
-
run(cmd, exception: workspace.exception, banner: verbose
|
283
|
+
def run_s(cmd, **kwargs)
|
284
|
+
run(cmd, exception: workspace.exception, banner: verbose?, **kwargs) if cmd.is_a?(::String)
|
290
285
|
end
|
291
286
|
|
292
|
-
def env(key,
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
if !equals.nil?
|
300
|
-
ret == equals.to_s
|
301
|
-
elsif !ret.empty? && ret != '0'
|
302
|
-
ret
|
287
|
+
def env(key, equals: nil, ignore: ['0'].freeze, default: nil, suffix: nil, strict: false)
|
288
|
+
a = "#{key}_#{name.upcase}"
|
289
|
+
b = ''
|
290
|
+
if suffix
|
291
|
+
a = [a, suffix].flatten.join('_')
|
292
|
+
elsif !strict
|
293
|
+
b = ENV.fetch(key, '')
|
303
294
|
end
|
295
|
+
ret = ENV.fetch(a, b)
|
296
|
+
return ret == equals.to_s unless equals.nil?
|
297
|
+
|
298
|
+
ret.empty? || as_a(ignore).any? { |val| ret == val.to_s } ? default : ret
|
304
299
|
end
|
305
300
|
|
306
301
|
def session(*cmd, options: nil)
|
@@ -312,8 +307,8 @@ module Squared
|
|
312
307
|
|
313
308
|
def close_session(cmd)
|
314
309
|
return cmd unless cmd.respond_to?(:done)
|
315
|
-
raise ArgumentError, message('none were provided', hint: name) if cmd.empty?
|
316
310
|
|
311
|
+
raise_error('none were provided', hint: name) if cmd.empty?
|
317
312
|
@session = nil if cmd == @session
|
318
313
|
cmd.done
|
319
314
|
end
|
@@ -324,26 +319,40 @@ module Squared
|
|
324
319
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
325
320
|
end
|
326
321
|
|
327
|
-
def print_banner(*lines, styles:
|
322
|
+
def print_banner(*lines, styles: theme[:banner], border: theme[:border])
|
323
|
+
pad = 0
|
324
|
+
if styles
|
325
|
+
if styles.any? { |s| s.to_s.end_with?('!') }
|
326
|
+
pad = 1
|
327
|
+
elsif styles.size <= 1
|
328
|
+
styles = [:bold] + styles
|
329
|
+
end
|
330
|
+
end
|
328
331
|
n = max_width(lines)
|
329
332
|
ch = ' ' * pad
|
330
333
|
index = -1
|
331
334
|
out = lines.map do |val|
|
332
335
|
index += 1
|
333
336
|
val = ch + val.ljust(n - (pad * 2)) + ch
|
334
|
-
if styles && (
|
337
|
+
if styles && (pad == 1 || index == 0)
|
335
338
|
sub_style(val, *styles)
|
336
339
|
else
|
337
340
|
val
|
338
341
|
end
|
339
342
|
end
|
340
|
-
out << ('-' * n)
|
343
|
+
out << sub_style('-' * n, styles: border)
|
341
344
|
out.join("\n")
|
342
345
|
end
|
343
346
|
|
344
|
-
def print_footer(*lines)
|
347
|
+
def print_footer(*lines, sub: nil, border: theme[:border])
|
345
348
|
n = max_width(lines)
|
346
|
-
|
349
|
+
sub = as_a(sub)
|
350
|
+
lines.map! do |val|
|
351
|
+
s = val.ljust(n)
|
352
|
+
sub.each { |h| s = sub_style(s, **h) }
|
353
|
+
s
|
354
|
+
end
|
355
|
+
[sub_style('-' * n, styles: border), *lines].join("\n")
|
347
356
|
end
|
348
357
|
|
349
358
|
def format_desc(action, flag, opts = nil, req: 'opts*')
|
@@ -355,20 +364,12 @@ module Squared
|
|
355
364
|
message(name, action, opts ? "#{flag}[#{opts}]" : flag)
|
356
365
|
end
|
357
366
|
|
358
|
-
def format_banner(cmd, banner: true,
|
367
|
+
def format_banner(cmd, banner: true, multiple: false)
|
359
368
|
return unless banner
|
360
369
|
|
361
370
|
if verbose?
|
362
|
-
|
363
|
-
|
364
|
-
if args.any? { |s| s.to_s.end_with?('!') }
|
365
|
-
pad = 1
|
366
|
-
elsif args.size <= 1
|
367
|
-
args = [:bold] + args
|
368
|
-
end
|
369
|
-
end
|
370
|
-
print_banner(cmd.sub(/^\S+/, &:upcase), path.to_s, styles: args, pad: pad, first: pad == 0)
|
371
|
-
elsif multitask && workspace.multitask?
|
371
|
+
print_banner(cmd.sub(/^\S+/, &:upcase), path.to_s)
|
372
|
+
elsif multiple && workspace.series.multiple?
|
372
373
|
"## #{path} ##"
|
373
374
|
end
|
374
375
|
end
|
@@ -386,17 +387,17 @@ module Squared
|
|
386
387
|
return unless (val = args[key]).nil? || (pat && !val.match?(pat))
|
387
388
|
|
388
389
|
@session = nil
|
389
|
-
|
390
|
+
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
390
391
|
elsif args.is_a?(::Array)
|
391
392
|
return unless args.empty?
|
392
393
|
|
393
394
|
@session = nil
|
394
|
-
|
395
|
+
raise_error(action, "#{flag}[]", hint: 'empty')
|
395
396
|
end
|
396
397
|
return unless action.to_s.empty?
|
397
398
|
|
398
399
|
@session = nil
|
399
|
-
|
400
|
+
raise_error('parameter', flag, hint: 'missing')
|
400
401
|
end
|
401
402
|
|
402
403
|
def verbose?
|
@@ -408,13 +409,12 @@ module Squared
|
|
408
409
|
end
|
409
410
|
|
410
411
|
def invoked_sync?(action)
|
411
|
-
return true if
|
412
|
+
return true if workspace.series.sync?("#{action}:sync")
|
412
413
|
|
413
|
-
missing = ->(val) { ::Rake::Task.tasks.none? { |item| item.name == val } }
|
414
414
|
check = lambda do |val|
|
415
415
|
if invoked?(val)
|
416
|
-
|
417
|
-
elsif
|
416
|
+
!workspace.task_defined?("#{val}:sync")
|
417
|
+
elsif workspace.series.sync?("#{val}:sync")
|
418
418
|
true
|
419
419
|
end
|
420
420
|
end
|
@@ -426,7 +426,7 @@ module Squared
|
|
426
426
|
ret = check.("#{action}:#{base.to_sym}")
|
427
427
|
return ret unless ret.nil?
|
428
428
|
end
|
429
|
-
invoked?("#{name}:#{action}") && (!invoked?(action) ||
|
429
|
+
invoked?("#{name}:#{action}") && (!invoked?(action) || !workspace.task_defined?("#{action}:sync"))
|
430
430
|
end
|
431
431
|
|
432
432
|
private
|