squared 0.0.1
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 +7 -0
- data/LICENSE +11 -0
- data/README.md +1347 -0
- data/README.ruby.md +50 -0
- data/lib/squared/common/class.rb +18 -0
- data/lib/squared/common/format.rb +151 -0
- data/lib/squared/common/shell.rb +40 -0
- data/lib/squared/common/system.rb +55 -0
- data/lib/squared/common/task.rb +27 -0
- data/lib/squared/common.rb +66 -0
- data/lib/squared/config.rb +240 -0
- data/lib/squared/repo/project/base.rb +357 -0
- data/lib/squared/repo/project/git.rb +521 -0
- data/lib/squared/repo/project/node.rb +394 -0
- data/lib/squared/repo/project/python.rb +104 -0
- data/lib/squared/repo/project/ruby.rb +277 -0
- data/lib/squared/repo/project.rb +49 -0
- data/lib/squared/repo/workspace.rb +427 -0
- data/lib/squared/repo.rb +39 -0
- data/lib/squared/version.rb +5 -0
- data/lib/squared.rb +13 -0
- data/squared.gemspec +29 -0
- metadata +95 -0
@@ -0,0 +1,427 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Repo
|
5
|
+
class Workspace
|
6
|
+
include Common
|
7
|
+
include Format
|
8
|
+
include System
|
9
|
+
include Task
|
10
|
+
include ::Rake::DSL
|
11
|
+
|
12
|
+
TASK_NAME = {
|
13
|
+
build: [],
|
14
|
+
copy: [],
|
15
|
+
depend: [],
|
16
|
+
outdated: [],
|
17
|
+
refresh: [],
|
18
|
+
doc: [],
|
19
|
+
clean: []
|
20
|
+
}
|
21
|
+
TASK_BASE = {}
|
22
|
+
private_constant :TASK_NAME, :TASK_BASE
|
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_NAME[val] = []
|
32
|
+
TASK_BASE[val] = 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
|
+
attr_reader :project_kind
|
46
|
+
end
|
47
|
+
|
48
|
+
@project_kind = []
|
49
|
+
|
50
|
+
attr_reader :main, :root, :home, :series
|
51
|
+
attr_accessor :script, :manifest, :manifest_url, :exception, :styles, :verbose
|
52
|
+
|
53
|
+
def initialize(main)
|
54
|
+
prompt = lambda do |path|
|
55
|
+
return false unless path.directory?
|
56
|
+
|
57
|
+
confirm "#{log_title(:warn)} \"#{sub_style(path, :bold)}\" is not empty. Continue with installation? [y/N] "
|
58
|
+
end
|
59
|
+
@main = main.to_s
|
60
|
+
@home = if (val = env('REPO_HOME'))
|
61
|
+
home = Pathname.new(val)
|
62
|
+
if @main == home.basename.to_s
|
63
|
+
@root = home.parent
|
64
|
+
if home.exist?
|
65
|
+
@root = nil unless home.directory?
|
66
|
+
elsif !@root.exist?
|
67
|
+
@root.mkpath
|
68
|
+
elsif !empty?(@root)
|
69
|
+
if prompt.(@root)
|
70
|
+
@override = true
|
71
|
+
else
|
72
|
+
@root = nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
raise ArgumentError, message('REPO_HOME', val, hint: 'invalid') unless @root
|
77
|
+
|
78
|
+
home.realdirpath
|
79
|
+
elsif (val = env('REPO_ROOT'))
|
80
|
+
@root = Pathname.new(val).realdirpath
|
81
|
+
if !@root.exist?
|
82
|
+
@root.mkpath
|
83
|
+
elsif !empty?(@root)
|
84
|
+
raise ArgumentError, message('REPO_ROOT', val, hint: 'exist') unless prompt.(@root)
|
85
|
+
|
86
|
+
@override = true
|
87
|
+
end
|
88
|
+
@root.join(@main).realdirpath
|
89
|
+
else
|
90
|
+
empty?(pwd = Pathname.pwd) ? pwd.join(@main) : pwd
|
91
|
+
end
|
92
|
+
@root ||= @home.parent
|
93
|
+
@series = TASK_NAME.dup
|
94
|
+
@styles = {}
|
95
|
+
@project = {}
|
96
|
+
@exception = !env('PIPE_FAIL', ignore: '0').nil?
|
97
|
+
@pipe = !env('PIPE_OUT', ignore: '0').nil?
|
98
|
+
@verbose = true
|
99
|
+
end
|
100
|
+
|
101
|
+
def repo(url, manifest = 'latest')
|
102
|
+
@manifest_url = url
|
103
|
+
@manifest = manifest
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def run(script, **kwargs)
|
108
|
+
@script = case (val = env('REPO_BUILD'))
|
109
|
+
when 'verbose'
|
110
|
+
"#{script}:verbose"
|
111
|
+
when 'silent'
|
112
|
+
@verbose = false
|
113
|
+
script
|
114
|
+
else
|
115
|
+
val || script
|
116
|
+
end
|
117
|
+
@dev = bool_match(env('REPO_DEV'), kwargs[:dev])
|
118
|
+
@prod = bool_match(env('REPO_PROD'), kwargs[:prod])
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def add(name, dir = nil, **kwargs)
|
123
|
+
path = (dir || name).to_s
|
124
|
+
ref = kwargs[:ref]
|
125
|
+
project = if !ref.is_a?(::Class)
|
126
|
+
Workspace.find(path: root_path(path), ref: ref)
|
127
|
+
elsif ref < Project::Base
|
128
|
+
ref
|
129
|
+
end
|
130
|
+
instance = (project || Project::Base).new(name, path, self, **kwargs)
|
131
|
+
@project[n = name.to_sym] = instance
|
132
|
+
get(:project)[n] = instance
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
def build(default: nil, parallel: [])
|
137
|
+
group = {}
|
138
|
+
parent = {}
|
139
|
+
incl = Set.new
|
140
|
+
@project.each do |name, proj|
|
141
|
+
next unless proj.enabled?
|
142
|
+
|
143
|
+
@series.each do |key, items|
|
144
|
+
target = "#{name}:#{key}"
|
145
|
+
case key
|
146
|
+
when :build, :refresh, :depend, :outdated, :doc, :copy, :clean
|
147
|
+
next unless proj.has?(key) || ::Rake::Task.task_defined?(target)
|
148
|
+
else
|
149
|
+
next unless task_defined?(proj, key)
|
150
|
+
end
|
151
|
+
if proj.group
|
152
|
+
incl << proj.group
|
153
|
+
(group[:"#{key}:#{proj.group}"] ||= []).push(target)
|
154
|
+
else
|
155
|
+
items << target
|
156
|
+
end
|
157
|
+
next unless (base = find_base(proj))
|
158
|
+
|
159
|
+
id = base.to_sym.to_s
|
160
|
+
next if id == proj.group
|
161
|
+
|
162
|
+
incl << id
|
163
|
+
(parent[:"#{key}:#{id}"] ||= []).push(target)
|
164
|
+
end
|
165
|
+
proj.populate
|
166
|
+
end
|
167
|
+
@series.merge!(parent) if incl.size > 1
|
168
|
+
@series.merge!(group)
|
169
|
+
if @manifest_url && (empty?(@root) || @override)
|
170
|
+
branch = env('REPO_MANIFEST') || read_manifest
|
171
|
+
target = branch || @manifest
|
172
|
+
stage = nil
|
173
|
+
failfast = true
|
174
|
+
cmd = []
|
175
|
+
newline = ARGV.index { |val| val.start_with?('repo:') }.to_i > 0
|
176
|
+
parse_opts = lambda do |args|
|
177
|
+
collect_args(args, :opts).each do |val|
|
178
|
+
case val
|
179
|
+
when 'no-fail'
|
180
|
+
failfast = false
|
181
|
+
when 'force'
|
182
|
+
cmd << '--force-checkout'
|
183
|
+
when 'rebase'
|
184
|
+
cmd << '--rebase'
|
185
|
+
when 'detach'
|
186
|
+
cmd << '--detach'
|
187
|
+
when 'gc'
|
188
|
+
cmd << '--auto-gc'
|
189
|
+
when 'no-update'
|
190
|
+
cmd << '--no-manifest-update'
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
status = lambda do |val, alt = nil|
|
195
|
+
ver = branch || alt
|
196
|
+
ver ? message('repo', val.sub('{0}', 'opts*=force,rebase,detach,gc,no-update,no-fail'), ver) : 'inactive'
|
197
|
+
end
|
198
|
+
|
199
|
+
namespace :repo do |repo|
|
200
|
+
desc status.('all[{0}]')
|
201
|
+
task :all, [:opts] do |_, args|
|
202
|
+
parse_opts.(args)
|
203
|
+
stage ||= :all
|
204
|
+
repo[:sync].invoke
|
205
|
+
# rubocop:disable Style/CombinableLoops
|
206
|
+
@project.each_value { |proj| proj.depend if proj.enabled? }
|
207
|
+
@project.each_value do |proj|
|
208
|
+
next unless proj.enabled? && proj.build?
|
209
|
+
|
210
|
+
proj.has?(:dev) ? proj.refresh : proj.build
|
211
|
+
end
|
212
|
+
# rubocop:enable Style/CombinableLoops
|
213
|
+
end
|
214
|
+
|
215
|
+
desc status.("init[manifest?=#{target},{0}]", target)
|
216
|
+
task :init, [:manifest, :opts] do |_, args|
|
217
|
+
parse_opts.(args)
|
218
|
+
stage = :init
|
219
|
+
puts if newline
|
220
|
+
system("repo init -u #{@manifest_url} -m #{args.manifest || target}.xml", chdir: @root)
|
221
|
+
repo[:all].invoke
|
222
|
+
end
|
223
|
+
|
224
|
+
desc status.('sync[{0}]')
|
225
|
+
task :sync, [:opts] do |_, args|
|
226
|
+
raise LoadError, message('repo is not initialized', 'rake repo:init') unless branch || stage == :init
|
227
|
+
|
228
|
+
parse_opts.(args)
|
229
|
+
cmd << "-j#{ENV.fetch('REPO_JOBS', ::Rake::CpuCounter.count)}"
|
230
|
+
cmd << '--fail-fast' if failfast
|
231
|
+
puts if newline && stage != :init
|
232
|
+
begin
|
233
|
+
shell("repo sync #{cmd.join(' ')}", chdir: @root, exception: failfast)
|
234
|
+
rescue StandardError => e
|
235
|
+
emphasize(e, title: "rake stash repo:#{stage || :sync}")
|
236
|
+
raise
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
return unless enabled?
|
242
|
+
|
243
|
+
multi = env('REPO_SYNC', ignore: '0') ? [] : parallel.map(&:to_sym)
|
244
|
+
output = dev? ? :refresh : :build
|
245
|
+
|
246
|
+
task default: default || output
|
247
|
+
|
248
|
+
desc 'all[git?=rebase|stash]'
|
249
|
+
task :all, [:git] do |_, args|
|
250
|
+
sync = ->(key) { multi.include?(key) ? :"#{key}:sync" : key }
|
251
|
+
pull = case args.git
|
252
|
+
when 'rebase'
|
253
|
+
sync.(:rebase)
|
254
|
+
when 'stash'
|
255
|
+
invoke sync.(:stash)
|
256
|
+
sync.(:pull)
|
257
|
+
else
|
258
|
+
sync.(:pull)
|
259
|
+
end
|
260
|
+
invoke(pull, exception: @exception)
|
261
|
+
invoke(output, exception: @exception)
|
262
|
+
end
|
263
|
+
|
264
|
+
desc 'init'
|
265
|
+
task init: [:depend, output]
|
266
|
+
|
267
|
+
@series.each do |key, items|
|
268
|
+
next if items.empty?
|
269
|
+
|
270
|
+
unless (valid = multi.include?(key))
|
271
|
+
group = key.to_s
|
272
|
+
valid = multi.include?(group.split(':').first.to_sym) if group.include?(':')
|
273
|
+
end
|
274
|
+
if valid
|
275
|
+
desc "#{key} (thread)"
|
276
|
+
multitask key => items
|
277
|
+
|
278
|
+
desc "#{key} (sync)"
|
279
|
+
task "#{key}:sync": items
|
280
|
+
else
|
281
|
+
desc key.to_s
|
282
|
+
task key => items
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def compose(name, &block)
|
288
|
+
namespace(name, &block)
|
289
|
+
self
|
290
|
+
end
|
291
|
+
|
292
|
+
def apply(&block)
|
293
|
+
instance_eval(&block)
|
294
|
+
self
|
295
|
+
end
|
296
|
+
|
297
|
+
def style(name, *args)
|
298
|
+
set = ->(k, v) { @styles[k.to_sym] = check_style(v, empty: false) }
|
299
|
+
if name.is_a?(Hash)
|
300
|
+
name.each { |k, v| set.(k, v || args.flatten) }
|
301
|
+
else
|
302
|
+
set.(name, args.flatten)
|
303
|
+
end
|
304
|
+
self
|
305
|
+
end
|
306
|
+
|
307
|
+
def env(key, equals: nil, ignore: nil)
|
308
|
+
ret = ENV.fetch("#{key}_#{@main.gsub(/[^\w]/, '_').upcase}", ENV[key]).to_s
|
309
|
+
return ret == equals.to_s if equals
|
310
|
+
|
311
|
+
ret.empty? || as_a(ignore).any? { |val| ret == val.to_s } ? nil : ret
|
312
|
+
end
|
313
|
+
|
314
|
+
def read_manifest
|
315
|
+
require 'rexml/document'
|
316
|
+
file = root_path('.repo/manifest.xml')
|
317
|
+
return unless file.exist?
|
318
|
+
|
319
|
+
doc = REXML::Document.new(File.read(file))
|
320
|
+
doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
|
321
|
+
end
|
322
|
+
|
323
|
+
def root_path(*args)
|
324
|
+
@root.join(*args)
|
325
|
+
end
|
326
|
+
|
327
|
+
def home_path(*args)
|
328
|
+
@home.join(*args)
|
329
|
+
end
|
330
|
+
|
331
|
+
def find_base(obj)
|
332
|
+
Workspace.project_kind.find { |proj| obj.instance_of?(proj) }
|
333
|
+
end
|
334
|
+
|
335
|
+
def bool_match(val, pat)
|
336
|
+
case val
|
337
|
+
when nil, ''
|
338
|
+
pat.is_a?(::Regexp) ? pat : nil
|
339
|
+
when '0'
|
340
|
+
false
|
341
|
+
when '1'
|
342
|
+
true
|
343
|
+
else
|
344
|
+
Regexp.new(val)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def empty?(dir)
|
349
|
+
return true if dir.empty? || dir.join('.repo').directory?
|
350
|
+
return true if dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__
|
351
|
+
|
352
|
+
dir == @root && !env('REPO_ROOT').nil? && @root.children.none? do |path|
|
353
|
+
path.directory? && !path.basename.to_s.start_with?('.') && path.to_s != @home.to_s
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def enabled?
|
358
|
+
!@series[:build].empty? || !@series[:doc].empty?
|
359
|
+
end
|
360
|
+
|
361
|
+
def multitask?
|
362
|
+
::Rake::Task.tasks.any? do |item|
|
363
|
+
next unless item.already_invoked
|
364
|
+
|
365
|
+
item.name.end_with?(':sync') || (!item.name.include?(':') && !item.name.start_with?('all', 'init'))
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def task_defined?(obj, key)
|
370
|
+
obj.is_a?(TASK_BASE[key])
|
371
|
+
end
|
372
|
+
|
373
|
+
def dev?(pat = nil, script: nil)
|
374
|
+
with?(pat, script: script, state: @dev)
|
375
|
+
end
|
376
|
+
|
377
|
+
def prod?(pat = nil, script: nil)
|
378
|
+
return false if @dev == true || !@prod
|
379
|
+
|
380
|
+
with?(pat, script: script, state: @prod)
|
381
|
+
end
|
382
|
+
|
383
|
+
def pipe?
|
384
|
+
@pipe
|
385
|
+
end
|
386
|
+
|
387
|
+
protected
|
388
|
+
|
389
|
+
def confirm(msg, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
|
390
|
+
require 'readline'
|
391
|
+
require 'timeout'
|
392
|
+
Timeout.timeout(ENV.fetch('REPO_TIMEOUT', timeout).to_i) do
|
393
|
+
ret = false
|
394
|
+
begin
|
395
|
+
while (ch = Readline.readline(msg, true))
|
396
|
+
case ch.chomp.upcase
|
397
|
+
when agree
|
398
|
+
ret = true
|
399
|
+
break
|
400
|
+
when cancel
|
401
|
+
break
|
402
|
+
end
|
403
|
+
attempts -= 1
|
404
|
+
exit 1 unless attempts >= 0
|
405
|
+
end
|
406
|
+
rescue Interrupt
|
407
|
+
puts
|
408
|
+
exit 0
|
409
|
+
else
|
410
|
+
ret
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
private
|
416
|
+
|
417
|
+
def with?(pat, script: nil, state: nil)
|
418
|
+
pat = state if pat.nil?
|
419
|
+
return pat == true unless pat.is_a?(::Regexp)
|
420
|
+
|
421
|
+
pat.match?(script || @script)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
Repo = Squared::Repo
|
data/lib/squared/repo.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Squared
|
4
|
+
module Repo
|
5
|
+
class << self
|
6
|
+
def resolve(*args)
|
7
|
+
ret = args.map do |id|
|
8
|
+
if id.is_a?(::Symbol)
|
9
|
+
project id
|
10
|
+
else
|
11
|
+
(id = Pathname.new(id).realdirpath.to_s) rescue nil if id.is_a?(::String)
|
12
|
+
get(:project).find { |_, val| val.path.to_s == id.to_s }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
ret.size == 1 ? ret.first : ret
|
16
|
+
end
|
17
|
+
|
18
|
+
def expect(name)
|
19
|
+
ret = project(name)
|
20
|
+
return ret if ret&.path&.directory?
|
21
|
+
|
22
|
+
raise NoMethodError, message('project is not initialized', name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def project?(name)
|
26
|
+
!!project(name)&.enabled?
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def project(name)
|
32
|
+
get(:project)[name.to_sym]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require_relative 'repo/workspace'
|
39
|
+
require_relative 'repo/project'
|
data/lib/squared.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'squared/version'
|
4
|
+
require_relative 'squared/common'
|
5
|
+
require_relative 'squared/repo'
|
6
|
+
require_relative 'squared/config'
|
7
|
+
|
8
|
+
Repo::Workspace.implement(
|
9
|
+
Repo::Project::Git,
|
10
|
+
Repo::Project::Node,
|
11
|
+
Repo::Project::Python,
|
12
|
+
Repo::Project::Ruby
|
13
|
+
)
|
data/squared.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/squared/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "squared"
|
7
|
+
spec.version = Squared::VERSION
|
8
|
+
spec.authors = ["An Pham"]
|
9
|
+
spec.email = ["anpham6@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Rake task generator for managing multi-language workspaces.}
|
12
|
+
spec.description = %q{Rake task generator for managing multi-language workspaces.}
|
13
|
+
spec.homepage = "https://github.com/anpham6/squared"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
15
|
+
spec.licenses = ["BSD-3-Clause"]
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
19
|
+
spec.metadata["documentation_uri"] = "https://squared.readthedocs.io"
|
20
|
+
|
21
|
+
spec.files = Dir["lib/**/*"] +
|
22
|
+
%w[LICENSE README.md README.ruby.md squared.gemspec]
|
23
|
+
spec.bindir = "exe"
|
24
|
+
spec.executables = []
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "rake"
|
28
|
+
spec.add_dependency "logger"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: squared
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- An Pham
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: logger
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Rake task generator for managing multi-language workspaces.
|
42
|
+
email:
|
43
|
+
- anpham6@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
- README.ruby.md
|
51
|
+
- lib/squared.rb
|
52
|
+
- lib/squared/common.rb
|
53
|
+
- lib/squared/common/class.rb
|
54
|
+
- lib/squared/common/format.rb
|
55
|
+
- lib/squared/common/shell.rb
|
56
|
+
- lib/squared/common/system.rb
|
57
|
+
- lib/squared/common/task.rb
|
58
|
+
- lib/squared/config.rb
|
59
|
+
- lib/squared/repo.rb
|
60
|
+
- lib/squared/repo/project.rb
|
61
|
+
- lib/squared/repo/project/base.rb
|
62
|
+
- lib/squared/repo/project/git.rb
|
63
|
+
- lib/squared/repo/project/node.rb
|
64
|
+
- lib/squared/repo/project/python.rb
|
65
|
+
- lib/squared/repo/project/ruby.rb
|
66
|
+
- lib/squared/repo/workspace.rb
|
67
|
+
- lib/squared/version.rb
|
68
|
+
- squared.gemspec
|
69
|
+
homepage: https://github.com/anpham6/squared
|
70
|
+
licenses:
|
71
|
+
- BSD-3-Clause
|
72
|
+
metadata:
|
73
|
+
homepage_uri: https://github.com/anpham6/squared
|
74
|
+
source_code_uri: https://github.com/anpham6/squared
|
75
|
+
documentation_uri: https://squared.readthedocs.io
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.4.0
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubygems_version: 3.5.22
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Rake task generator for managing multi-language workspaces.
|
95
|
+
test_files: []
|