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,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Workspace
|
5
|
+
module Project
|
6
|
+
class Python < Git
|
7
|
+
REF = :python
|
8
|
+
REQUIREMENTS = %w[requirements.txt pyproject.toml setup.py].freeze
|
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
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def populate(*); end
|
17
|
+
|
18
|
+
def tasks
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def venv?
|
23
|
+
val = ENV['VIRTUAL_ENV']
|
24
|
+
!val.nil? && Dir.exist?(val)
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_a?(val)
|
28
|
+
if (val = as_path(val))
|
29
|
+
REQUIREMENTS.any? { |file| val.join(file).exist? }
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :requirements
|
37
|
+
|
38
|
+
def initialize(name, path, workspace, *, **kwargs)
|
39
|
+
super
|
40
|
+
@reqindex = REQUIREMENTS.index { |file| base_path(file).exist? } || 0
|
41
|
+
@requirements = base_path(REQUIREMENTS[@reqindex])
|
42
|
+
initialize_build(REF, **kwargs)
|
43
|
+
end
|
44
|
+
|
45
|
+
@@tasks[REF] = {
|
46
|
+
install: %i[user upgrade force]
|
47
|
+
}.freeze
|
48
|
+
|
49
|
+
def populate(*)
|
50
|
+
super
|
51
|
+
return unless outdated?
|
52
|
+
|
53
|
+
namespace name do
|
54
|
+
@@tasks[REF].each do |action, flags|
|
55
|
+
namespace action do
|
56
|
+
flags.each do |flag|
|
57
|
+
case action
|
58
|
+
when :install
|
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)
|
68
|
+
task flag do |_, args|
|
69
|
+
depend(flag, opts: collect_args(args, :opts), override: true)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def depend(flag = nil, opts: [], override: false)
|
79
|
+
if @depend && !override
|
80
|
+
super
|
81
|
+
elsif outdated?
|
82
|
+
case (type = install_type)
|
83
|
+
when 1, 2
|
84
|
+
cmd = pip_session 'install'
|
85
|
+
case flag
|
86
|
+
when :user
|
87
|
+
cmd << '--user'
|
88
|
+
append_general opts, OPT_USER
|
89
|
+
when :upgrade
|
90
|
+
cmd << '--upgrade'
|
91
|
+
append_general opts, OPT_UPGRADE
|
92
|
+
when :force
|
93
|
+
cmd << '--force-reinstall'
|
94
|
+
append_general opts, OPT_FORCE
|
95
|
+
end
|
96
|
+
cmd << (type == 1 ? '-r requirements.txt' : '.')
|
97
|
+
run(exception: workspace.exception, sync: invoked_sync?('depend'))
|
98
|
+
when 3
|
99
|
+
run_s("#{@bin} setup.py install", sync: invoked_sync?('depend'))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def outdated(*); end
|
105
|
+
|
106
|
+
def install_type(*)
|
107
|
+
requirements.exist? ? @reqindex + 1 : 0
|
108
|
+
end
|
109
|
+
|
110
|
+
def depend?
|
111
|
+
outdated? || !!@depend
|
112
|
+
end
|
113
|
+
|
114
|
+
def outdated?
|
115
|
+
install_type > 0
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def pip_session(*cmd)
|
121
|
+
session('pip', *cmd)
|
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
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Squared
|
4
|
-
module
|
4
|
+
module Workspace
|
5
5
|
module Project
|
6
6
|
class Ruby < Git
|
7
7
|
REF = :ruby
|
@@ -33,17 +33,21 @@ module Squared
|
|
33
33
|
rake: nil
|
34
34
|
}.freeze
|
35
35
|
|
36
|
-
|
36
|
+
attr_reader :gemfile
|
37
|
+
|
38
|
+
def initialize(name, path, workspace, *, version: nil, autodetect: false, **kwargs)
|
37
39
|
super
|
38
40
|
initialize_build(REF, **kwargs)
|
39
|
-
@version = env('BUILD', suffix: 'VERSION', strict: true) ||
|
40
|
-
@autodetect =
|
41
|
+
@version = env('BUILD', suffix: 'VERSION', strict: true) || version
|
42
|
+
@autodetect = autodetect
|
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
|
44
48
|
pat = %r{\brequire\s+(["'])bundler/gem_tasks\1}
|
45
49
|
File.foreach(file) do |line|
|
46
|
-
next unless line
|
50
|
+
next unless line =~ pat
|
47
51
|
|
48
52
|
@output[0] = 'bundle exec rake build'
|
49
53
|
@copy = 'bundle exec rake install'
|
@@ -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
|
|
@@ -112,8 +116,7 @@ module Squared
|
|
112
116
|
elsif outdated?
|
113
117
|
case flag
|
114
118
|
when :redownload, :local, :'prefer-local'
|
115
|
-
cmd = bundle_session 'install'
|
116
|
-
cmd << "--#{flag}"
|
119
|
+
cmd = bundle_session 'install', "--#{flag}"
|
117
120
|
if (val = env('BUNDLE_TRUST_POLICY'))
|
118
121
|
cmd << "--trust-policy=#{case val
|
119
122
|
when '0'
|
@@ -130,14 +133,15 @@ module Squared
|
|
130
133
|
val
|
131
134
|
end}"
|
132
135
|
end
|
133
|
-
|
136
|
+
append_bundle opts, OPT_INSTALL
|
134
137
|
when :'with-g', :'without-g'
|
135
138
|
guard_params('install', flag, args: group)
|
136
139
|
cmd = gem_session 'install', '-g'
|
137
140
|
opt = flag.to_s.sub('-g', '')
|
138
|
-
group.each { |s| cmd << "--#{opt}=#{shell_escape(s)}" }
|
141
|
+
group.each { |s| cmd << "--#{opt}=#{shell_escape(s, quote: true)}" }
|
139
142
|
else
|
140
143
|
cmd = bundle_session 'install'
|
144
|
+
append_bundle
|
141
145
|
end
|
142
146
|
run(banner: banner?, exception: workspace.exception)
|
143
147
|
end
|
@@ -160,7 +164,7 @@ module Squared
|
|
160
164
|
a = base_path(val)
|
161
165
|
b = dest.join(val)
|
162
166
|
c = glob[i] || '**/*'
|
163
|
-
warn "cp #{a.join(c)} #{b}"
|
167
|
+
log.warn "cp #{a.join(c)} #{b}"
|
164
168
|
copy_d(a, b, glob: c, verbose: verbose?)
|
165
169
|
end
|
166
170
|
end
|
@@ -173,7 +177,7 @@ module Squared
|
|
173
177
|
when :all, :major, :patch, :minor
|
174
178
|
cmd << "--#{flag}"
|
175
179
|
end
|
176
|
-
|
180
|
+
append_bundle opts, OPT_UPDATE
|
177
181
|
run(banner: banner?, exception: workspace.exception)
|
178
182
|
end
|
179
183
|
|
@@ -203,7 +207,7 @@ module Squared
|
|
203
207
|
end
|
204
208
|
|
205
209
|
def copy?
|
206
|
-
return true if @copy
|
210
|
+
return true if @copy.is_a?(::String) || @copy&.fetch(:gemdir, nil)
|
207
211
|
return gemdir? if @gemdir
|
208
212
|
|
209
213
|
gempath = -> { "gems#{::File::SEPARATOR}#{project}-#{@version}" }
|
@@ -213,11 +217,11 @@ module Squared
|
|
213
217
|
end
|
214
218
|
return false unless @autodetect
|
215
219
|
|
216
|
-
|
220
|
+
unsafe = ->(hint) { raise_error('failed to parse', hint: hint) }
|
217
221
|
begin
|
218
222
|
out = `gem -C #{shell_quote(path)} list --local -d #{project}`
|
219
223
|
data = /#{Regexp.escape(project)} \(([^)]+)\)/.match(out)
|
220
|
-
|
224
|
+
unsafe.('version') unless data
|
221
225
|
ver = data[1].split(/\s*,\s*/)
|
222
226
|
if @version
|
223
227
|
ver.unshift(@version)
|
@@ -227,14 +231,14 @@ module Squared
|
|
227
231
|
data = /\(#{Regexp.escape(v)}(?:,[^)]+|\b)\):([^\n]+)/.match(out)
|
228
232
|
next unless data
|
229
233
|
|
230
|
-
warn "using version #{v} (given #{@version})" if @version && @version != v
|
234
|
+
log.warn "using version #{v} (given #{@version})" if @version && @version != v
|
231
235
|
@version = v
|
232
236
|
break
|
233
237
|
end
|
234
|
-
|
238
|
+
unsafe.('path') unless data
|
235
239
|
@gemdir = Pathname.new(data[1].strip).join(gempath.())
|
236
240
|
rescue StandardError => e
|
237
|
-
error e
|
241
|
+
log.error e
|
238
242
|
@version = nil
|
239
243
|
@gemdir = nil
|
240
244
|
@autodetect = false
|
@@ -244,13 +248,11 @@ module Squared
|
|
244
248
|
end
|
245
249
|
|
246
250
|
def depend?
|
247
|
-
|
251
|
+
outdated? || !!@depend
|
248
252
|
end
|
249
253
|
|
250
254
|
def outdated?
|
251
|
-
|
252
|
-
|
253
|
-
@outdated = GEMFILE.any? { |file| base_path(file).exist? }
|
255
|
+
gemfile.exist?
|
254
256
|
end
|
255
257
|
|
256
258
|
def dev?
|
@@ -259,15 +261,18 @@ module Squared
|
|
259
261
|
|
260
262
|
private
|
261
263
|
|
262
|
-
def
|
264
|
+
def append_bundle(opts = nil, list = nil)
|
263
265
|
if (val = env('BUNDLE_JOBS')).to_i > 0
|
264
266
|
@session << "-j#{val}"
|
265
267
|
end
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
268
|
+
@session << '--norc' if env('BUNDLE_NORC')
|
269
|
+
return unless opts && list
|
270
|
+
|
271
|
+
opts.each do |opt|
|
272
|
+
if list.include?(opt)
|
273
|
+
@session << "--#{opt}"
|
274
|
+
elsif opt.match(/^g(?:roup)?=(.+)$/)
|
275
|
+
@session << "--group=#{shell_escape($1, quote: true)}"
|
271
276
|
end
|
272
277
|
end
|
273
278
|
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Workspace
|
5
|
+
module Repo
|
6
|
+
include Common
|
7
|
+
include Format
|
8
|
+
include System
|
9
|
+
include Task
|
10
|
+
|
11
|
+
attr_accessor :warning
|
12
|
+
|
13
|
+
def repo(url, manifest = 'latest', run: nil, dev: nil, prod: nil)
|
14
|
+
@home = if (val = env('REPO_HOME'))
|
15
|
+
home = Pathname.new(val)
|
16
|
+
if @main == home.basename.to_s
|
17
|
+
@root = home.parent
|
18
|
+
if home.exist?
|
19
|
+
@root = nil unless home.directory?
|
20
|
+
elsif !@root.exist?
|
21
|
+
@root.mkpath
|
22
|
+
elsif !install?
|
23
|
+
@root = nil unless confirm_install
|
24
|
+
end
|
25
|
+
end
|
26
|
+
raise_error('REPO_HOME', val, hint: 'invalid') unless @root
|
27
|
+
|
28
|
+
home.realdirpath
|
29
|
+
elsif (val = env('REPO_ROOT'))
|
30
|
+
@root = Pathname.new(val).realdirpath
|
31
|
+
if !@root.exist?
|
32
|
+
@root.mkpath
|
33
|
+
elsif !install?
|
34
|
+
raise_error('REPO_ROOT', val, hint: 'exist') unless confirm_install
|
35
|
+
end
|
36
|
+
@root.join(@main).realdirpath
|
37
|
+
else
|
38
|
+
install?(pwd = Pathname.pwd) ? pwd.join(@main) : pwd
|
39
|
+
end
|
40
|
+
@root = @home.parent
|
41
|
+
@manifest_url = url
|
42
|
+
@manifest = manifest
|
43
|
+
if repo?
|
44
|
+
@script[:build] = case (val = env('REPO_BUILD'))
|
45
|
+
when 'verbose'
|
46
|
+
@verbose = true
|
47
|
+
"#{run}:verbose" if run
|
48
|
+
when 'silent'
|
49
|
+
@verbose = false
|
50
|
+
@warning = false
|
51
|
+
run
|
52
|
+
else
|
53
|
+
val || run
|
54
|
+
end
|
55
|
+
@script[:dev] = bool_match(env('REPO_DEV'), dev)
|
56
|
+
@script[:prod] = bool_match(env('REPO_PROD'), prod)
|
57
|
+
@warning = case env('REPO_WARN')
|
58
|
+
when '0'
|
59
|
+
false
|
60
|
+
when '1'
|
61
|
+
true
|
62
|
+
else
|
63
|
+
!empty?(@root)
|
64
|
+
end
|
65
|
+
@extensions << :__repo__
|
66
|
+
else
|
67
|
+
@script[:build] = run
|
68
|
+
@script[:dev] = dev
|
69
|
+
@script[:prod] = prod
|
70
|
+
end
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def repo?
|
77
|
+
!@manifest_url.nil? && (install? || !!@override)
|
78
|
+
end
|
79
|
+
|
80
|
+
def empty?(dir)
|
81
|
+
dir.empty? || (dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def __repo__(**kwargs)
|
87
|
+
kwargs.delete(:parallel) if env('REPO_SYNC', ignore: '0')
|
88
|
+
|
89
|
+
branch = env('REPO_MANIFEST') || read_manifest
|
90
|
+
target = branch || @manifest
|
91
|
+
stage = nil
|
92
|
+
failfast = true
|
93
|
+
cmd = []
|
94
|
+
newline = ARGV.index { |val| val.start_with?('repo:') }.to_i > 0
|
95
|
+
parse_opts = lambda do |args|
|
96
|
+
collect_args(args, :opts).each do |val|
|
97
|
+
case val
|
98
|
+
when 'no-fail'
|
99
|
+
failfast = false
|
100
|
+
when 'force'
|
101
|
+
cmd << '--force-checkout'
|
102
|
+
when 'rebase'
|
103
|
+
cmd << '--rebase'
|
104
|
+
when 'detach'
|
105
|
+
cmd << '--detach'
|
106
|
+
when 'gc'
|
107
|
+
cmd << '--auto-gc'
|
108
|
+
when 'no-update'
|
109
|
+
cmd << '--no-manifest-update'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
status = lambda do |val, alt = nil|
|
114
|
+
ver = branch || alt
|
115
|
+
ver ? message('repo', val.sub('{0}', 'opts*=force,rebase,detach,gc,no-update,no-fail'), ver) : 'inactive'
|
116
|
+
end
|
117
|
+
|
118
|
+
namespace 'repo' do |repo|
|
119
|
+
desc status.('all[{0}]')
|
120
|
+
task 'all', [:opts] do |_, args|
|
121
|
+
parse_opts.(args)
|
122
|
+
stage ||= 'all'
|
123
|
+
repo['sync'].invoke
|
124
|
+
@project.select do |_, proj|
|
125
|
+
if proj.enabled?
|
126
|
+
proj.depend
|
127
|
+
proj.build?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
.each_value { |proj| proj.has?(:dev) ? proj.refresh : proj.build }
|
131
|
+
end
|
132
|
+
|
133
|
+
desc status.("init[manifest?=#{target},{0}]", target)
|
134
|
+
task 'init', [:manifest, :opts] do |_, args|
|
135
|
+
parse_opts.(args)
|
136
|
+
stage = 'init'
|
137
|
+
puts if newline
|
138
|
+
system("repo init -u #{@manifest_url} -m #{args.manifest || target}.xml", chdir: root)
|
139
|
+
repo['all'].invoke
|
140
|
+
end
|
141
|
+
|
142
|
+
desc status.('sync[{0}]')
|
143
|
+
task 'sync', [:opts] do |_, args|
|
144
|
+
raise_error('repo is not initialized', 'rake repo:init', kind: LoadError) unless branch || stage == 'init'
|
145
|
+
|
146
|
+
parse_opts.(args)
|
147
|
+
cmd << "-j#{ENV.fetch('REPO_JOBS', ::Rake::CpuCounter.count)}"
|
148
|
+
cmd << '--fail-fast' if failfast
|
149
|
+
puts if newline && stage != 'init'
|
150
|
+
begin
|
151
|
+
shell("repo sync #{cmd.join(' ')}", chdir: root, exception: failfast)
|
152
|
+
rescue StandardError => e
|
153
|
+
emphasize(e, title: "rake stash repo:#{stage || 'sync'}")
|
154
|
+
raise
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def read_manifest
|
161
|
+
require 'rexml/document'
|
162
|
+
return unless (file = root_path('.repo/manifest.xml')).exist?
|
163
|
+
|
164
|
+
doc = REXML::Document.new(file.read)
|
165
|
+
doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
|
166
|
+
end
|
167
|
+
|
168
|
+
def confirm_install
|
169
|
+
return false unless @root.directory?
|
170
|
+
|
171
|
+
@override = confirm(
|
172
|
+
"#{log_title(:warn)} \"#{sub_style(@root, :bold)}\" is not empty. Continue with installation? [y/N] ",
|
173
|
+
default: 'N',
|
174
|
+
timeout: env('REPO_TIMEOUT', ignore: '0', default: 15)
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
178
|
+
def bool_match(val, pat)
|
179
|
+
case val
|
180
|
+
when nil, ''
|
181
|
+
pat
|
182
|
+
when '0'
|
183
|
+
false
|
184
|
+
when '1'
|
185
|
+
true
|
186
|
+
else
|
187
|
+
Regexp.new(val)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def install?(dir = @root)
|
192
|
+
return true if empty?(dir) || dir.join('.repo').directory?
|
193
|
+
return false unless dir == root && env('REPO_HOME').nil? && !env('REPO_ROOT').nil?
|
194
|
+
|
195
|
+
root.children.none? { |path| path.directory? && path.basename.to_s[0] != '.' && path.to_s != home.to_s }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
Application.include Repo
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Squared
|
6
|
+
module Workspace
|
7
|
+
class Series
|
8
|
+
include ::Rake::DSL
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
attr_reader :workspace, :sync, :multiple, :parallel
|
12
|
+
|
13
|
+
def_delegators :@data, :[], :each, :each_key, :keys, :fetch, :to_a, :to_s, :inspect, :merge!, :key?, :has_key?
|
14
|
+
|
15
|
+
def initialize(tasks, workspace, keys: Workspace::Application::WORKSPACE_KEYS)
|
16
|
+
if tasks.is_a?(Array)
|
17
|
+
@data = {}
|
18
|
+
tasks.each { |key| __set__ key }
|
19
|
+
else
|
20
|
+
@data = tasks.dup
|
21
|
+
end
|
22
|
+
@workspace = workspace
|
23
|
+
@keys = keys
|
24
|
+
@sync = []
|
25
|
+
@multiple = []
|
26
|
+
@parallel = []
|
27
|
+
@session = {
|
28
|
+
group: {},
|
29
|
+
parent: {},
|
30
|
+
id: []
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def __set__(key)
|
35
|
+
self[key.to_sym] ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
def populate(proj)
|
39
|
+
return unless @session
|
40
|
+
|
41
|
+
group, parent, id = @session.values
|
42
|
+
each do |key, items|
|
43
|
+
target = "#{proj.name}:#{key}"
|
44
|
+
if @keys.include?(key)
|
45
|
+
next unless proj.has?(key) || (target = workspace.task_base?(key, target))
|
46
|
+
else
|
47
|
+
next unless workspace.task_include?(proj, key)
|
48
|
+
end
|
49
|
+
if (g = proj.group)
|
50
|
+
id << g
|
51
|
+
(group[:"#{key}:#{g}"] ||= []).push(target)
|
52
|
+
else
|
53
|
+
items << target
|
54
|
+
end
|
55
|
+
next unless (b = find_base(proj)) && (name = b.to_sym.to_s) != g
|
56
|
+
|
57
|
+
id << name
|
58
|
+
(parent[:"#{key}:#{name}"] ||= []).push(target)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(key, *)
|
63
|
+
self[key]
|
64
|
+
end
|
65
|
+
|
66
|
+
def finalize!(thread = [])
|
67
|
+
thread.map!(&:to_s)
|
68
|
+
group, parent, id = @session.values
|
69
|
+
merge!(parent) if id.uniq.size > 1
|
70
|
+
merge!(group)
|
71
|
+
each do |key, items|
|
72
|
+
next if items.empty?
|
73
|
+
|
74
|
+
key = key.to_s
|
75
|
+
if items.size > 1
|
76
|
+
multiple << key
|
77
|
+
if thread.include?(key) || (key.include?(':') && thread.include?(key.split(':').first.to_sym))
|
78
|
+
desc "#{key} (thread)"
|
79
|
+
multitask key => items
|
80
|
+
parallel << key
|
81
|
+
|
82
|
+
desc "#{key} (sync)"
|
83
|
+
task "#{key}:sync": items
|
84
|
+
sync << "#{key}:sync"
|
85
|
+
multiple << "#{key}:sync"
|
86
|
+
next
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
desc key
|
91
|
+
task key => items
|
92
|
+
end
|
93
|
+
@session = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def has?(key)
|
97
|
+
!key.nil? && key?(key = key.to_sym) && !self[key].empty?
|
98
|
+
end
|
99
|
+
|
100
|
+
def multiple?(val = nil)
|
101
|
+
already_invoked?(multiple, val)
|
102
|
+
end
|
103
|
+
|
104
|
+
def sync?(val = nil)
|
105
|
+
already_invoked?(sync, val)
|
106
|
+
end
|
107
|
+
|
108
|
+
def parallel?(val = nil)
|
109
|
+
already_invoked?(parallel, val)
|
110
|
+
end
|
111
|
+
|
112
|
+
def respond_to_missing?(key, *)
|
113
|
+
key?(key)
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def already_invoked?(list, val)
|
119
|
+
return list.include?(val) && invoked?(val) if val
|
120
|
+
|
121
|
+
::Rake::Task.tasks.any? { |item| item.already_invoked && list.include?(item.name) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'common'
|
4
|
+
|
3
5
|
module Squared
|
4
|
-
module
|
6
|
+
module Workspace
|
5
7
|
class << self
|
6
8
|
def resolve(*args)
|
7
9
|
ret = args.map do |id|
|
@@ -35,5 +37,6 @@ module Squared
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
require_relative '
|
39
|
-
require_relative '
|
40
|
+
require_relative 'workspace/application'
|
41
|
+
require_relative 'workspace/series'
|
42
|
+
require_relative 'workspace/project'
|
data/lib/squared.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'squared/version'
|
4
|
-
require_relative 'squared/
|
5
|
-
require_relative 'squared/repo'
|
6
|
-
require_relative 'squared/config'
|
4
|
+
require_relative 'squared/workspace'
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
Workspace = Squared::Workspace
|
7
|
+
Project = Squared::Workspace::Project
|
8
|
+
|
9
|
+
Workspace::Application.implement(
|
10
|
+
Project::Git,
|
11
|
+
Project::Node,
|
12
|
+
Project::Python,
|
13
|
+
Project::Ruby
|
13
14
|
)
|