squared 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|