squared 0.4.16 → 0.4.18

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.
@@ -10,6 +10,9 @@ module Squared
10
10
  include Common::Shell
11
11
  extend Forwardable
12
12
 
13
+ OPT_VALUE = /\A([^=]+)=(.+)\z/
14
+ private_constant :OPT_VALUE
15
+
13
16
  class << self
14
17
  include Common::Format
15
18
  include Shell
@@ -45,6 +48,15 @@ module Squared
45
48
  val.map { |s| s.sub(/\A-([a-z\d])(.+)\z/i, '\1=\2').sub(/\A--?/, '') }.reject(&:empty?)
46
49
  end
47
50
 
51
+ def select(list, bare: true, no: true, single: false, double: false)
52
+ ret = bare ? list.grep_v(/=/) : list.grep(/=/).map! { |val| val.split('=', 2).first }
53
+ ret.map! { |val| val.split('|', 2).last }
54
+ ret = ret.grep_v(/^no-/) unless no
55
+ return ret if single == double
56
+
57
+ ret.select { |val| single ? val.size == 1 : val.size > 1 }
58
+ end
59
+
48
60
  def arg?(target, *args, value: false, **)
49
61
  r, s = args.partition { |val| val.is_a?(Regexp) }
50
62
  unless s.empty?
@@ -53,14 +65,21 @@ module Squared
53
65
  end
54
66
  target.any? { |opt| r.any? { |val| opt&.match?(val) } }
55
67
  end
68
+
69
+ def pattern?(val)
70
+ val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*\})/)
71
+ end
56
72
  end
57
73
 
58
74
  attr_reader :target, :extras, :found, :errors, :values, :project, :path
59
75
 
60
76
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
61
- :merge, :delete, :delete?, :delete_if, :grep, :inspect, :to_a, :to_s
77
+ :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
62
78
  def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
63
- :pop, :push, :index, :delete_at, :join, :map, :map!, :select, :reject, :size
79
+ :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :reject, :size
80
+
81
+ def_delegator :@extras, :delete, :remove
82
+ def_delegator :@extras, :delete_if, :remove_if
64
83
 
65
84
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
66
85
  @target = target.is_a?(Set) ? target : Set.new(target)
@@ -138,35 +157,35 @@ module Squared
138
157
  skip = false
139
158
  opts.each do |opt|
140
159
  next skip = true if opt == '--'
141
- next @extras << opt if skip
160
+ next push opt if skip
142
161
 
143
162
  if single&.match?(opt)
144
- target << "-#{opt}"
163
+ add "-#{opt}"
145
164
  elsif bare.include?(opt)
146
- target << (opt.size == 1 ? "-#{opt}" : "--#{opt}")
165
+ add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
147
166
  elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
148
- target << "--no-#{name}"
167
+ add "--no-#{name}"
149
168
  else
150
- if opt =~ /\A([^=]+)=(.+)\z/
169
+ if opt =~ OPT_VALUE
151
170
  key = $1
152
171
  val = $2
153
172
  merge = m.include?(key)
154
173
  if e.include?(key)
155
- target << shell_option(key, val, merge: merge)
174
+ add shell_option(key, val, merge: merge)
156
175
  elsif q.include?(key)
157
- target << quote_option(key, val, double: qq.include?(key), merge: merge)
176
+ add quote_option(key, val, double: qq.include?(key), merge: merge)
158
177
  elsif p.include?(key) && path
159
- target << quote_option(key, path + val, merge: merge)
178
+ add quote_option(key, path + val, merge: merge)
160
179
  elsif b.include?(key) || numcheck.call(key, val)
161
- target << basic_option(key, val, merge: merge)
180
+ add basic_option(key, val, merge: merge)
162
181
  elsif merge
163
- target << basic_option(key, val, merge: true)
182
+ add basic_option(key, val, merge: true)
164
183
  else
165
- @extras << opt
184
+ push opt
166
185
  end
167
186
  opt = key
168
187
  else
169
- @extras << opt
188
+ push opt
170
189
  skip = true if args
171
190
  end
172
191
  skip = true if first&.any? { |s| s.is_a?(Regexp) ? opt.match?(s) : !opt.include?(s) }
@@ -192,6 +211,22 @@ module Squared
192
211
  self
193
212
  end
194
213
 
214
+ def uniq(list)
215
+ items = map { |val| nameonly(val) }
216
+ list.reject do |val|
217
+ next true if items.include?(s = nameonly(val))
218
+
219
+ pat = /\A#{s = fill_option(s)}(?:#{s.start_with?('--') ? '[= ]' : '.*'}|\z)/
220
+ any? { |opt| opt.match?(pat) }
221
+ end
222
+ end
223
+
224
+ def uniq!(list)
225
+ n = size
226
+ concat uniq(list)
227
+ extras if size > n
228
+ end
229
+
195
230
  def clear(opts = nil, errors: false, **kwargs)
196
231
  styles = project.theme[:inline] if project
197
232
  if !opts
@@ -229,10 +264,63 @@ module Squared
229
264
  args = items[0...i] + args + items[i..-1]
230
265
  target.clear
231
266
  end
232
- merge(args)
267
+ merge args
233
268
  self
234
269
  end
235
270
 
271
+ def add_path(*args, **kwargs)
272
+ add shell_quote(path ? path.join(*args) : File.join(*args), **kwargs)
273
+ self
274
+ end
275
+
276
+ def add_quote(*args, **kwargs)
277
+ merge(args.map { |val| shell_quote(val, **kwargs) })
278
+ self
279
+ end
280
+
281
+ def splice(*exclude, quote: true, delim: true, path: false, pattern: false, &blk)
282
+ found, other = if block_given?
283
+ partition(&blk)
284
+ elsif exclude.first.is_a?(Symbol)
285
+ partition(&exclude.first)
286
+ else
287
+ partition do |val|
288
+ next false if pattern && OptionPartition.pattern?(val)
289
+
290
+ exclude.none? { |pat| val.match?(Regexp.new(pat)) }
291
+ end
292
+ end
293
+ unless found.empty?
294
+ add '--' if delim
295
+ extras.clear
296
+ concat other
297
+ if path
298
+ found.each { |val| add_path(val) }
299
+ else
300
+ merge(quote ? found.map! { |val| shell_quote(val) } : found)
301
+ end
302
+ end
303
+ self
304
+ end
305
+
306
+ def append?(key, val = nil, type: nil, **kwargs)
307
+ return false if arg?(key)
308
+
309
+ val = yield self if block_given?
310
+ return false unless val
311
+
312
+ type ||= :quote if kwargs.empty?
313
+ op << case type
314
+ when :quote
315
+ quote_option(key, val)
316
+ when :basic
317
+ basic_option(key, val)
318
+ else
319
+ shell_option(key, val, **kwargs)
320
+ end
321
+ true
322
+ end
323
+
236
324
  def reset(errors: false)
237
325
  extras.clear
238
326
  clear(errors: true) if errors
@@ -242,6 +330,12 @@ module Squared
242
330
  def arg?(*args, **kwargs)
243
331
  OptionPartition.arg?(target, *args, **kwargs)
244
332
  end
333
+
334
+ private
335
+
336
+ def nameonly(val)
337
+ val[OPT_VALUE, 1] || val
338
+ end
245
339
  end
246
340
  end
247
341
  end
@@ -113,56 +113,41 @@ module Squared
113
113
  def __repo__(**kwargs)
114
114
  kwargs.delete(:parallel) if env('REPO_SYNC', ignore: '0')
115
115
 
116
- namespace(name = task_name('repo')) do |repo|
116
+ namespace task_name('repo') do |ns|
117
+ path = ns.scope.path
117
118
  branch = env('REPO_MANIFEST') || Repo.read_manifest(root)
118
119
  target = branch || manifest
120
+ cmd = nil
119
121
  stage = nil
120
- failfast = true
121
- cmd = []
122
+ opts = %w[force rebase detach submodules fail no-update gc]
122
123
  newline = ARGV.index { |val| val.start_with?('repo:') }.to_i > 0
123
- parse_opts = lambda do |args|
124
- args.to_a.each do |val|
125
- case val
126
- when 'no-fail'
127
- failfast = false
128
- when 'force'
129
- cmd << '--force-checkout'
130
- when 'rebase'
131
- cmd << '--rebase'
132
- when 'detach'
133
- cmd << '--detach'
134
- when 'gc'
135
- cmd << '--auto-gc'
136
- when 'no-update'
137
- cmd << '--no-manifest-update'
138
- end
139
- end
140
- end
141
124
  desc = lambda do |val, alt = nil|
142
125
  if (ver = branch || alt)
143
- val = val.sub('{0}', 'opts*=force,rebase,detach,gc,no-update,no-fail')
144
- task_desc(task_name('repo'), val, ver)
126
+ val = val.sub('{0}', "opts*=#{opts.join(',')}")
127
+ task_desc(path, val, ver)
145
128
  else
146
129
  task_desc 'inactive'
147
130
  end
148
131
  end
149
132
 
150
133
  desc.call('all[{0}]')
151
- task 'all', [:opts] do |_, args|
152
- parse_opts.call(args)
134
+ task 'all' do |_, args|
135
+ cmd ||= repo_opts args
153
136
  stage ||= 'all'
154
- repo['sync'].invoke
155
- next if env('REPO_DRYRUN', equals: '2')
137
+ ns['sync'].invoke
138
+ next if env('REPO_STAGE', equals: '1')
156
139
 
157
140
  @project.select do |_, proj|
158
141
  next unless proj.enabled?(proj.workspace.baseref)
159
142
 
160
143
  proj.depend(sync: true) if proj.depend?
161
- proj.build? unless env('REPO_DRYRUN', ignore: '0')
144
+ next if env('REPO_STAGE', equals: '2')
145
+
146
+ proj.build?
162
147
  end
163
148
  .each_value do |proj|
164
149
  proj.build(sync: true)
165
- next unless proj.dev? && proj.copy?
150
+ next unless proj.dev? && proj.copy? && !env('REPO_STAGE', equals: '3')
166
151
 
167
152
  if (ws = proj.workspace).task_defined?(target = task_join(proj.name, 'copy'))
168
153
  task_invoke(target, **ws.invokeargs)
@@ -172,40 +157,57 @@ module Squared
172
157
  end
173
158
  end
174
159
 
175
- desc.call("init[manifest?=#{target},{0}]", target)
176
- task 'init', [:manifest, :opts] do |_, args|
177
- parse_opts.call(args)
160
+ desc.call("init[manifest?=#{target},groups?,{0}]", target)
161
+ task 'init' do |_, args|
162
+ args = args.to_a
163
+ u = env('REPO_URL') || manifest_url
164
+ m = args.first && !opts.include?(args.first) ? args.shift : target
165
+ g = case (g = env('REPO_GROUPS'))
166
+ when '0', 'false'
167
+ nil
168
+ else
169
+ g || (args.first && !opts.include?(args.first) ? args.shift : nil)
170
+ end
171
+ cmd = repo_opts args
172
+ s = case (s = env('REPO_SUBMODULES'))
173
+ when '0', 'false'
174
+ false
175
+ else
176
+ s ? true : cmd.include?('--fetch-submodules')
177
+ end
178
178
  stage = 'init'
179
179
  puts if newline
180
- Common::System.shell("repo init -u #{env('REPO_URL') || manifest_url} -m #{args.manifest || target}.xml",
181
- chdir: root)
182
- repo['all'].invoke
180
+ args = ["-u #{u}", "-m #{m}.xml"]
181
+ args << "-g #{g}" if g
182
+ args << '--submodules' if s
183
+ Common::System.shell("#{repo_bin} init #{args.join(' ')}", chdir: root)
184
+ next if env('REPO_STAGE', equals: '0')
185
+
186
+ ns['all'].invoke
183
187
  end
184
188
 
185
189
  desc.call('sync[{0}]')
186
- task 'sync', [:opts] do |_, args|
187
- unless branch || stage == 'init'
188
- raise_error('repo not initialized', hint: task_name('repo:init'), kind: LoadError)
189
- end
190
- parse_opts.call(args)
190
+ task 'sync' do |t, args|
191
+ raise_error 'repo not initialized' unless branch || stage == 'init'
192
+ cmd ||= repo_opts args
191
193
  cmd << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}"
192
- cmd << '--fail-fast' if failfast
193
- puts if newline && stage != 'init'
194
+ puts unless !newline || stage == 'init'
194
195
  begin
195
- Common::System.shell("repo sync #{cmd.join(' ')}", chdir: root, exception: failfast)
196
+ Common::System.shell("#{repo_bin} sync #{cmd.join(' ')}", chdir: root,
197
+ exception: cmd.include?('--fail-fast'))
196
198
  rescue Errno::ENOENT => e
197
199
  emphasize(e, title: root)
198
200
  raise
199
201
  rescue StandardError => e
200
- emphasize(e, title: "rake stash #{task_name(task_join('repo', stage || 'sync'))}")
202
+ emphasize(e, title: "rake stash #{t.name}")
201
203
  raise
202
204
  end
203
205
  end
204
206
 
205
207
  series.sync.push(
206
- task_join(name, 'all'),
207
- task_join(name, 'init'),
208
- task_join(name, 'sync')
208
+ task_join(path, 'all'),
209
+ task_join(path, 'init'),
210
+ task_join(path, 'sync')
209
211
  )
210
212
  end
211
213
  end
@@ -221,6 +223,31 @@ module Squared
221
223
  )
222
224
  end
223
225
 
226
+ def repo_opts(args)
227
+ ret = []
228
+ args.to_a.each do |val|
229
+ case val
230
+ when 'force'
231
+ ret << '--force-checkout'
232
+ when 'rebase', 'detach'
233
+ ret << "--#{val}"
234
+ when 'submodules'
235
+ ret << '--fetch-submodules'
236
+ when 'fail'
237
+ ret << '--fail-fast'
238
+ when 'no-update'
239
+ ret << '--no-manifest-update'
240
+ when 'gc'
241
+ ret << '--auto-gc'
242
+ end
243
+ end
244
+ ret
245
+ end
246
+
247
+ def repo_bin
248
+ Common::Shell.shell_bin('repo')
249
+ end
250
+
224
251
  def repo?
225
252
  !manifest_url.nil? && (repo_install? || @repo_override == true)
226
253
  end
data/squared.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = %q{Rake task generator for managing multi-language workspaces.}
12
12
  spec.description = %q{Rake task generator for managing multi-language workspaces.}
13
- spec.homepage = "https://github.com/anpham6/squared"
13
+ spec.homepage = "https://github.com/anpham6/squared-ruby"
14
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
15
15
  spec.licenses = ["BSD-3-Clause"]
16
16
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.metadata["documentation_uri"] = "https://squared.readthedocs.io"
20
20
 
21
21
  spec.files = Dir["lib/**/*"] +
22
- %w[CHANGELOG.md LICENSE README.md README.ruby.md squared.gemspec]
22
+ %w[CHANGELOG.md LICENSE README.md squared.gemspec]
23
23
  spec.bindir = "exe"
24
24
  spec.executables = []
25
25
  spec.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.16
4
+ version: 0.4.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -75,7 +75,6 @@ files:
75
75
  - CHANGELOG.md
76
76
  - LICENSE
77
77
  - README.md
78
- - README.ruby.md
79
78
  - lib/squared.rb
80
79
  - lib/squared/app.rb
81
80
  - lib/squared/common.rb
@@ -105,12 +104,12 @@ files:
105
104
  - lib/squared/workspace/support/base.rb
106
105
  - lib/squared/workspace/support/data.rb
107
106
  - squared.gemspec
108
- homepage: https://github.com/anpham6/squared
107
+ homepage: https://github.com/anpham6/squared-ruby
109
108
  licenses:
110
109
  - BSD-3-Clause
111
110
  metadata:
112
- homepage_uri: https://github.com/anpham6/squared
113
- source_code_uri: https://github.com/anpham6/squared
111
+ homepage_uri: https://github.com/anpham6/squared-ruby
112
+ source_code_uri: https://github.com/anpham6/squared-ruby
114
113
  documentation_uri: https://squared.readthedocs.io
115
114
  rdoc_options: []
116
115
  require_paths: