squared 0.0.6 → 0.0.8

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.
@@ -4,11 +4,11 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Ruby < Git
7
- REF = :ruby
8
7
  GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
9
- OPT_INSTALL = %w[no-cache force quiet verbose].freeze
10
- OPT_UPDATE = %w[redownload local strict conservative group=s quiet verbose].freeze
11
- private_constant :REF, :GEMFILE, :OPT_INSTALL, :OPT_UPDATE
8
+ OPT_INSTALL = %w[no-cache force].freeze
9
+ OPT_UPDATE = %w[redownload local strict conservative group=s].freeze
10
+ OPT_OUTDATED = %w[local strict pre only-explicit group=s].freeze
11
+ private_constant :GEMFILE, :OPT_INSTALL, :OPT_UPDATE, :OPT_OUTDATED
12
12
 
13
13
  class << self
14
14
  def populate(*); end
@@ -26,32 +26,34 @@ module Squared
26
26
  end
27
27
  end
28
28
 
29
- @@tasks[REF] = {
30
- install: %i[redownload local prefer-local with-g without-g],
29
+ @@tasks[ref] = {
30
+ install: %i[redownload local prefer-local gem with without],
31
31
  update: %i[all patch minor major],
32
- pristine: %i[version extensions],
32
+ outdated: %i[patch minor major],
33
+ pristine: %i[gem all version],
34
+ exec: nil,
35
+ config: nil,
33
36
  rake: nil
34
37
  }.freeze
35
38
 
36
39
  attr_reader :gemfile
37
40
 
38
- def initialize(name, path, workspace, *, version: nil, autodetect: false, **kwargs)
41
+ def initialize(*, version: nil, autodetect: false, **kwargs)
39
42
  super
40
- initialize_build(REF, **kwargs)
41
- @version = env('BUILD', suffix: 'VERSION', strict: true) || version
43
+ initialize_build(Ruby.ref, **kwargs)
44
+ @version = env('BUILD', version, suffix: 'VERSION', strict: true)
42
45
  @autodetect = autodetect
43
46
  index = GEMFILE.index { |file| base_path(file).exist? } || 0
44
47
  @gemfile = base_path(GEMFILE[index])
45
48
  return if !@output[0].nil? || !@copy.nil? || @version || @autodetect || (file = rakefile).nil?
46
49
 
47
50
  begin
48
- pat = %r{\brequire\s+(["'])bundler/gem_tasks\1}
49
51
  File.foreach(file) do |line|
50
- next unless line =~ pat
52
+ next unless line =~ %r{\brequire\s+(["'])bundler/gem_tasks\1}
51
53
 
52
54
  @output[0] = 'bundle exec rake build'
53
55
  @copy = 'bundle exec rake install'
54
- @clean ||= 'bundle exec rake clean'
56
+ @clean = 'bundle exec rake clean' if @clean.nil?
55
57
  break
56
58
  end
57
59
  rescue StandardError => e
@@ -61,18 +63,23 @@ module Squared
61
63
 
62
64
  def populate(*)
63
65
  super
64
- return unless outdated?
66
+ return unless outdated? && ref?(Ruby.ref)
65
67
 
66
68
  namespace name do
67
- @@tasks[REF].each do |action, flags|
69
+ @@tasks[Ruby.ref].each do |action, flags|
68
70
  if flags.nil?
69
71
  case action
72
+ when :exec, :config
73
+ desc format_desc(action, nil, 'command+')
74
+ task action, [:command] do |_, args|
75
+ bundle(action, args.to_a)
76
+ end
70
77
  when :rake
71
78
  next unless rakefile
72
79
 
73
80
  desc format_desc(action, nil, 'command*')
74
81
  task action, [:command] do |_, args|
75
- rake collect_args(args, :command)
82
+ rake args.to_a
76
83
  end
77
84
  end
78
85
  else
@@ -81,26 +88,51 @@ module Squared
81
88
  case action
82
89
  when :install
83
90
  case flag
84
- when :'with-g', :'without-g'
91
+ when :gem
92
+ desc format_desc(action, flag, 'name+')
93
+ task flag, [:name] do |_, args|
94
+ name = args.to_a
95
+ guard_params(action, flag, args: name)
96
+ depend(flag, opts: name)
97
+ end
98
+ when :with, :without
85
99
  desc format_desc(action, flag, 'group+')
86
100
  task flag, [:group] do |_, args|
87
- depend(flag, group: collect_args(args, :group), override: true)
101
+ group = args.to_a
102
+ guard_params(action, flag, args: group)
103
+ depend(flag, opts: group)
88
104
  end
89
105
  else
90
106
  desc format_desc(action, flag, OPT_INSTALL)
91
107
  task flag, [:opts] do |_, args|
92
- depend(flag, opts: collect_args(args, :opts), override: true)
108
+ depend(flag, opts: args.to_a)
93
109
  end
94
110
  end
95
- when :update
96
- desc format_desc(action, flag, OPT_UPDATE)
111
+ when :update, :outdated
112
+ desc format_desc(action, flag, action == :update ? OPT_UPDATE : OPT_OUTDATED)
97
113
  task flag, [:opts] do |_, args|
98
- update(flag, opts: collect_args(args, :opts))
114
+ __send__(action, flag, opts: args.to_a)
99
115
  end
100
116
  when :pristine
101
- desc format_desc(action, flag, 'version?')
102
- task flag, [:version] do |_, args|
103
- pristine(flag, version: args.version)
117
+ case flag
118
+ when :gem
119
+ desc format_desc(action, flag, 'name+')
120
+ task flag, [:name] do |_, args|
121
+ name = args.to_a
122
+ guard_params(action, flag, args: name)
123
+ pristine(flag, opts: name)
124
+ end
125
+ when :all
126
+ desc format_desc(action, flag, 'skip*')
127
+ task flag, [:skip] do |_, args|
128
+ pristine(flag, opts: args.to_a)
129
+ end
130
+ when :version
131
+ desc format_desc(action, flag, 'version?')
132
+ task flag, [:version] do |_, args|
133
+ guard_params(action, flag, args: args, key: :version)
134
+ pristine(flag, version: args.version)
135
+ end
104
136
  end
105
137
  end
106
138
  end
@@ -110,11 +142,17 @@ module Squared
110
142
  end
111
143
  end
112
144
 
113
- def depend(flag = nil, opts: [], group: [], override: false)
114
- if @depend && !override
145
+ def depend(flag = nil, opts: [])
146
+ if @depend && !flag
115
147
  super
116
148
  elsif outdated?
117
149
  case flag
150
+ when :gem
151
+ gem_session 'install'
152
+ append_value opts
153
+ when :with, :without
154
+ gem_session 'install'
155
+ append_repeat flag, opts
118
156
  when :redownload, :local, :'prefer-local'
119
157
  cmd = bundle_session 'install', "--#{flag}"
120
158
  if (val = env('BUNDLE_TRUST_POLICY'))
@@ -134,16 +172,11 @@ module Squared
134
172
  end}"
135
173
  end
136
174
  append_bundle opts, OPT_INSTALL
137
- when :'with-g', :'without-g'
138
- guard_params('install', flag, args: group)
139
- cmd = gem_session 'install', '-g'
140
- opt = flag.to_s.sub('-g', '')
141
- group.each { |s| cmd << "--#{opt}=#{shell_escape(s, quote: true)}" }
142
175
  else
143
- cmd = bundle_session 'install'
176
+ bundle_session 'install'
144
177
  append_bundle
145
178
  end
146
- run(banner: banner?, exception: workspace.exception)
179
+ run_rb(sync: invoked_sync?('depend', flag))
147
180
  end
148
181
  end
149
182
 
@@ -169,28 +202,120 @@ module Squared
169
202
  end
170
203
  end
171
204
 
172
- def outdated(*); end
205
+ def outdated(rev = nil, opts: [])
206
+ cmd = bundle_session 'outdated', rev && "--#{rev}"
207
+ append_bundle opts, OPT_OUTDATED
208
+ cmd = cmd.done
209
+ log.info cmd
210
+ print_item format_banner(cmd) if store_pwd || invoked_sync?("outdated#{rev && ":#{rev}"}")
211
+ start = 0
212
+ found = 0
213
+ major = 0
214
+ IO.popen("#{cmd} --no-color").each do |line|
215
+ if start > 0
216
+ unless pipe?
217
+ data = line.scan(SEM_VER)
218
+ cur = data.shift
219
+ lat = data.shift
220
+ if cur && lat
221
+ semver(cur)
222
+ semver(lat)
223
+ c = cur.join
224
+ l = lat.join
225
+ styles = []
226
+ data.each do |val|
227
+ break unless (req = /(>=?|=|~>|!=|<=?) (#{Regexp.escape(val.join)})/.match(line))
228
+
229
+ v = semver(val).join
230
+ case req[1]
231
+ when '>', '>='
232
+ if semmajor(cur, lat)
233
+ styles = %i[green bold]
234
+ major += 1
235
+ else
236
+ styles[0] = cur[2] == lat[2] ? :yellow : :green
237
+ end
238
+ when '<', '<='
239
+ if c <= v
240
+ if semmajor(cur, lat)
241
+ styles = %i[green bold]
242
+ major += 1
243
+ else
244
+ styles[0] = :yellow
245
+ end
246
+ end
247
+ when '!='
248
+ if c == l
249
+ styles.clear
250
+ else
251
+ styles[1] = :bold
252
+ end
253
+ when '~>'
254
+ if c < v && cur[0] == val[0] && !semmajor(cur, val)
255
+ styles[0] = :yellow
256
+ elsif semmajor(lat, val)
257
+ styles[1] = :underline
258
+ else
259
+ styles[1] = :bold
260
+ end
261
+ end
262
+ end
263
+ unless styles.empty?
264
+ case styles[0]
265
+ when :green
266
+ line = sub_style(line, pat: /^(\S+)(.+)$/, styles: theme[styles[1] == :bold ? :major : :active])
267
+ found += 1
268
+ when :yellow
269
+ found += 1
270
+ end
271
+ line = sub_style(line, pat: /^((?:\S+\s+){2})(#{Regexp.escape(l)})(.+)$/,
272
+ styles: styles.compact, index: 2)
273
+ end
274
+ end
275
+ end
276
+ puts "#{start.to_s.rjust(2)}. #{line}"
277
+ start += 1
278
+ elsif line =~ /^Gem /
279
+ unless pipe?
280
+ puts print_footer(" # #{line.chomp}", reverse: true, sub: [
281
+ { pat: /^(.+)(Gem)(.+)$/, styles: theme[:header], index: 2 },
282
+ { pat: /^(.+)(Latest)(.+)$/, styles: theme[:header], index: 2 }
283
+ ])
284
+ end
285
+ start += 1
286
+ end
287
+ end
288
+ if found > 0
289
+ puts print_footer(empty_status('Updates are available', 'major', major, always: true))
290
+ elsif start == 0
291
+ puts 'No updates were found'
292
+ end
293
+ store_pwd true
294
+ end
173
295
 
174
296
  def update(flag, opts: [])
175
- cmd = bundle_session 'update'
176
- case flag
177
- when :all, :major, :patch, :minor
178
- cmd << "--#{flag}"
179
- end
297
+ bundle_session 'update', "--#{flag}"
180
298
  append_bundle opts, OPT_UPDATE
181
- run(banner: banner?, exception: workspace.exception)
299
+ run_rb
182
300
  end
183
301
 
184
- def pristine(flag, version: nil)
185
- cmd = gem_session 'pristine', project
302
+ def pristine(flag, version: nil, opts: [])
303
+ cmd = gem_session 'pristine'
186
304
  case flag
187
- when :extensions
188
- cmd << '--extensions'
305
+ when :gem
306
+ append_value opts
307
+ when :all
308
+ cmd << '--all'
309
+ append_repeat 'skip', opts
189
310
  when :version
190
- guard_params version, 'version'
311
+ cmd << project << "--version=#{shell_escape(version)}"
191
312
  end
192
- cmd << "--version=#{version}" if version
193
- run(banner: banner?, exception: workspace.exception)
313
+ run_rb
314
+ end
315
+
316
+ def bundle(flag, cmd)
317
+ guard_params('bundle', flag, args: cmd)
318
+ run_s "bundle #{flag} #{cmd.join(' ')}"
194
319
  end
195
320
 
196
321
  def rake(cmd)
@@ -210,9 +335,8 @@ module Squared
210
335
  return true if @copy.is_a?(::String) || @copy&.fetch(:gemdir, nil)
211
336
  return gemdir? if @gemdir
212
337
 
213
- gempath = -> { "gems#{::File::SEPARATOR}#{project}-#{@version}" }
214
338
  if @version && (val = ENV['GEM_HOME'])
215
- @gemdir = Pathname.new(val).join(gempath.())
339
+ @gemdir = Pathname.new(val).join(gempath)
216
340
  return true if gemdir?
217
341
  end
218
342
  return false unless @autodetect
@@ -236,7 +360,7 @@ module Squared
236
360
  break
237
361
  end
238
362
  unsafe.('path') unless data
239
- @gemdir = Pathname.new(data[1].strip).join(gempath.())
363
+ @gemdir = Pathname.new(data[1].strip).join(gempath)
240
364
  rescue StandardError => e
241
365
  log.error e
242
366
  @version = nil
@@ -247,38 +371,46 @@ module Squared
247
371
  end
248
372
  end
249
373
 
250
- def depend?
251
- outdated? || !!@depend
252
- end
253
-
254
374
  def outdated?
255
375
  gemfile.exist?
256
376
  end
257
377
 
258
- def dev?
259
- @dev
260
- end
261
-
262
378
  private
263
379
 
380
+ def run_rb(sync: true)
381
+ run(sync: sync, banner: !@session.include?('--quiet'))
382
+ end
383
+
264
384
  def append_bundle(opts = nil, list = nil)
265
385
  if (val = env('BUNDLE_JOBS')).to_i > 0
266
386
  @session << "-j#{val}"
267
387
  end
268
- @session << '--norc' if env('BUNDLE_NORC')
269
388
  return unless opts && list
270
389
 
271
390
  opts.each do |opt|
272
391
  if list.include?(opt)
273
392
  @session << "--#{opt}"
274
393
  elsif opt.match(/^g(?:roup)?=(.+)$/)
275
- @session << "--group=#{shell_escape($1, quote: true)}"
394
+ @session << "--group=#{shell_escape($1)}"
276
395
  end
277
396
  end
278
397
  end
279
398
 
399
+ def append_repeat(flag, opts)
400
+ opts.each { |val| @session << "--#{flag}=#{shell_escape(val, quote: true)}" }
401
+ end
402
+
403
+ def append_value(opts)
404
+ opts.each { |val| @session << val }
405
+ end
406
+
280
407
  def gem_session(*cmd)
281
- session('gem', *cmd)
408
+ ret = session('gem', *cmd)
409
+ if (val = env('GEM_CONFIG_FILE'))
410
+ ret << "--config-file=#{shell_escape(base_path(val).to_s, quote: true)}"
411
+ end
412
+ ret << '--norc' if env('GEM_NORC')
413
+ ret
282
414
  end
283
415
 
284
416
  def bundle_session(*cmd)
@@ -286,8 +418,8 @@ module Squared
286
418
  append_nocolor
287
419
  end
288
420
 
289
- def banner?
290
- !@session.include?('--quiet')
421
+ def gempath
422
+ File.join('gems', "#{project}-#{@version}")
291
423
  end
292
424
 
293
425
  def gemdir?
@@ -5,6 +5,10 @@ module Squared
5
5
  module Project
6
6
  class << self
7
7
  attr_accessor :line_width
8
+
9
+ def max_width(lines)
10
+ [lines.max_by(&:size).size, line_width].max
11
+ end
8
12
  end
9
13
 
10
14
  @line_width = ENV.fetch('LOG_COLUMNS', 80).to_i
@@ -6,14 +6,11 @@ module Squared
6
6
  include Common
7
7
  include Format
8
8
  include System
9
- include Task
10
9
 
11
- attr_accessor :warning
12
-
13
- def repo(url, manifest = 'latest', run: nil, dev: nil, prod: nil)
10
+ def repo(url, manifest = 'latest', run: nil, dev: nil, prod: nil, ref: @ref, group: @group)
14
11
  @home = if (val = env('REPO_HOME'))
15
12
  home = Pathname.new(val)
16
- if @main == home.basename.to_s
13
+ if main == home.basename.to_s
17
14
  @root = home.parent
18
15
  if home.exist?
19
16
  @root = nil unless home.directory?
@@ -33,18 +30,25 @@ module Squared
33
30
  elsif !install?
34
31
  raise_error('REPO_ROOT', val, hint: 'exist') unless confirm_install
35
32
  end
36
- @root.join(@main).realdirpath
33
+ @root.join(main).realdirpath
37
34
  else
38
- install?(pwd = Pathname.pwd) ? pwd.join(@main) : pwd
35
+ install?(pwd = @home) ? pwd.join(main) : pwd
39
36
  end
40
37
  @root = @home.parent
41
38
  @manifest_url = url
42
39
  @manifest = manifest
40
+ set_ref = lambda do
41
+ if group
42
+ @script[:group][:_] = group.to_s
43
+ elsif ref
44
+ @script[:ref][:_] = ref.to_sym
45
+ end
46
+ end
43
47
  if repo?
44
48
  @script[:build] = case (val = env('REPO_BUILD'))
45
49
  when 'verbose'
46
50
  @verbose = true
47
- "#{run}:verbose" if run
51
+ run.is_a?(String) ? "#{run}:verbose" : run
48
52
  when 'silent'
49
53
  @verbose = false
50
54
  @warning = false
@@ -54,33 +58,33 @@ module Squared
54
58
  end
55
59
  @script[:dev] = bool_match(env('REPO_DEV'), dev)
56
60
  @script[:prod] = bool_match(env('REPO_PROD'), prod)
61
+ if (val = env('REPO_GROUP'))
62
+ @script[:group][:_] = val.to_s
63
+ @script[:env] = true
64
+ elsif (val = env('REPO_REF'))
65
+ @script[:ref][:_] = val.to_sym
66
+ @script[:env] = true
67
+ else
68
+ set_ref
69
+ end
57
70
  @warning = case env('REPO_WARN')
58
71
  when '0'
59
72
  false
60
73
  when '1'
61
74
  true
62
75
  else
63
- !empty?(@root)
76
+ @warning && !empty?(@root)
64
77
  end
65
78
  @extensions << :__repo__
66
79
  else
67
80
  @script[:build] = run
68
81
  @script[:dev] = dev
69
82
  @script[:prod] = prod
83
+ set_ref
70
84
  end
71
85
  self
72
86
  end
73
87
 
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
88
  private
85
89
 
86
90
  def __repo__(**kwargs)
@@ -93,7 +97,7 @@ module Squared
93
97
  cmd = []
94
98
  newline = ARGV.index { |val| val.start_with?('repo:') }.to_i > 0
95
99
  parse_opts = lambda do |args|
96
- collect_args(args, :opts).each do |val|
100
+ args.to_a.each do |val|
97
101
  case val
98
102
  when 'no-fail'
99
103
  failfast = false
@@ -122,10 +126,10 @@ module Squared
122
126
  stage ||= 'all'
123
127
  repo['sync'].invoke
124
128
  @project.select do |_, proj|
125
- if proj.enabled?
126
- proj.depend
127
- proj.build?
128
- end
129
+ next false unless proj.enabled? && proj.ref?(Project::Base.ref)
130
+
131
+ proj.depend if proj.depend?
132
+ proj.build?
129
133
  end
130
134
  .each_value { |proj| proj.has?(:dev) ? proj.refresh : proj.build }
131
135
  end
@@ -166,12 +170,13 @@ module Squared
166
170
  end
167
171
 
168
172
  def confirm_install
169
- return false unless @root.directory?
173
+ return false unless root.directory?
170
174
 
175
+ path = sub_style(root, styles: theme[:inline])
171
176
  @override = confirm(
172
- "#{log_title(:warn)} \"#{sub_style(@root, :bold)}\" is not empty. Continue with installation? [y/N] ",
177
+ "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation? [y/N] ",
173
178
  default: 'N',
174
- timeout: env('REPO_TIMEOUT', ignore: '0', default: 15)
179
+ timeout: env('REPO_TIMEOUT', 15, ignore: '0')
175
180
  )
176
181
  end
177
182
 
@@ -188,7 +193,15 @@ module Squared
188
193
  end
189
194
  end
190
195
 
191
- def install?(dir = @root)
196
+ def repo?
197
+ !@manifest_url.nil? && (install? || !!@override)
198
+ end
199
+
200
+ def empty?(dir)
201
+ dir.empty? || (dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__)
202
+ end
203
+
204
+ def install?(dir = root)
192
205
  return true if empty?(dir) || dir.join('.repo').directory?
193
206
  return false unless dir == root && env('REPO_HOME').nil? && !env('REPO_ROOT').nil?
194
207