squared 0.0.3 → 0.0.5
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 +23 -1
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +2 -4
- data/lib/squared/common/shell.rb +2 -2
- data/lib/squared/common/task.rb +1 -1
- data/lib/squared/config.rb +17 -18
- data/lib/squared/repo/project/base.rb +44 -50
- data/lib/squared/repo/project/git.rb +30 -30
- data/lib/squared/repo/project/node.rb +11 -14
- data/lib/squared/repo/project/python.rb +55 -28
- data/lib/squared/repo/project/ruby.rb +35 -21
- data/lib/squared/repo/workspace.rb +99 -48
- data/lib/squared/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fad15a8296b3ab7fec1ff1ac0bbe1f92b65b3bd263e8f9ea38cd62e1a8e3460e
|
4
|
+
data.tar.gz: 1ab92094b8d239572ac66a42014aafcca6585f86af1159060715e322d8138503
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4b7ecd7671596c8da581f567e43a4968ec7ea2f060a75d92b4369d19d3e1638e2f2c91b70e3c0205bbc77ccd309341d5dbb47c1c774eead07f5c71a0bf13684
|
7
|
+
data.tar.gz: 1c88e0dabe3ef47f17527c604440775fdf5984a5389ad6e6e8ec4a9c8ade34a4c59423bdf0f1277e6ffb88a8484d774da3029f814cc37526b92f1d737257e18b
|
data/README.ruby.md
CHANGED
@@ -28,9 +28,15 @@ gem install squared
|
|
28
28
|
|
29
29
|
## Example - Rakefile
|
30
30
|
|
31
|
+
Projects from any accessible folder can be added either relative to `REPO_ROOT` or absolutely. The same Rakefile can also manage other similarly cloned repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
|
32
|
+
|
31
33
|
```ruby
|
32
34
|
require "squared"
|
33
35
|
|
36
|
+
# REPO_ROOT = /workspaces
|
37
|
+
# REPO_HOME = /workspaces/squared
|
38
|
+
# rake = /workspaces/squared/Rakefile
|
39
|
+
|
34
40
|
Repo::Workspace
|
35
41
|
.new("squared") # REPO_HOME
|
36
42
|
.repo("https://github.com/anpham6/squared-repo", "nightly", run: 'build') # Optional
|
@@ -40,7 +46,7 @@ Repo::Workspace
|
|
40
46
|
.add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", ref: :ruby) # Ruby (with C extensions)
|
41
47
|
.add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
|
42
48
|
.add("logger", copy: { from: "lib", glob: "**/*.rb", gemdir: "~/.rvm/gems/ruby-3.3.5/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
|
43
|
-
.add("android", "android-docs", run: false, doc: "make html", ref: :python) #
|
49
|
+
.add("android", "android-docs", run: false, doc: "make html", ref: :python) # Python
|
44
50
|
.add("emc", "e-mc", copy: { from: "publish", into: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
|
45
51
|
.add("pir", "pi-r", copy: { from: "publish", into: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
|
46
52
|
.add("squared", log: { file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app") # Copy target (main)
|
@@ -51,6 +57,22 @@ Repo::Workspace
|
|
51
57
|
.style(:banner, "bright_cyan", "bold", "bright_black!")
|
52
58
|
.finalize! # Optional
|
53
59
|
end
|
60
|
+
# pathname = /workspaces/pathname
|
61
|
+
# optparse = /workspaces/optparse
|
62
|
+
# log = /workspaces/logger
|
63
|
+
# android = /workspaces/android-docs
|
64
|
+
# emc = /workspaces/e-mc
|
65
|
+
# pir = /workspaces/pi-r
|
66
|
+
# squared = /workspaces/squared
|
67
|
+
|
68
|
+
Repo::Workspace
|
69
|
+
.new("squared")
|
70
|
+
.group("default", "ruby", run: "rake build", copy: "rake install", clean: "rake clean", pathname: { run: "rake compile" })
|
71
|
+
.build
|
72
|
+
# default = /workspaces/ruby/*
|
73
|
+
# pathname = /workspaces/ruby/pathname
|
74
|
+
# optparse = /workspaces/ruby/optparse
|
75
|
+
# logger = /workspaces/ruby/logger
|
54
76
|
```
|
55
77
|
|
56
78
|
**NOTE**: The use of "**ref**" (class name) is only necessary when running `repo:init` for the first time into an empty directory.
|
data/lib/squared/common/class.rb
CHANGED
@@ -66,14 +66,12 @@ module Squared
|
|
66
66
|
yield out
|
67
67
|
elsif pipe.respond_to?(:puts)
|
68
68
|
pipe.puts out
|
69
|
-
elsif err
|
70
|
-
defined?(__warn__) == 'method' ? __warn__(out) : warn(out)
|
71
69
|
else
|
72
|
-
|
70
|
+
err ? warn(out) : puts(out)
|
73
71
|
end
|
74
72
|
end
|
75
73
|
|
76
|
-
def sub_style(val, *args,
|
74
|
+
def sub_style(val, *args, styles: nil, pat: nil, index: 1)
|
77
75
|
return val unless ENV['NO_COLOR'].to_s.empty?
|
78
76
|
|
79
77
|
if pat && index != 0
|
data/lib/squared/common/shell.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
module Squared
|
4
4
|
module Common
|
5
5
|
module Shell
|
6
|
-
def shell_escape(val)
|
7
|
-
return val if ::Rake::Win32.windows?
|
6
|
+
def shell_escape(val, quote: false)
|
7
|
+
return (quote ? shell_quote(val, force: false) : val) if ::Rake::Win32.windows?
|
8
8
|
|
9
9
|
require 'shellwords'
|
10
10
|
Shellwords.escape(val)
|
data/lib/squared/common/task.rb
CHANGED
data/lib/squared/config.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
|
3
5
|
module Squared
|
4
6
|
module Config
|
5
7
|
class Viewer
|
@@ -10,19 +12,20 @@ module Squared
|
|
10
12
|
|
11
13
|
class << self
|
12
14
|
def to_s
|
13
|
-
/[^:]
|
15
|
+
super.to_s.match(/[^:]+$/)[0]
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
19
|
attr_reader :name, :main, :project, :theme
|
18
20
|
|
19
|
-
def initialize(main, name = nil, project: nil, opts: {}, auto: true, common: true)
|
21
|
+
def initialize(main, name = nil, project: nil, dump: nil, opts: {}, auto: true, common: true)
|
20
22
|
if project
|
21
23
|
main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
|
22
24
|
@required = true
|
23
25
|
end
|
24
26
|
@name = name&.to_s || @project&.name
|
25
27
|
@ext = File.extname(main)
|
28
|
+
@dump = dump
|
26
29
|
@mime = {}
|
27
30
|
@theme = common ? __get__(:theme)[:viewer] : {}
|
28
31
|
if exist?
|
@@ -61,7 +64,6 @@ module Squared
|
|
61
64
|
if @mime['json'] && (exist? || !::Rake::Task.task_defined?("#{name}:#{view}:json"))
|
62
65
|
desc format_desc(view, %w[json])
|
63
66
|
task :json, [:keys] do |_, args|
|
64
|
-
require 'json'
|
65
67
|
read_keys(JSON, 'json', *params.(args))
|
66
68
|
end
|
67
69
|
end
|
@@ -79,18 +81,17 @@ module Squared
|
|
79
81
|
yield self if block_given?
|
80
82
|
end
|
81
83
|
|
82
|
-
def add(type, gem: nil, parse: nil, ext:
|
84
|
+
def add(type, gem: nil, parse: nil, ext: nil, opts: {}, command: 'view', file: nil, exist: nil)
|
83
85
|
return self if @mime.frozen?
|
84
86
|
|
85
87
|
type = type.to_s
|
86
88
|
if parse && enabled?
|
87
89
|
require(gem || type)
|
88
90
|
obj = eval(parse)
|
89
|
-
ext = as_a(ext)
|
90
|
-
ext << type if ext.empty?
|
91
|
+
ext << type if (ext = as_a(ext)).empty?
|
91
92
|
file = realpath if file.nil? && exist?
|
92
93
|
namespace name do
|
93
|
-
desc format_desc(command, ext)
|
94
|
+
desc format_desc(command, ext, exist: exist)
|
94
95
|
namespace command do
|
95
96
|
task type, [:keys] do |_, args|
|
96
97
|
if file
|
@@ -128,7 +129,7 @@ module Squared
|
|
128
129
|
end
|
129
130
|
end
|
130
131
|
name ||= file.basename.to_s.chomp(File.extname(file))
|
131
|
-
add(type, gem: gem, parse: parse, ext: ext, opts: opts, command: name, file: file)
|
132
|
+
add(type, gem: gem, parse: parse, ext: ext, opts: opts, command: name, file: file, exist: true)
|
132
133
|
end
|
133
134
|
|
134
135
|
def style(name, *args)
|
@@ -175,7 +176,7 @@ module Squared
|
|
175
176
|
raise ArgumentError, message(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", hint: 'not found')
|
176
177
|
end
|
177
178
|
end
|
178
|
-
project&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
|
179
|
+
project&.log&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
|
179
180
|
doc = if reader.respond_to?(:load_file)
|
180
181
|
reader.load_file(file, **@mime[type])
|
181
182
|
else
|
@@ -224,7 +225,7 @@ module Squared
|
|
224
225
|
end
|
225
226
|
end
|
226
227
|
rescue StandardError
|
227
|
-
project&.warn "#{Viewer}(#{type}) => #{file ? "#{file} " : ''}{#{key}: undefined}"
|
228
|
+
project&.log&.warn "#{Viewer}(#{type}) => #{file ? "#{file} " : ''}{#{key}: undefined}"
|
228
229
|
val = Regexp.escape($!.message)
|
229
230
|
key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
|
230
231
|
s = "<#{$3 || $2 || $1}>"
|
@@ -234,16 +235,14 @@ module Squared
|
|
234
235
|
$2 ? ".#{s}" : "#{s}."
|
235
236
|
end
|
236
237
|
end
|
237
|
-
out << [key, pipe? ? nil : 'undefined']
|
238
|
+
out << [key, pipe? ? JSON.dump(nil) : 'undefined']
|
238
239
|
else
|
239
|
-
out << [key, pipe? ? val : val.inspect]
|
240
|
+
out << [key, @dump == 'json' || pipe? ? JSON.dump(val) : val.inspect]
|
240
241
|
end
|
241
|
-
pad = key.size
|
242
|
+
pad = [pad, key.size].max
|
242
243
|
end
|
243
244
|
if pipe?
|
244
|
-
|
245
|
-
out = out.map { |item| JSON.dump(item[1]) }
|
246
|
-
puts out.join("\n")
|
245
|
+
puts out.map(&:last).join("\n")
|
247
246
|
else
|
248
247
|
out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
|
249
248
|
end
|
@@ -264,8 +263,8 @@ module Squared
|
|
264
263
|
end
|
265
264
|
end
|
266
265
|
|
267
|
-
def format_desc(command, ext)
|
268
|
-
message(name, command, "#{ext.first}[#{exist
|
266
|
+
def format_desc(command, ext, exist: exist?)
|
267
|
+
message(name, command, "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys*]")
|
269
268
|
end
|
270
269
|
|
271
270
|
def realpath
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'forwardable'
|
4
3
|
require 'date'
|
5
4
|
|
6
5
|
module Squared
|
@@ -12,7 +11,6 @@ module Squared
|
|
12
11
|
include Shell
|
13
12
|
include Task
|
14
13
|
include ::Rake::DSL
|
15
|
-
extend Forwardable
|
16
14
|
|
17
15
|
class << self
|
18
16
|
include Common::Task
|
@@ -31,7 +29,7 @@ module Squared
|
|
31
29
|
end
|
32
30
|
|
33
31
|
def to_s
|
34
|
-
/[^:]
|
32
|
+
super.to_s.match(/[^:]+$/)[0]
|
35
33
|
end
|
36
34
|
|
37
35
|
def to_sym
|
@@ -42,15 +40,9 @@ module Squared
|
|
42
40
|
@@print_order = 0
|
43
41
|
@@tasks = {}
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
attr_reader :name, :project, :workspace, :group, :path, :logger, :theme
|
43
|
+
attr_reader :name, :project, :workspace, :group, :path, :log, :theme
|
48
44
|
attr_accessor :warning
|
49
45
|
|
50
|
-
protected :logger
|
51
|
-
|
52
|
-
def_delegators :logger, :log, :<<, :debug, :info, :warn, :error, :fatal, :unknown
|
53
|
-
|
54
46
|
def initialize(name, path, workspace, *, group: nil, log: nil, common: true, **kwargs)
|
55
47
|
@name = name.to_s
|
56
48
|
@path = workspace.root_path(path.to_s)
|
@@ -63,12 +55,14 @@ module Squared
|
|
63
55
|
@output = [kwargs[:run], nil]
|
64
56
|
@copy = kwargs[:copy]
|
65
57
|
@clean = kwargs[:clean]
|
66
|
-
@
|
58
|
+
@warning = workspace.warning
|
59
|
+
@theme = if !workspace.verbose
|
60
|
+
{}
|
61
|
+
elsif common
|
67
62
|
workspace.theme
|
68
63
|
else
|
69
64
|
__get__(:theme)[:project][to_sym] ||= {}
|
70
65
|
end
|
71
|
-
@warning = workspace.warning
|
72
66
|
log = { file: log } unless log.is_a?(::Hash)
|
73
67
|
if (logfile = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
|
74
68
|
logfile = case auto
|
@@ -87,10 +81,10 @@ module Squared
|
|
87
81
|
logfile.realdirpath
|
88
82
|
rescue StandardError => e
|
89
83
|
logfile = nil
|
90
|
-
|
84
|
+
warn e if @warning
|
91
85
|
end
|
92
86
|
end
|
93
|
-
@
|
87
|
+
@log = Logger.new(logfile, progname: @name, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
|
94
88
|
end
|
95
89
|
|
96
90
|
def initialize_build(ref, **kwargs)
|
@@ -100,15 +94,13 @@ module Squared
|
|
100
94
|
elsif @script && @output[0] != false
|
101
95
|
@output[0] ||= @script[:run]
|
102
96
|
end
|
97
|
+
@dev = kwargs.delete(:dev)
|
103
98
|
if env('BUILD', suffix: 'DEV', equals: '0')
|
104
99
|
@dev = false
|
105
|
-
|
106
|
-
@dev =
|
107
|
-
|
108
|
-
|
109
|
-
elsif @dev.nil?
|
110
|
-
@dev = workspace.dev?
|
111
|
-
end
|
100
|
+
elsif env('BUILD', suffix: 'DEV')
|
101
|
+
@dev = true
|
102
|
+
elsif @dev.nil?
|
103
|
+
@dev = workspace.dev?
|
112
104
|
end
|
113
105
|
end
|
114
106
|
|
@@ -125,12 +117,8 @@ module Squared
|
|
125
117
|
def populate(*)
|
126
118
|
namespace name do
|
127
119
|
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
|
120
|
+
next unless Workspace::TASK_KEYS.include?(key) ? has?(key) : workspace.task_defined?(self, key)
|
121
|
+
|
134
122
|
desc message(name, key)
|
135
123
|
task key do
|
136
124
|
__send__(key)
|
@@ -201,7 +189,7 @@ module Squared
|
|
201
189
|
dir = base_path(dir) unless dir.absolute?
|
202
190
|
next unless dir.directory?
|
203
191
|
|
204
|
-
warn "rm -rf #{dir}"
|
192
|
+
log.warn "rm -rf #{dir}"
|
205
193
|
dir.rmtree(verbose: true)
|
206
194
|
else
|
207
195
|
files = val.include?('*') ? Dir[base_path(val)] : [base_path(val)]
|
@@ -209,7 +197,7 @@ module Squared
|
|
209
197
|
begin
|
210
198
|
File.delete(file) if File.file?(file)
|
211
199
|
rescue StandardError => e
|
212
|
-
error e
|
200
|
+
log.error e
|
213
201
|
end
|
214
202
|
end
|
215
203
|
end
|
@@ -275,12 +263,12 @@ module Squared
|
|
275
263
|
return if req && !base_path(req).exist?
|
276
264
|
|
277
265
|
cmd = close_session(cmd)
|
278
|
-
info cmd
|
266
|
+
log.info cmd
|
279
267
|
print_item format_banner(cmd, banner: banner)
|
280
268
|
begin
|
281
269
|
shell(cmd, chdir: path, exception: exception)
|
282
270
|
rescue StandardError => e
|
283
|
-
error e
|
271
|
+
log.error e
|
284
272
|
raise
|
285
273
|
end
|
286
274
|
end
|
@@ -324,26 +312,40 @@ module Squared
|
|
324
312
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
325
313
|
end
|
326
314
|
|
327
|
-
def print_banner(*lines, styles:
|
315
|
+
def print_banner(*lines, styles: theme[:banner], border: theme[:border])
|
316
|
+
pad = 0
|
317
|
+
if styles
|
318
|
+
if styles.any? { |s| s.to_s.end_with?('!') }
|
319
|
+
pad = 1
|
320
|
+
elsif styles.size <= 1
|
321
|
+
styles = [:bold] + styles
|
322
|
+
end
|
323
|
+
end
|
328
324
|
n = max_width(lines)
|
329
325
|
ch = ' ' * pad
|
330
326
|
index = -1
|
331
327
|
out = lines.map do |val|
|
332
328
|
index += 1
|
333
329
|
val = ch + val.ljust(n - (pad * 2)) + ch
|
334
|
-
if styles && (
|
330
|
+
if styles && (pad == 1 || index == 0)
|
335
331
|
sub_style(val, *styles)
|
336
332
|
else
|
337
333
|
val
|
338
334
|
end
|
339
335
|
end
|
340
|
-
out << ('-' * n)
|
336
|
+
out << sub_style('-' * n, styles: border)
|
341
337
|
out.join("\n")
|
342
338
|
end
|
343
339
|
|
344
|
-
def print_footer(*lines)
|
340
|
+
def print_footer(*lines, sub: nil, border: theme[:border])
|
345
341
|
n = max_width(lines)
|
346
|
-
|
342
|
+
sub = as_a(sub)
|
343
|
+
lines.map! do |val|
|
344
|
+
s = val.ljust(n)
|
345
|
+
sub.each { |h| s = sub_style(s, **h) }
|
346
|
+
s
|
347
|
+
end
|
348
|
+
[sub_style('-' * n, styles: border), *lines].join("\n")
|
347
349
|
end
|
348
350
|
|
349
351
|
def format_desc(action, flag, opts = nil, req: 'opts*')
|
@@ -355,20 +357,12 @@ module Squared
|
|
355
357
|
message(name, action, opts ? "#{flag}[#{opts}]" : flag)
|
356
358
|
end
|
357
359
|
|
358
|
-
def format_banner(cmd, banner: true,
|
360
|
+
def format_banner(cmd, banner: true, multiple: false)
|
359
361
|
return unless banner
|
360
362
|
|
361
363
|
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?
|
364
|
+
print_banner(cmd.sub(/^\S+/, &:upcase), path.to_s)
|
365
|
+
elsif multiple && workspace.multiple?
|
372
366
|
"## #{path} ##"
|
373
367
|
end
|
374
368
|
end
|
@@ -408,13 +402,13 @@ module Squared
|
|
408
402
|
end
|
409
403
|
|
410
404
|
def invoked_sync?(action)
|
411
|
-
return true if
|
405
|
+
return true if workspace.sync?("#{action}:sync")
|
412
406
|
|
413
407
|
missing = ->(val) { ::Rake::Task.tasks.none? { |item| item.name == val } }
|
414
408
|
check = lambda do |val|
|
415
409
|
if invoked?(val)
|
416
410
|
missing.("#{val}:sync")
|
417
|
-
elsif
|
411
|
+
elsif workspace.sync?("#{val}:sync")
|
418
412
|
true
|
419
413
|
end
|
420
414
|
end
|
@@ -426,7 +420,7 @@ module Squared
|
|
426
420
|
ret = check.("#{action}:#{base.to_sym}")
|
427
421
|
return ret unless ret.nil?
|
428
422
|
end
|
429
|
-
invoked?("#{name}:#{action}") && (!invoked?(action) || missing.(sync))
|
423
|
+
invoked?("#{name}:#{action}") && (!invoked?(action) || missing.("#{action}:sync"))
|
430
424
|
end
|
431
425
|
|
432
426
|
private
|
@@ -7,7 +7,9 @@ module Squared
|
|
7
7
|
include Format
|
8
8
|
|
9
9
|
REF = :git
|
10
|
-
|
10
|
+
OPT_PULL = %w[all tags prune ff-only autostash dry-run].freeze
|
11
|
+
OPT_FETCH = %w[tags prune prune-tags depth=n dry-run].freeze
|
12
|
+
private_constant :REF, :OPT_PULL, :OPT_FETCH
|
11
13
|
|
12
14
|
class << self
|
13
15
|
def populate(workspace, parallel: [], **)
|
@@ -49,7 +51,7 @@ module Squared
|
|
49
51
|
diff: %i[head cached branch],
|
50
52
|
fetch: %i[all submodules unshallow],
|
51
53
|
files: %i[cached modified deleted others],
|
52
|
-
pull: %i[rebase no-rebase commit no-commit submodules],
|
54
|
+
pull: %i[head rebase no-rebase commit no-commit submodules],
|
53
55
|
stash: %i[push pop apply list clear],
|
54
56
|
refs: %i[heads tags],
|
55
57
|
reset: %i[head soft mixed hard merge keep submodules],
|
@@ -67,13 +69,13 @@ module Squared
|
|
67
69
|
flags.each do |flag|
|
68
70
|
case action
|
69
71
|
when :pull
|
70
|
-
desc format_desc(action, flag,
|
72
|
+
desc format_desc(action, flag, OPT_PULL)
|
71
73
|
task flag, [:opts] do |_, args|
|
72
74
|
opts = collect_args(args, :opts)
|
73
75
|
pull(flag, opts: opts)
|
74
76
|
end
|
75
77
|
when :fetch
|
76
|
-
desc format_desc(action, flag,
|
78
|
+
desc format_desc(action, flag, OPT_FETCH)
|
77
79
|
task flag, [:opts] do |_, args|
|
78
80
|
opts = collect_args(args, :opts)
|
79
81
|
fetch(flag, opts: opts)
|
@@ -202,14 +204,8 @@ module Squared
|
|
202
204
|
elsif flag == :commit || option('commit')
|
203
205
|
cmd << '--commit'
|
204
206
|
end
|
205
|
-
|
206
|
-
|
207
|
-
case val
|
208
|
-
when 'all', 'tags', 'prune', 'ff-only', 'autostash', 'dry-run'
|
209
|
-
cmd << "--#{val}"
|
210
|
-
end
|
211
|
-
end
|
212
|
-
source(sync: sync, stderr: true, exception: !workspace.multitask?)
|
207
|
+
append_pull opts, OPT_PULL, flag
|
208
|
+
source(sync: sync, stderr: true, exception: !workspace.multiple?)
|
213
209
|
end
|
214
210
|
|
215
211
|
def rebase
|
@@ -219,16 +215,8 @@ module Squared
|
|
219
215
|
def fetch(flag = nil, opts: [])
|
220
216
|
cmd = git_session 'fetch'
|
221
217
|
cmd << '--all' if flag == :all || option('all')
|
222
|
-
|
223
|
-
|
224
|
-
case val
|
225
|
-
when 'tags', 'prune', 'prune-tags', 'dry-run'
|
226
|
-
cmd << "--#{val}"
|
227
|
-
else
|
228
|
-
cmd << "--depth=#{$1}" if /^depth=(\d+)$/.match(val)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
source(sync: invoked_sync?('fetch', flag), stderr: true, exception: !workspace.multitask?)
|
218
|
+
append_pull opts, OPT_FETCH, flag
|
219
|
+
source(sync: invoked_sync?('fetch', flag), stderr: true, exception: !workspace.multiple?)
|
232
220
|
end
|
233
221
|
|
234
222
|
def stash(flag = :push, files = [], commit: nil)
|
@@ -448,9 +436,9 @@ module Squared
|
|
448
436
|
|
449
437
|
def source(cmd = @session, exception: true, banner: true, io: false, sync: true, stdout: false, stderr: false)
|
450
438
|
cmd = close_session(cmd)
|
451
|
-
info cmd
|
439
|
+
log.info cmd
|
452
440
|
begin
|
453
|
-
banner = format_banner(cmd.gsub(trailing_slash(path), ''), banner: banner,
|
441
|
+
banner = format_banner(cmd.gsub(trailing_slash(path), ''), banner: banner, multiple: true)
|
454
442
|
cmd = cmd.sub(/^git\b/, "git --work-tree #{shell_quote(path)} --git-dir #{shell_quote(gitdir)}")
|
455
443
|
if io
|
456
444
|
[IO.popen(cmd), banner]
|
@@ -481,7 +469,7 @@ module Squared
|
|
481
469
|
end
|
482
470
|
end
|
483
471
|
rescue StandardError => e
|
484
|
-
error e
|
472
|
+
log.error e
|
485
473
|
raise if exception
|
486
474
|
|
487
475
|
emphasize e, message('git', cmd)
|
@@ -497,7 +485,7 @@ module Squared
|
|
497
485
|
next if grep && !line.match?(grep)
|
498
486
|
|
499
487
|
if loglevel
|
500
|
-
log loglevel, line
|
488
|
+
log.add loglevel, line
|
501
489
|
else
|
502
490
|
sub&.each { |h| line = sub_style(line, **h) }
|
503
491
|
if banner
|
@@ -516,9 +504,10 @@ module Squared
|
|
516
504
|
return unless verbose?
|
517
505
|
|
518
506
|
if size > 0
|
519
|
-
|
520
|
-
|
521
|
-
puts print_footer
|
507
|
+
styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
|
508
|
+
styles << :bold if styles.size <= 1
|
509
|
+
puts print_footer("#{size} #{size == 1 ? type.sub(/s$/, '') : type}",
|
510
|
+
sub: { styles: styles, pat: /^(\d+)(.+)$/ })
|
522
511
|
else
|
523
512
|
puts empty_status("No #{type} were #{action}", 'grep', grep)
|
524
513
|
end
|
@@ -529,13 +518,24 @@ module Squared
|
|
529
518
|
end
|
530
519
|
|
531
520
|
def source_path?(val)
|
532
|
-
return val.to_s.start_with?(
|
521
|
+
return val.to_s.start_with?(File.join(path, '').to_s) if Pathname.new(val).absolute?
|
533
522
|
|
534
523
|
!val.match?(%r{^\.\.[/\\]})
|
535
524
|
end
|
536
525
|
|
537
526
|
private
|
538
527
|
|
528
|
+
def append_pull(opts, list, flag = nil)
|
529
|
+
append_submodules flag
|
530
|
+
opts.each do |opt|
|
531
|
+
if list.include?(opt)
|
532
|
+
@session << "--#{opt}"
|
533
|
+
elsif opt.match(/^depth=(\d+)$/)
|
534
|
+
@session << "--depth=#{$1}"
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
539
|
def append_commit(val)
|
540
540
|
val = val.to_s.strip
|
541
541
|
val.empty? ? 'HEAD' : val
|
@@ -33,6 +33,8 @@ module Squared
|
|
33
33
|
run: nil
|
34
34
|
}.freeze
|
35
35
|
|
36
|
+
attr_reader :package
|
37
|
+
|
36
38
|
def initialize(name, path, workspace, *, **kwargs)
|
37
39
|
super
|
38
40
|
initialize_script(REF)
|
@@ -43,6 +45,7 @@ module Squared
|
|
43
45
|
else
|
44
46
|
@output[1] = (@script && @script[:run]) || workspace.script
|
45
47
|
end
|
48
|
+
@package = base_path('package.json')
|
46
49
|
@dev = workspace.bool_match(env('BUILD', suffix: 'DEV'), kwargs.delete(:dev))
|
47
50
|
@prod = workspace.bool_match(env('BUILD', suffix: 'PROD'), kwargs.delete(:prod))
|
48
51
|
@pm = {}
|
@@ -71,7 +74,7 @@ module Squared
|
|
71
74
|
when :install
|
72
75
|
desc format_desc(action, flag)
|
73
76
|
task flag do
|
74
|
-
|
77
|
+
depend(flag, override: true)
|
75
78
|
end
|
76
79
|
when :outdated
|
77
80
|
desc format_desc(action, flag, %w[prune dry-run], req: 'opts?')
|
@@ -129,15 +132,15 @@ module Squared
|
|
129
132
|
|
130
133
|
from = base_path(from)
|
131
134
|
dest = dest.join(subdir, into || project)
|
132
|
-
warn "cp #{from.join(glob)} #{dest}"
|
135
|
+
log.warn "cp #{from.join(glob)} #{dest}"
|
133
136
|
copy_d(from, dest, glob: glob, verbose: verbose?)
|
134
137
|
end
|
135
138
|
end
|
136
139
|
|
137
|
-
def depend(flag = nil)
|
138
|
-
if @depend
|
140
|
+
def depend(flag = nil, override: false)
|
141
|
+
if @depend && !override
|
139
142
|
super
|
140
|
-
|
143
|
+
elsif outdated?
|
141
144
|
frozen = flag == :frozen
|
142
145
|
force = flag == :force
|
143
146
|
dedupe = flag == :dedupe
|
@@ -200,10 +203,10 @@ module Squared
|
|
200
203
|
require 'json'
|
201
204
|
rev ||= prod? ? :patch : :minor
|
202
205
|
cmd = pnpm? ? 'pnpm outdated' : 'npm outdated'
|
203
|
-
print_item format_banner(message("#{cmd}#{opts.include?('dry-run') ? ' --dry-run' : ''}"),
|
206
|
+
print_item format_banner(message("#{cmd}#{opts.include?('dry-run') ? ' --dry-run' : ''}"), multiple: true)
|
204
207
|
pwd = Dir.pwd
|
205
208
|
Dir.chdir(path)
|
206
|
-
info cmd
|
209
|
+
log.info cmd
|
207
210
|
data = `#{cmd} --json --loglevel=error`
|
208
211
|
Dir.chdir(pwd)
|
209
212
|
json = JSON.parse(doc = package.read)
|
@@ -366,7 +369,7 @@ module Squared
|
|
366
369
|
end
|
367
370
|
|
368
371
|
def depend?
|
369
|
-
|
372
|
+
outdated? || !!@depend
|
370
373
|
end
|
371
374
|
|
372
375
|
def copy?
|
@@ -465,12 +468,6 @@ module Squared
|
|
465
468
|
end
|
466
469
|
end
|
467
470
|
end
|
468
|
-
|
469
|
-
private
|
470
|
-
|
471
|
-
def package
|
472
|
-
@package ||= base_path('package.json')
|
473
|
-
end
|
474
471
|
end
|
475
472
|
end
|
476
473
|
end
|
@@ -6,7 +6,11 @@ module Squared
|
|
6
6
|
class Python < Git
|
7
7
|
REF = :python
|
8
8
|
REQUIREMENTS = %w[requirements.txt pyproject.toml setup.py].freeze
|
9
|
-
|
9
|
+
OPT_USER = %w[pre dry-run].freeze
|
10
|
+
OPT_FORCE = [*OPT_USER, 'user'].freeze
|
11
|
+
OPT_UPGRADE = [*OPT_FORCE, 'eager'].freeze
|
12
|
+
OPT_GENERAL = %w{venv isolated no-cache [v]erbose}.freeze
|
13
|
+
private_constant :REF, :REQUIREMENTS, :OPT_USER, :OPT_FORCE, :OPT_UPGRADE, :OPT_GENERAL
|
10
14
|
|
11
15
|
class << self
|
12
16
|
def populate(*); end
|
@@ -29,13 +33,17 @@ module Squared
|
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
36
|
+
attr_reader :requirements
|
37
|
+
|
32
38
|
def initialize(name, path, workspace, *, **kwargs)
|
33
39
|
super
|
40
|
+
@reqindex = REQUIREMENTS.index { |file| base_path(file).exist? } || 0
|
41
|
+
@requirements = base_path(REQUIREMENTS[@reqindex])
|
34
42
|
initialize_build(REF, **kwargs)
|
35
43
|
end
|
36
44
|
|
37
45
|
@@tasks[REF] = {
|
38
|
-
install: %i[upgrade force]
|
46
|
+
install: %i[user upgrade force]
|
39
47
|
}.freeze
|
40
48
|
|
41
49
|
def populate(*)
|
@@ -48,18 +56,17 @@ module Squared
|
|
48
56
|
flags.each do |flag|
|
49
57
|
case action
|
50
58
|
when :install
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
59
|
+
list = case flag
|
60
|
+
when :upgrade
|
61
|
+
OPT_UPGRADE
|
62
|
+
when :force
|
63
|
+
OPT_FORCE
|
64
|
+
else
|
65
|
+
OPT_USER
|
66
|
+
end
|
67
|
+
desc format_desc(action, flag, list + OPT_GENERAL)
|
61
68
|
task flag do |_, args|
|
62
|
-
|
69
|
+
depend(flag, opts: collect_args(args, :opts), override: true)
|
63
70
|
end
|
64
71
|
end
|
65
72
|
end
|
@@ -68,26 +75,25 @@ module Squared
|
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
71
|
-
def depend(flag = nil, opts: [])
|
72
|
-
if @depend
|
78
|
+
def depend(flag = nil, opts: [], override: false)
|
79
|
+
if @depend && !override
|
73
80
|
super
|
74
81
|
elsif outdated?
|
75
|
-
case install_type
|
82
|
+
case (type = install_type)
|
76
83
|
when 1, 2
|
77
84
|
cmd = pip_session 'install'
|
78
85
|
case flag
|
86
|
+
when :user
|
87
|
+
cmd << '--user'
|
88
|
+
append_general opts, OPT_USER
|
79
89
|
when :upgrade
|
80
90
|
cmd << '--upgrade'
|
81
|
-
|
91
|
+
append_general opts, OPT_UPGRADE
|
82
92
|
when :force
|
83
93
|
cmd << '--force-reinstall'
|
94
|
+
append_general opts, OPT_FORCE
|
84
95
|
end
|
85
|
-
cmd << '
|
86
|
-
cmd << '--require-virtualenv' if opts.include?('venv')
|
87
|
-
cmd << '--no-cache-dir' if opts.include?('no-cache')
|
88
|
-
cmd << '--dry-run' if opts.include?('dry-run')
|
89
|
-
append_nocolor
|
90
|
-
cmd << (install_type == 1 ? '-r requirements.txt' : '.')
|
96
|
+
cmd << (type == 1 ? '-r requirements.txt' : '.')
|
91
97
|
run(exception: workspace.exception)
|
92
98
|
when 3
|
93
99
|
run_s "#{@bin} setup.py install"
|
@@ -98,14 +104,11 @@ module Squared
|
|
98
104
|
def outdated(*); end
|
99
105
|
|
100
106
|
def install_type(*)
|
101
|
-
|
102
|
-
|
103
|
-
ret = REQUIREMENTS.index { |file| base_path(file).exist? }
|
104
|
-
@requirements = ret ? ret + 1 : 0
|
107
|
+
requirements.exist? ? @reqindex + 1 : 0
|
105
108
|
end
|
106
109
|
|
107
110
|
def depend?
|
108
|
-
|
111
|
+
outdated? || !!@depend
|
109
112
|
end
|
110
113
|
|
111
114
|
def outdated?
|
@@ -117,6 +120,30 @@ module Squared
|
|
117
120
|
def pip_session(*cmd)
|
118
121
|
session('pip', *cmd)
|
119
122
|
end
|
123
|
+
|
124
|
+
def append_general(opts, list = [])
|
125
|
+
list += OPT_GENERAL
|
126
|
+
opts.each do |opt|
|
127
|
+
next unless (v = opt.match(/^v+$/)) || list.include?(opt)
|
128
|
+
|
129
|
+
@session << case opt
|
130
|
+
when 'eager'
|
131
|
+
'--upgrade-strategy=eager'
|
132
|
+
when 'venv'
|
133
|
+
'--require-virtualenv'
|
134
|
+
when 'no-cache'
|
135
|
+
'--no-cache-dir'
|
136
|
+
else
|
137
|
+
(v ? "-#{v[0]}" : "--#{opt}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
@session << '--user' if env('PIP_USER')
|
141
|
+
@session << '--no-input' if env('PIP_NO_INPUT')
|
142
|
+
if (val = env('PIP_PROXY'))
|
143
|
+
@session << "--proxy=#{shell_escape(val, quote: true)}"
|
144
|
+
end
|
145
|
+
append_nocolor
|
146
|
+
end
|
120
147
|
end
|
121
148
|
end
|
122
149
|
end
|
@@ -7,7 +7,7 @@ module Squared
|
|
7
7
|
REF = :ruby
|
8
8
|
GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
|
9
9
|
OPT_INSTALL = %w[no-cache force quiet verbose].freeze
|
10
|
-
OPT_UPDATE = %w[redownload local strict conservative quiet verbose].freeze
|
10
|
+
OPT_UPDATE = %w[redownload local strict conservative group=s quiet verbose].freeze
|
11
11
|
private_constant :REF, :GEMFILE, :OPT_INSTALL, :OPT_UPDATE
|
12
12
|
|
13
13
|
class << self
|
@@ -33,11 +33,15 @@ module Squared
|
|
33
33
|
rake: nil
|
34
34
|
}.freeze
|
35
35
|
|
36
|
+
attr_reader :gemfile
|
37
|
+
|
36
38
|
def initialize(name, path, workspace, *, **kwargs)
|
37
39
|
super
|
38
40
|
initialize_build(REF, **kwargs)
|
39
41
|
@version = env('BUILD', suffix: 'VERSION', strict: true) || kwargs.delete(:version)
|
40
42
|
@autodetect = kwargs.key?(:autodetect) ? kwargs.delete(:autodetect) : false
|
43
|
+
index = GEMFILE.index { |file| base_path(file).exist? } || 0
|
44
|
+
@gemfile = base_path(GEMFILE[index])
|
41
45
|
return if !@output[0].nil? || !@copy.nil? || @version || @autodetect || (file = rakefile).nil?
|
42
46
|
|
43
47
|
begin
|
@@ -51,7 +55,7 @@ module Squared
|
|
51
55
|
break
|
52
56
|
end
|
53
57
|
rescue StandardError => e
|
54
|
-
error e
|
58
|
+
log.error e
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
@@ -80,12 +84,12 @@ module Squared
|
|
80
84
|
when :'with-g', :'without-g'
|
81
85
|
desc format_desc(action, flag, 'group+')
|
82
86
|
task flag, [:group] do |_, args|
|
83
|
-
|
87
|
+
depend(flag, group: collect_args(args, :group), override: true)
|
84
88
|
end
|
85
89
|
else
|
86
90
|
desc format_desc(action, flag, OPT_INSTALL)
|
87
91
|
task flag, [:opts] do |_, args|
|
88
|
-
|
92
|
+
depend(flag, opts: collect_args(args, :opts), override: true)
|
89
93
|
end
|
90
94
|
end
|
91
95
|
when :update
|
@@ -106,10 +110,10 @@ module Squared
|
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
109
|
-
def depend(flag = nil, opts: [], group: [])
|
110
|
-
if @depend
|
113
|
+
def depend(flag = nil, opts: [], group: [], override: false)
|
114
|
+
if @depend && !override
|
111
115
|
super
|
112
|
-
|
116
|
+
elsif outdated?
|
113
117
|
case flag
|
114
118
|
when :redownload, :local, :'prefer-local'
|
115
119
|
cmd = bundle_session 'install'
|
@@ -130,14 +134,15 @@ module Squared
|
|
130
134
|
val
|
131
135
|
end}"
|
132
136
|
end
|
133
|
-
|
137
|
+
append_bundle opts, OPT_INSTALL
|
134
138
|
when :'with-g', :'without-g'
|
135
139
|
guard_params('install', flag, args: group)
|
136
140
|
cmd = gem_session 'install', '-g'
|
137
141
|
opt = flag.to_s.sub('-g', '')
|
138
|
-
group.each { |s| cmd << "--#{opt}=#{shell_escape(s)}" }
|
142
|
+
group.each { |s| cmd << "--#{opt}=#{shell_escape(s, quote: true)}" }
|
139
143
|
else
|
140
144
|
cmd = bundle_session 'install'
|
145
|
+
append_bundle
|
141
146
|
end
|
142
147
|
run(banner: banner?, exception: workspace.exception)
|
143
148
|
end
|
@@ -160,7 +165,7 @@ module Squared
|
|
160
165
|
a = base_path(val)
|
161
166
|
b = dest.join(val)
|
162
167
|
c = glob[i] || '**/*'
|
163
|
-
warn "cp #{a.join(c)} #{b}"
|
168
|
+
log.warn "cp #{a.join(c)} #{b}"
|
164
169
|
copy_d(a, b, glob: c, verbose: verbose?)
|
165
170
|
end
|
166
171
|
end
|
@@ -173,7 +178,7 @@ module Squared
|
|
173
178
|
when :all, :major, :patch, :minor
|
174
179
|
cmd << "--#{flag}"
|
175
180
|
end
|
176
|
-
|
181
|
+
append_bundle opts, OPT_UPDATE
|
177
182
|
run(banner: banner?, exception: workspace.exception)
|
178
183
|
end
|
179
184
|
|
@@ -203,7 +208,7 @@ module Squared
|
|
203
208
|
end
|
204
209
|
|
205
210
|
def copy?
|
206
|
-
return true if @copy
|
211
|
+
return true if @copy.is_a?(::String) || @copy&.fetch(:gemdir, nil)
|
207
212
|
return gemdir? if @gemdir
|
208
213
|
|
209
214
|
gempath = -> { "gems#{::File::SEPARATOR}#{project}-#{@version}" }
|
@@ -213,11 +218,11 @@ module Squared
|
|
213
218
|
end
|
214
219
|
return false unless @autodetect
|
215
220
|
|
216
|
-
|
221
|
+
unsafe = ->(hint) { raise ArgumentError, message('failed to parse', hint: hint) }
|
217
222
|
begin
|
218
223
|
out = `gem -C #{shell_quote(path)} list --local -d #{project}`
|
219
224
|
data = /#{Regexp.escape(project)} \(([^)]+)\)/.match(out)
|
220
|
-
|
225
|
+
unsafe.('version') unless data
|
221
226
|
ver = data[1].split(/\s*,\s*/)
|
222
227
|
if @version
|
223
228
|
ver.unshift(@version)
|
@@ -227,14 +232,14 @@ module Squared
|
|
227
232
|
data = /\(#{Regexp.escape(v)}(?:,[^)]+|\b)\):([^\n]+)/.match(out)
|
228
233
|
next unless data
|
229
234
|
|
230
|
-
warn "using version #{v} (given #{@version})" if @version && @version != v
|
235
|
+
log.warn "using version #{v} (given #{@version})" if @version && @version != v
|
231
236
|
@version = v
|
232
237
|
break
|
233
238
|
end
|
234
|
-
|
239
|
+
unsafe.('path') unless data
|
235
240
|
@gemdir = Pathname.new(data[1].strip).join(gempath.())
|
236
241
|
rescue StandardError => e
|
237
|
-
error e
|
242
|
+
log.error e
|
238
243
|
@version = nil
|
239
244
|
@gemdir = nil
|
240
245
|
@autodetect = false
|
@@ -244,11 +249,11 @@ module Squared
|
|
244
249
|
end
|
245
250
|
|
246
251
|
def depend?
|
247
|
-
|
252
|
+
outdated? || !!@depend
|
248
253
|
end
|
249
254
|
|
250
255
|
def outdated?
|
251
|
-
|
256
|
+
gemfile.exist?
|
252
257
|
end
|
253
258
|
|
254
259
|
def dev?
|
@@ -257,11 +262,20 @@ module Squared
|
|
257
262
|
|
258
263
|
private
|
259
264
|
|
260
|
-
def
|
265
|
+
def append_bundle(opts = nil, list = nil)
|
261
266
|
if (val = env('BUNDLE_JOBS')).to_i > 0
|
262
267
|
@session << "-j#{val}"
|
263
268
|
end
|
264
|
-
|
269
|
+
@session << '--norc' if env('BUNDLE_NORC')
|
270
|
+
return unless opts && list
|
271
|
+
|
272
|
+
opts.each do |opt|
|
273
|
+
if list.include?(opt)
|
274
|
+
@session << "--#{opt}"
|
275
|
+
elsif opt.match(/^g(?:roup)?=(.+)$/)
|
276
|
+
@session << "--group=#{shell_escape($1, quote: true)}"
|
277
|
+
end
|
278
|
+
end
|
265
279
|
end
|
266
280
|
|
267
281
|
def gem_session(*cmd)
|
@@ -11,15 +11,16 @@ module Squared
|
|
11
11
|
|
12
12
|
TASK_NAME = {
|
13
13
|
build: [],
|
14
|
-
|
14
|
+
refresh: [],
|
15
15
|
depend: [],
|
16
16
|
outdated: [],
|
17
|
-
refresh: [],
|
18
17
|
doc: [],
|
19
18
|
test: [],
|
19
|
+
copy: [],
|
20
20
|
clean: []
|
21
21
|
}
|
22
22
|
TASK_BASE = {}
|
23
|
+
TASK_KEYS = TASK_NAME.keys.freeze
|
23
24
|
private_constant :TASK_NAME, :TASK_BASE
|
24
25
|
|
25
26
|
class << self
|
@@ -44,7 +45,7 @@ module Squared
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def to_s
|
47
|
-
/[^:]
|
48
|
+
super.to_s.match(/[^:]+$/)[0]
|
48
49
|
end
|
49
50
|
|
50
51
|
attr_reader :project_kind
|
@@ -52,7 +53,7 @@ module Squared
|
|
52
53
|
|
53
54
|
@project_kind = []
|
54
55
|
|
55
|
-
attr_reader :main, :root, :home, :series, :theme
|
56
|
+
attr_reader :main, :root, :home, :series, :theme, :sync, :multiple, :parallel
|
56
57
|
attr_accessor :manifest, :manifest_url, :exception, :pipe, :verbose, :warning
|
57
58
|
|
58
59
|
def initialize(main, *, common: true, **)
|
@@ -91,7 +92,6 @@ module Squared
|
|
91
92
|
end
|
92
93
|
@root ||= @home.parent
|
93
94
|
@series = TASK_NAME.dup
|
94
|
-
@theme = common ? __get__(:theme)[:workspace] : {}
|
95
95
|
@project = {}
|
96
96
|
@script = {
|
97
97
|
group: {},
|
@@ -103,14 +103,18 @@ module Squared
|
|
103
103
|
@exception = !env('PIPE_FAIL', ignore: '0').nil?
|
104
104
|
@pipe = !env('PIPE_OUT', ignore: '0').nil?
|
105
105
|
@verbose = !@pipe
|
106
|
-
@warning = !empty?(@root,
|
106
|
+
@warning = !empty?(@root, repo: false)
|
107
|
+
@sync = []
|
108
|
+
@multiple = []
|
109
|
+
@parallel = []
|
110
|
+
@theme = common && @verbose ? __get__(:theme)[:workspace] : {}
|
107
111
|
end
|
108
112
|
|
109
113
|
def build(**kwargs)
|
110
114
|
return unless enabled?
|
111
115
|
|
112
116
|
default = kwargs[:default]
|
113
|
-
|
117
|
+
multi = env('REPO_SYNC', ignore: '0') ? [] : kwargs.fetch(:parallel, []).map!(&:to_sym)
|
114
118
|
|
115
119
|
group = {}
|
116
120
|
parent = {}
|
@@ -182,14 +186,13 @@ module Squared
|
|
182
186
|
parse_opts.(args)
|
183
187
|
stage ||= :all
|
184
188
|
repo[:sync].invoke
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
proj.has?(:dev) ? proj.refresh : proj.build
|
189
|
+
@project.select do |_, proj|
|
190
|
+
if proj.enabled?
|
191
|
+
proj.depend
|
192
|
+
proj.build?
|
193
|
+
end
|
191
194
|
end
|
192
|
-
|
195
|
+
.each_value { |proj| proj.has?(:dev) ? proj.refresh : proj.build }
|
193
196
|
end
|
194
197
|
|
195
198
|
desc status.("init[manifest?=#{target},{0}]", target)
|
@@ -235,20 +238,27 @@ module Squared
|
|
235
238
|
series.each do |key, items|
|
236
239
|
next if items.empty?
|
237
240
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
241
|
+
s = key.to_s
|
242
|
+
if items.size > 1
|
243
|
+
multiple << s
|
244
|
+
unless (valid = multi.include?(key))
|
245
|
+
group = key.to_s
|
246
|
+
valid = multi.include?(group.split(':').first.to_sym) if group.include?(':')
|
247
|
+
end
|
248
|
+
if valid
|
249
|
+
desc "#{key} (thread)"
|
250
|
+
multitask key => items
|
251
|
+
parallel << s
|
252
|
+
|
253
|
+
desc "#{key} (sync)"
|
254
|
+
task "#{key}:sync": items
|
255
|
+
sync << "#{key}:sync"
|
256
|
+
multiple << "#{key}:sync"
|
257
|
+
next
|
258
|
+
end
|
251
259
|
end
|
260
|
+
desc s
|
261
|
+
task key => items
|
252
262
|
end
|
253
263
|
|
254
264
|
yield self if block_given?
|
@@ -259,6 +269,7 @@ module Squared
|
|
259
269
|
@manifest = manifest
|
260
270
|
script = case (val = env('REPO_BUILD'))
|
261
271
|
when 'verbose'
|
272
|
+
@verbose = true
|
262
273
|
run ? "#{run}:verbose" : nil
|
263
274
|
when 'silent'
|
264
275
|
@verbose = false
|
@@ -273,7 +284,9 @@ module Squared
|
|
273
284
|
when '1'
|
274
285
|
@warning = true
|
275
286
|
end
|
276
|
-
|
287
|
+
return self unless script
|
288
|
+
|
289
|
+
run(script, dev: bool_match(env('REPO_DEV'), dev), prod: bool_match(env('REPO_DEV'), prod))
|
277
290
|
end
|
278
291
|
|
279
292
|
def run(script, group: nil, ref: nil, **kwargs)
|
@@ -303,9 +316,8 @@ module Squared
|
|
303
316
|
script_command :test, script, group, ref
|
304
317
|
end
|
305
318
|
|
306
|
-
def add(name, path = nil, **kwargs)
|
319
|
+
def add(name, path = nil, ref: nil, **kwargs)
|
307
320
|
path = root_path((path || name).to_s)
|
308
|
-
ref = kwargs[:ref]
|
309
321
|
project = if !ref.is_a?(::Class)
|
310
322
|
Workspace.find(path: path, ref: ref)
|
311
323
|
elsif ref < Project::Base
|
@@ -317,6 +329,27 @@ module Squared
|
|
317
329
|
self
|
318
330
|
end
|
319
331
|
|
332
|
+
def group(name, path, **kwargs)
|
333
|
+
root_path(path).children.map do |ent|
|
334
|
+
next unless (dir = Pathname.new(ent)).directory?
|
335
|
+
|
336
|
+
index = 0
|
337
|
+
basename = dir.basename.to_s.to_sym
|
338
|
+
override = kwargs.delete(basename)
|
339
|
+
while @project[basename]
|
340
|
+
index += 1
|
341
|
+
basename = :"#{basename}-#{index}"
|
342
|
+
end
|
343
|
+
[basename, dir, override]
|
344
|
+
end
|
345
|
+
.each do |basename, dir, override|
|
346
|
+
opts = kwargs.dup
|
347
|
+
opts.merge!(override) if override
|
348
|
+
add(basename, dir, group: name, **opts)
|
349
|
+
end
|
350
|
+
self
|
351
|
+
end
|
352
|
+
|
320
353
|
def compose(name, &blk)
|
321
354
|
namespace(name, &blk)
|
322
355
|
self
|
@@ -360,8 +393,7 @@ module Squared
|
|
360
393
|
|
361
394
|
def read_manifest(*)
|
362
395
|
require 'rexml/document'
|
363
|
-
file = root_path('.repo/manifest.xml')
|
364
|
-
return unless file.exist?
|
396
|
+
return unless (file = root_path('.repo/manifest.xml')).exist?
|
365
397
|
|
366
398
|
doc = REXML::Document.new(file.read)
|
367
399
|
doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
|
@@ -408,19 +440,29 @@ module Squared
|
|
408
440
|
!manifest_url.nil? && (empty?(root) || @override)
|
409
441
|
end
|
410
442
|
|
411
|
-
def
|
412
|
-
|
413
|
-
next unless item.already_invoked
|
443
|
+
def multiple?(val = nil)
|
444
|
+
return multiple.include?(val) && invoked?(val) if val
|
414
445
|
|
415
|
-
|
416
|
-
|
446
|
+
::Rake::Task.tasks.any? { |item| item.already_invoked && multiple.include?(item.name) }
|
447
|
+
end
|
448
|
+
|
449
|
+
def sync?(val = nil)
|
450
|
+
return sync.include?(val) && invoked?(val) if val
|
451
|
+
|
452
|
+
::Rake::Task.tasks.any? { |item| item.already_invoked && sync.include?(item.name) }
|
453
|
+
end
|
454
|
+
|
455
|
+
def parallel?(val = nil)
|
456
|
+
return parallel.include?(val) && invoked?(val) if val
|
457
|
+
|
458
|
+
::Rake::Task.tasks.any? { |item| item.already_invoked && parallel.include?(item.name) }
|
417
459
|
end
|
418
460
|
|
419
|
-
def empty?(dir,
|
420
|
-
return true if dir.empty? || (
|
461
|
+
def empty?(dir, repo: true)
|
462
|
+
return true if dir.empty? || (repo && dir.join('.repo').directory?)
|
421
463
|
return true if dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__
|
422
464
|
|
423
|
-
dir == root && !env('REPO_ROOT').nil? && root.children.none? do |path|
|
465
|
+
dir.to_s == root.to_s && !env('REPO_ROOT').nil? && root.children.none? do |path|
|
424
466
|
path.directory? && !path.basename.to_s.start_with?('.') && path.to_s != home.to_s
|
425
467
|
end
|
426
468
|
end
|
@@ -430,7 +472,7 @@ module Squared
|
|
430
472
|
end
|
431
473
|
|
432
474
|
def dev?(script: nil, pat: nil, global: nil)
|
433
|
-
with?(:dev, script: script, pat: pat, global: (pat.nil? && global.nil?)
|
475
|
+
with?(:dev, script: script, pat: pat, global: global || (pat.nil? && global.nil?))
|
434
476
|
end
|
435
477
|
|
436
478
|
def prod?(script: nil, pat: nil, global: false)
|
@@ -441,7 +483,7 @@ module Squared
|
|
441
483
|
|
442
484
|
protected
|
443
485
|
|
444
|
-
def confirm(msg, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
|
486
|
+
def confirm(msg, agree: 'Y', cancel: 'N', default: nil, attempts: 5, timeout: 15)
|
445
487
|
require 'readline'
|
446
488
|
require 'timeout'
|
447
489
|
Timeout.timeout(ENV.fetch('REPO_TIMEOUT', timeout).to_i) do
|
@@ -454,6 +496,14 @@ module Squared
|
|
454
496
|
break
|
455
497
|
when cancel
|
456
498
|
break
|
499
|
+
when ''
|
500
|
+
case default
|
501
|
+
when agree
|
502
|
+
ret = true
|
503
|
+
break
|
504
|
+
when cancel
|
505
|
+
break
|
506
|
+
end
|
457
507
|
end
|
458
508
|
attempts -= 1
|
459
509
|
exit 1 unless attempts >= 0
|
@@ -484,15 +534,16 @@ module Squared
|
|
484
534
|
def repo_prompt(path)
|
485
535
|
return false unless path.directory?
|
486
536
|
|
487
|
-
confirm
|
537
|
+
confirm("#{log_title(:warn)} \"#{sub_style(path, :bold)}\" is not empty. Continue with installation? [y/N] ",
|
538
|
+
default: 'N')
|
488
539
|
end
|
489
540
|
|
490
541
|
def with?(state, script: nil, pat: nil, global: false)
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
pat.match?(script
|
542
|
+
if global
|
543
|
+
pat = @script[state] if pat.nil?
|
544
|
+
script ||= @script[:build]
|
545
|
+
end
|
546
|
+
pat.is_a?(::Regexp) ? pat.match?(script) : pat == true
|
496
547
|
end
|
497
548
|
end
|
498
549
|
end
|
data/lib/squared/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- An Pham
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|