squared 0.4.15 → 0.4.16
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/CHANGELOG.md +29 -0
- data/README.ruby.md +4 -2
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +1 -2
- data/lib/squared/common/utils.rb +9 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +14 -10
- data/lib/squared/workspace/project/base.rb +157 -113
- data/lib/squared/workspace/project/docker.rb +21 -23
- data/lib/squared/workspace/project/git.rb +25 -27
- data/lib/squared/workspace/project/node.rb +67 -25
- data/lib/squared/workspace/project/python.rb +12 -8
- data/lib/squared/workspace/project/ruby.rb +80 -47
- data/lib/squared/workspace/project/support/class.rb +2 -4
- data/lib/squared/workspace/series.rb +4 -4
- data/lib/squared/workspace/support/base.rb +17 -0
- data/lib/squared/workspace/support.rb +1 -0
- data/lib/squared/workspace.rb +0 -8
- data/squared.gemspec +2 -2
- metadata +3 -2
@@ -3,7 +3,7 @@
|
|
3
3
|
module Squared
|
4
4
|
module Workspace
|
5
5
|
module Git
|
6
|
-
GIT_REPO =
|
6
|
+
GIT_REPO = Support.hashobj
|
7
7
|
GIT_PROTO = %r{^(?:https?|ssh|git|file)://}i.freeze
|
8
8
|
private_constant :GIT_REPO, :GIT_PROTO
|
9
9
|
|
@@ -179,6 +179,9 @@ module Squared
|
|
179
179
|
}.freeze,
|
180
180
|
git: {
|
181
181
|
add: %w[N|intent-to-add refresh].freeze,
|
182
|
+
blame: %w[b c l s t w C=im? L=q M=im? S=p color-by-age color-lines first-parent incremental line-porcelain
|
183
|
+
p|porcelain root score-debug f|show-name e|show-email n|show-number show-stats abbrev=i
|
184
|
+
contents=p date=q encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
|
182
185
|
clean: %w[d x X f|force n|dry-run i|interactive q|quiet e|exclude=q].freeze,
|
183
186
|
mv: %w[k f|force n|dry-run v|verbose].freeze,
|
184
187
|
revert: %w[e S=bm? abort continue n|no-commit quit reference skip cleanup=b gpg-sign=b? m|mainline=i
|
@@ -245,6 +248,7 @@ module Squared
|
|
245
248
|
tag: %w[n=im cleanup=b create-reflog i|ignore-case color=b? column=b contains=b? format=q merged=b?
|
246
249
|
no-contains=b? no-merged=b? points-at=q sort=q].freeze,
|
247
250
|
no: {
|
251
|
+
blame: %w[progress].freeze,
|
248
252
|
branch: %w[color color-moved column track].freeze,
|
249
253
|
checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
|
250
254
|
fetch: {
|
@@ -330,7 +334,7 @@ module Squared
|
|
330
334
|
'diff' => %i[head branch files view between contain].freeze,
|
331
335
|
'fetch' => %i[origin remote].freeze,
|
332
336
|
'files' => %i[cached modified deleted others].freeze,
|
333
|
-
'git' => %i[add clean mv revert rm].freeze,
|
337
|
+
'git' => %i[add blame clean mv revert rm].freeze,
|
334
338
|
'log' => %i[view between contain].freeze,
|
335
339
|
'merge' => %i[commit no-commit send].freeze,
|
336
340
|
'pull' => %i[origin remote].freeze,
|
@@ -360,7 +364,7 @@ module Squared
|
|
360
364
|
|
361
365
|
namespace name do
|
362
366
|
Git.subtasks do |action, flags|
|
363
|
-
next if
|
367
|
+
next if task_pass?(action)
|
364
368
|
|
365
369
|
namespace action do
|
366
370
|
flags.each do |flag|
|
@@ -859,19 +863,14 @@ module Squared
|
|
859
863
|
args = args.to_a
|
860
864
|
if args.empty? || args.last == ':'
|
861
865
|
files = []
|
862
|
-
status_data.each
|
863
|
-
case (flag == :staged ? line[2] : line[1])
|
864
|
-
when /[AMDRTC]/
|
865
|
-
files << line[0]
|
866
|
-
end
|
867
|
-
end
|
866
|
+
status_data.each { |row| files << row[0] if row[flag == :staged ? 2 : 1].match?(/[AMDRTC]/) }
|
868
867
|
unless files.empty?
|
869
868
|
files = choice_index('Select a file', files, multiple: true, force: false,
|
870
869
|
accept: 'Restore?')
|
871
870
|
end
|
872
871
|
args.pop
|
873
872
|
args, glob = args.partition { |val| val.match?(/^(?:[a-z-]+=|[^*]+$)/) }
|
874
|
-
|
873
|
+
files.concat(glob)
|
875
874
|
next if args.empty? && files.empty?
|
876
875
|
end
|
877
876
|
restore(flag, args, files: files)
|
@@ -879,10 +878,11 @@ module Squared
|
|
879
878
|
end
|
880
879
|
when 'git'
|
881
880
|
before = case flag
|
881
|
+
when :blame then 'file'
|
882
882
|
when :mv then 'source+,destination'
|
883
883
|
when :revert then 'commit+' end
|
884
884
|
format_desc(action, flag, 'opts*', before: before, after: case flag
|
885
|
-
when :add then 'pathspec
|
885
|
+
when :add then 'pathspec*,:pattern:*'
|
886
886
|
when :clean, :rm then 'pathspec*' end)
|
887
887
|
task flag do |_, args|
|
888
888
|
git flag, args.to_a
|
@@ -1142,10 +1142,7 @@ module Squared
|
|
1142
1142
|
rescue StandardError => e
|
1143
1143
|
warn log_message(Logger::WARN, e, pass: true) if warning?
|
1144
1144
|
else
|
1145
|
-
|
1146
|
-
msg = sub_style('completed', styles: theme[:active])
|
1147
|
-
puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
|
1148
|
-
end
|
1145
|
+
print_status(name, subject: 'revbuild', start: start, from: :completed)
|
1149
1146
|
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
|
1150
1147
|
sync: sync, utc: 'build')
|
1151
1148
|
end
|
@@ -1623,10 +1620,16 @@ module Squared
|
|
1623
1620
|
|
1624
1621
|
def git(flag, opts = [])
|
1625
1622
|
cmd, opts = git_session(flag, opts: opts)
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1623
|
+
op = OptionPartition.new(opts, OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, []), cmd,
|
1624
|
+
project: self, no: OPT_GIT[:no][flag], first: case flag
|
1625
|
+
when :blame, :revert
|
1626
|
+
nil
|
1627
|
+
else matchpathspec end)
|
1629
1628
|
case flag
|
1629
|
+
when :blame
|
1630
|
+
raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
|
1631
|
+
op << '--' << shell_quote(path + op.delete_at(n))
|
1632
|
+
op.clear
|
1630
1633
|
when :revert
|
1631
1634
|
if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
|
1632
1635
|
op.clear
|
@@ -1637,14 +1640,13 @@ module Squared
|
|
1637
1640
|
end
|
1638
1641
|
when :add, :clean
|
1639
1642
|
if flag == :add && !op.arg?('pathspec-from-file')
|
1640
|
-
grep, list = op.
|
1641
|
-
|
1642
|
-
red = color(:red)
|
1643
|
+
grep, list = op.partition { |val| val.start_with?(':') && val.end_with?(':') }
|
1644
|
+
unless grep.empty? && !list.empty?
|
1643
1645
|
grep.map! { |val| Regexp.new(val[1..-2]) }
|
1644
1646
|
files = status_data.map! do |a, b|
|
1645
1647
|
next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
|
1646
1648
|
|
1647
|
-
"#{sub_style(b, styles: red)} #{a}"
|
1649
|
+
"#{sub_style(b, styles: color(:red))} #{a}"
|
1648
1650
|
end
|
1649
1651
|
.compact
|
1650
1652
|
unless files.empty?
|
@@ -1741,11 +1743,7 @@ module Squared
|
|
1741
1743
|
end
|
1742
1744
|
end
|
1743
1745
|
rescue StandardError => e
|
1744
|
-
|
1745
|
-
ret = on(:error, from, e)
|
1746
|
-
raise if exception && ret != true
|
1747
|
-
|
1748
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
1746
|
+
on_error(e, from, pass: true)
|
1749
1747
|
nil
|
1750
1748
|
else
|
1751
1749
|
on :last, from
|
@@ -120,7 +120,7 @@ module Squared
|
|
120
120
|
|
121
121
|
namespace name do
|
122
122
|
Node.subtasks do |action, flags|
|
123
|
-
next if
|
123
|
+
next if task_pass?(action)
|
124
124
|
|
125
125
|
if flags.nil?
|
126
126
|
case action
|
@@ -257,6 +257,11 @@ module Squared
|
|
257
257
|
otp = args.first
|
258
258
|
else
|
259
259
|
tag, otp = param_guard(action, flag, args: args)
|
260
|
+
unless SEM_VER.match?(tag)
|
261
|
+
a = sub_style(project, styles: theme[:active])
|
262
|
+
b = sub_style(tag, styles: theme[:inline])
|
263
|
+
exit 1 unless confirm("Publish #{a}@#{b}? [y/N] ", 'N')
|
264
|
+
end
|
260
265
|
end
|
261
266
|
publish(flag, otp: otp, tag: tag, dryrun: dryrun, access: access)
|
262
267
|
end
|
@@ -268,7 +273,7 @@ module Squared
|
|
268
273
|
end
|
269
274
|
end
|
270
275
|
|
271
|
-
def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, workspace: false,
|
276
|
+
def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, files: nil, workspace: false,
|
272
277
|
link: false, force: false, override: false, sync: invoked_sync?('copy'), **kwargs)
|
273
278
|
glob = kwargs[:include]
|
274
279
|
pass = kwargs[:exclude]
|
@@ -277,6 +282,7 @@ module Squared
|
|
277
282
|
|
278
283
|
from = @copy[:from] if @copy.key?(:from)
|
279
284
|
into = @copy[:into] if @copy.key?(:into)
|
285
|
+
files = @copy[:files] if @copy.key?(:files)
|
280
286
|
workspace = @copy[:workspace] if @copy.key?(:workspace)
|
281
287
|
link = @copy[:link] if @copy.key?(:link)
|
282
288
|
force = @copy[:force] if @copy.key?(:force)
|
@@ -298,6 +304,7 @@ module Squared
|
|
298
304
|
|
299
305
|
on :first, :copy
|
300
306
|
print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
|
307
|
+
packed = false
|
301
308
|
items.each do |dir|
|
302
309
|
case dir
|
303
310
|
when Pathname
|
@@ -335,9 +342,49 @@ module Squared
|
|
335
342
|
end
|
336
343
|
next unless from && dest&.directory?
|
337
344
|
|
338
|
-
from
|
345
|
+
if from == :npm
|
346
|
+
begin
|
347
|
+
unless packed
|
348
|
+
require 'open3'
|
349
|
+
files = pwd_set do
|
350
|
+
Open3.capture2e(session_output('npm', 'pack --dry-run --no-color', npmname).to_s)
|
351
|
+
.first
|
352
|
+
.scan(/^npm notice \d+(?:\.\d+)?[a-z]+ (.+)$/i)
|
353
|
+
.map { |item| Pathname.new(item.first) }
|
354
|
+
.select(&:exist?)
|
355
|
+
end
|
356
|
+
.concat(Array(files))
|
357
|
+
packed = true
|
358
|
+
end
|
359
|
+
to = dest.join(into, npmname)
|
360
|
+
to.mkpath
|
361
|
+
log.info "cp npm:#{npmname} #{to}"
|
362
|
+
subdir = []
|
363
|
+
errors = 0
|
364
|
+
files.each do |file|
|
365
|
+
s, d = file.is_a?(Array) ? file : [file, file]
|
366
|
+
dest = to + d
|
367
|
+
unless subdir.include?((target = dest.dirname).to_s)
|
368
|
+
target.mkpath
|
369
|
+
subdir << target.to_s
|
370
|
+
end
|
371
|
+
begin
|
372
|
+
FileUtils.cp(path + s, dest, verbose: verbose.is_a?(Numeric) && verbose > 0)
|
373
|
+
rescue StandardError => e
|
374
|
+
print_error e
|
375
|
+
errors += 1
|
376
|
+
end
|
377
|
+
end
|
378
|
+
rescue StandardError => e
|
379
|
+
on_error e, :copy
|
380
|
+
else
|
381
|
+
puts message(to, subdir.size, files.size - errors) if verbose
|
382
|
+
end
|
383
|
+
next
|
384
|
+
end
|
339
385
|
glob = Array(glob || '**/*')
|
340
386
|
target = []
|
387
|
+
from = path + from
|
341
388
|
if workspace
|
342
389
|
Dir.glob(from + '*').each do |path|
|
343
390
|
next unless (path = Pathname.new(path)).directory?
|
@@ -361,16 +408,14 @@ module Squared
|
|
361
408
|
end
|
362
409
|
end
|
363
410
|
else
|
364
|
-
target << [from, dest.join(into, scope ||
|
411
|
+
target << [from, dest.join(into, scope || npmname)]
|
365
412
|
end
|
366
413
|
target.each do |src, to|
|
367
414
|
glob.each { |val| log.info "cp #{from + val} #{to}" }
|
368
415
|
begin
|
369
416
|
copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
|
370
417
|
rescue StandardError => e
|
371
|
-
|
372
|
-
ret = on(:error, :copy, e)
|
373
|
-
raise if exception && ret != true
|
418
|
+
on_error e, :copy
|
374
419
|
end
|
375
420
|
end
|
376
421
|
end
|
@@ -436,19 +481,14 @@ module Squared
|
|
436
481
|
log.info cmd.to_s
|
437
482
|
on :first, :outdated
|
438
483
|
end
|
439
|
-
banner = format_banner(cmd.temp(dryrun ? '
|
484
|
+
banner = format_banner(cmd.temp(dryrun ? '--dry-run' : nil))
|
440
485
|
print_item banner if sync
|
441
486
|
begin
|
442
487
|
data = pwd_set { `#{cmd.temp('--json', '--loglevel=error')}` }
|
443
488
|
doc = dependfile.read
|
444
489
|
json = JSON.parse(doc)
|
445
490
|
rescue StandardError => e
|
446
|
-
|
447
|
-
unless dryrun
|
448
|
-
ret = on(:error, :outdated, e)
|
449
|
-
raise if exception && ret != true
|
450
|
-
end
|
451
|
-
warn log_message(Logger::WARN, e) if warning?
|
491
|
+
on_error(e, :outdated, dryrun: dryrun)
|
452
492
|
return
|
453
493
|
else
|
454
494
|
dep1 = json['dependencies'] || {}
|
@@ -599,16 +639,16 @@ module Squared
|
|
599
639
|
package('update', from: :update)
|
600
640
|
end
|
601
641
|
|
602
|
-
def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil,
|
642
|
+
def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, access: nil, dryrun: nil)
|
603
643
|
if !version || read_packagemanager(:private)
|
604
644
|
warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: version ? 'private' : nil)
|
605
645
|
return
|
606
646
|
end
|
607
647
|
cmd = session 'npm', 'publish'
|
608
|
-
cmd << basic_option('otp', otp) if otp
|
609
|
-
cmd << basic_option('tag', tag) if tag
|
610
|
-
cmd << basic_option('access', access) if access
|
611
|
-
dryrun
|
648
|
+
cmd << basic_option('otp', otp) if otp &&= option('otp')
|
649
|
+
cmd << basic_option('tag', tag) if tag &&= option('tag')
|
650
|
+
cmd << basic_option('access', access) if access &&= option('access')
|
651
|
+
dryrun &&= dryrun?('npm')
|
612
652
|
if dryrun
|
613
653
|
cmd << '--dry-run'
|
614
654
|
else
|
@@ -616,7 +656,7 @@ module Squared
|
|
616
656
|
log.info cmd.to_s
|
617
657
|
end
|
618
658
|
if sync
|
619
|
-
run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(
|
659
|
+
run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
|
620
660
|
else
|
621
661
|
on :first, from
|
622
662
|
pwd_set(from: :publish, dryrun: dryrun) do
|
@@ -735,9 +775,7 @@ module Squared
|
|
735
775
|
raise_error('version not found', hint: dependfile)
|
736
776
|
end
|
737
777
|
rescue StandardError => e
|
738
|
-
|
739
|
-
ret = on(:error, :bump, e)
|
740
|
-
raise if exception && ret != true
|
778
|
+
on_error e, :bump
|
741
779
|
end
|
742
780
|
end
|
743
781
|
|
@@ -876,7 +914,7 @@ module Squared
|
|
876
914
|
end
|
877
915
|
|
878
916
|
def version
|
879
|
-
|
917
|
+
@version ||= read_packagemanager(:version)
|
880
918
|
end
|
881
919
|
|
882
920
|
def packagename
|
@@ -902,7 +940,7 @@ module Squared
|
|
902
940
|
else
|
903
941
|
if key
|
904
942
|
@pm[key]
|
905
|
-
elsif (ret = @pm[:_]) && !(version && ret[(ret.index('@') + 1)..-1]
|
943
|
+
elsif (ret = @pm[:_]) && !(version && semcmp(ret[(ret.index('@') + 1)..-1], version) == 1)
|
906
944
|
ret
|
907
945
|
end
|
908
946
|
end
|
@@ -967,6 +1005,10 @@ module Squared
|
|
967
1005
|
'package.json' if parent&.has?('outdated', Node.ref)
|
968
1006
|
end
|
969
1007
|
|
1008
|
+
def npmname
|
1009
|
+
packagename || project
|
1010
|
+
end
|
1011
|
+
|
970
1012
|
def npmnotice
|
971
1013
|
[
|
972
1014
|
{ pat: /^(npm error )(code|\d+)(.+)$/, styles: color(:cyan), index: 2 },
|
@@ -114,7 +114,7 @@ module Squared
|
|
114
114
|
|
115
115
|
namespace name do
|
116
116
|
Python.subtasks do |action, flags|
|
117
|
-
next if
|
117
|
+
next if task_pass?(action)
|
118
118
|
|
119
119
|
if flags.nil?
|
120
120
|
case action
|
@@ -183,7 +183,7 @@ module Squared
|
|
183
183
|
elsif i || args.empty?
|
184
184
|
readline('Enter command', force: true)
|
185
185
|
else
|
186
|
-
if (val = command_args(args, prefix: 'python'))
|
186
|
+
if (val = command_args(args, min: 1, prefix: 'python'))
|
187
187
|
args << val
|
188
188
|
end
|
189
189
|
args.join(' ')
|
@@ -366,7 +366,11 @@ module Squared
|
|
366
366
|
pwd_set(from: :outdated) do
|
367
367
|
buffer = []
|
368
368
|
out = ->(val) { sync ? puts(val) : buffer << val }
|
369
|
-
|
369
|
+
if workspace.windows?
|
370
|
+
(venv ? command(runenv, cmd) : `#{cmd}`).lines
|
371
|
+
else
|
372
|
+
IO.popen(runenv || {}, cmd)
|
373
|
+
end.each do |line|
|
370
374
|
next if line.match?(/^[ -]+$/)
|
371
375
|
|
372
376
|
if start > 0
|
@@ -488,7 +492,7 @@ module Squared
|
|
488
492
|
if srcdir
|
489
493
|
args = flag == :pdm ? ['d', 'dest'] : ['o', 'output']
|
490
494
|
if op.arg?(*args)
|
491
|
-
op.
|
495
|
+
op.push(srcdir)
|
492
496
|
else
|
493
497
|
op << quote_option(args.last, path + srcdir)
|
494
498
|
end
|
@@ -531,7 +535,7 @@ module Squared
|
|
531
535
|
case flag
|
532
536
|
when :hatch, :twine
|
533
537
|
if op.empty?
|
534
|
-
op.
|
538
|
+
op.push("#{dist.call}/*")
|
535
539
|
else
|
536
540
|
op.map! { |val| path + val }
|
537
541
|
end
|
@@ -651,7 +655,7 @@ module Squared
|
|
651
655
|
if edit
|
652
656
|
edit = path + edit unless %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
|
653
657
|
if flag == :editable
|
654
|
-
op.
|
658
|
+
op.push(edit)
|
655
659
|
else
|
656
660
|
target << quote_option('e', edit)
|
657
661
|
end
|
@@ -847,8 +851,8 @@ module Squared
|
|
847
851
|
return if !venv || (venvbin.directory? && !venvbin.empty?)
|
848
852
|
|
849
853
|
puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'init')
|
850
|
-
|
851
|
-
venv_create(venv,
|
854
|
+
opts = @venvopts&.map { |val| OptionPartition.strip(val) }&.flatten
|
855
|
+
venv_create(venv, opts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
|
852
856
|
puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'created')
|
853
857
|
end
|
854
858
|
|