squared 0.8.4 → 0.9.0.pre1
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 +87 -3
- data/README.md +159 -117
- data/exe/sqd +224 -0
- data/lib/squared/common/base.rb +7 -3
- data/lib/squared/common/format.rb +8 -3
- data/lib/squared/common/host.rb +4 -0
- data/lib/squared/common/prompt.rb +65 -31
- data/lib/squared/common/shell.rb +3 -1
- data/lib/squared/common/system.rb +2 -9
- data/lib/squared/config.rb +3 -3
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +24 -13
- data/lib/squared/workspace/project/base.rb +103 -48
- data/lib/squared/workspace/project/docker.rb +160 -83
- data/lib/squared/workspace/project/git.rb +65 -88
- data/lib/squared/workspace/project/node.rb +28 -25
- data/lib/squared/workspace/project/python.rb +58 -19
- data/lib/squared/workspace/project/ruby.rb +44 -33
- data/lib/squared/workspace/project/support/class.rb +1 -1
- data/lib/squared/workspace/project/support/optionpartition.rb +25 -18
- data/lib/squared/workspace/repo.rb +6 -6
- data/lib/squared/workspace/series.rb +4 -2
- data/squared.gemspec +7 -5
- metadata +21 -5
|
@@ -102,7 +102,7 @@ module Squared
|
|
|
102
102
|
|
|
103
103
|
@@tasks = {}
|
|
104
104
|
@@graph = { _: [] }
|
|
105
|
-
@@asdf = Pathname.new(ENV['ASDF_DIR'] || "#{Dir.home}/.asdf").
|
|
105
|
+
@@asdf = Pathname.new(ENV['ASDF_DIR'] || "#{Dir.home}/.asdf").then do |path|
|
|
106
106
|
version = if path.join('asdf.sh').exist?
|
|
107
107
|
15
|
|
108
108
|
elsif ENV['ASDF_DATA_DIR'] && (path = Pathname.new(ENV['ASDF_DATA_DIR'])).exist?
|
|
@@ -640,7 +640,7 @@ module Squared
|
|
|
640
640
|
end
|
|
641
641
|
env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
|
|
642
642
|
start, neg = start.partition { |name| !name.start_with?('-') }
|
|
643
|
-
data = graph_collect(self, start, pass: neg.map { |name| name[1
|
|
643
|
+
data = graph_collect(self, start, pass: neg.map { |name| name[1..] })
|
|
644
644
|
unless out
|
|
645
645
|
data[name] << self
|
|
646
646
|
on :first, :graph
|
|
@@ -700,7 +700,7 @@ module Squared
|
|
|
700
700
|
headers = headers.is_a?(Hash) ? headers.merge(data) : data
|
|
701
701
|
end
|
|
702
702
|
if file
|
|
703
|
-
ext ||= File.extname(file)[1
|
|
703
|
+
ext ||= File.extname(file)[1..]
|
|
704
704
|
else
|
|
705
705
|
require 'open-uri'
|
|
706
706
|
data = nil
|
|
@@ -824,7 +824,7 @@ module Squared
|
|
|
824
824
|
cmd << name
|
|
825
825
|
banner = false if flag == :latest || flag == :where
|
|
826
826
|
end
|
|
827
|
-
success?(run(banner: banner, from: symjoin('asdf', flag)), banner,
|
|
827
|
+
success?(run(banner: banner, from: symjoin('asdf', flag)), banner, %i[set reshim].include?(flag))
|
|
828
828
|
end
|
|
829
829
|
|
|
830
830
|
def first(key, *args, **kwargs, &blk)
|
|
@@ -876,7 +876,7 @@ module Squared
|
|
|
876
876
|
return
|
|
877
877
|
end
|
|
878
878
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
879
|
-
if interactive && sync && (
|
|
879
|
+
if interactive && sync && !(@session && option('y'))
|
|
880
880
|
print_item(series: true)
|
|
881
881
|
msg, y, h = case interactive
|
|
882
882
|
when Array
|
|
@@ -913,7 +913,7 @@ module Squared
|
|
|
913
913
|
ret = shell_t(*args, name: send, chdir: chdir, exception: exception, timeout: timeout || 0)
|
|
914
914
|
end
|
|
915
915
|
rescue Timeout::Error => e
|
|
916
|
-
print_error(Logger::ERROR,
|
|
916
|
+
print_error(Logger::ERROR, e, subject: name, hint: cmd)
|
|
917
917
|
exit 1 unless exception?(Logger::DEBUG, Logger::INFO)
|
|
918
918
|
rescue => e
|
|
919
919
|
on_error(e, exception: true)
|
|
@@ -924,9 +924,9 @@ module Squared
|
|
|
924
924
|
end
|
|
925
925
|
end
|
|
926
926
|
|
|
927
|
-
def scope(
|
|
927
|
+
def scope(...)
|
|
928
928
|
namespace name do
|
|
929
|
-
task(
|
|
929
|
+
task(...)
|
|
930
930
|
end
|
|
931
931
|
end
|
|
932
932
|
|
|
@@ -1288,26 +1288,25 @@ module Squared
|
|
|
1288
1288
|
file = if (val = env('LOG_FILE'))
|
|
1289
1289
|
Time.now.strftime(val)
|
|
1290
1290
|
elsif (val = env('LOG_AUTO'))
|
|
1291
|
-
|
|
1291
|
+
d = Time.now
|
|
1292
1292
|
"#{@name}-%s.log" % [case val
|
|
1293
1293
|
when 'y', 'year'
|
|
1294
|
-
|
|
1294
|
+
d.year
|
|
1295
1295
|
when 'm', 'month'
|
|
1296
|
-
|
|
1296
|
+
d.strftime('%Y-%m')
|
|
1297
1297
|
when 'd', 'day', '1'
|
|
1298
|
-
|
|
1298
|
+
d.strftime('%Y-%m-%d')
|
|
1299
1299
|
else
|
|
1300
|
-
val.include?('%') ?
|
|
1300
|
+
val.include?('%') ? d.strftime(val) : d.strftime('%FT%T%:z')
|
|
1301
1301
|
end]
|
|
1302
1302
|
elsif (val = log[:file])
|
|
1303
1303
|
if val.is_a?(String)
|
|
1304
1304
|
Time.now.strftime(val)
|
|
1305
1305
|
else
|
|
1306
|
-
|
|
1307
|
-
"#{@name}-#{Date.today}.log"
|
|
1306
|
+
"#{@name}-#{Time.now.strftime('%Y-%m-%d')}.log"
|
|
1308
1307
|
end
|
|
1309
1308
|
end
|
|
1310
|
-
.
|
|
1309
|
+
.then do |path|
|
|
1311
1310
|
next unless path
|
|
1312
1311
|
|
|
1313
1312
|
@workspace.home.join(env('LOG_DIR', ''), path).realdirpath
|
|
@@ -1466,7 +1465,7 @@ module Squared
|
|
|
1466
1465
|
|
|
1467
1466
|
t = uniq.call(name = proj.name)
|
|
1468
1467
|
j = if out
|
|
1469
|
-
if i == items.size.pred || (post = items[i.succ
|
|
1468
|
+
if i == items.size.pred || (post = items[i.succ..] - done).empty?
|
|
1470
1469
|
true
|
|
1471
1470
|
elsif !t.empty? && depth > 0
|
|
1472
1471
|
(post - t).empty?
|
|
@@ -1572,14 +1571,18 @@ module Squared
|
|
|
1572
1571
|
end
|
|
1573
1572
|
|
|
1574
1573
|
def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
|
|
1575
|
-
name = "#{key}_#{envname_get}"
|
|
1574
|
+
name = suffix == false ? key : "#{key}_#{envname_get}"
|
|
1576
1575
|
ret = if suffix
|
|
1577
1576
|
ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
|
|
1578
1577
|
elsif strict
|
|
1579
1578
|
ENV[name].to_s
|
|
1580
1579
|
else
|
|
1581
1580
|
ignore = ['0'].freeze if ignore.nil?
|
|
1582
|
-
|
|
1581
|
+
if key =~ /^(.+)_(FORCE|YES|Y)$/ && !(ret = __arg__($2 == 'Y' ? 'YES' : $2, $1)).nil?
|
|
1582
|
+
ret
|
|
1583
|
+
else
|
|
1584
|
+
ENV[name] || ENV.fetch(key, '')
|
|
1585
|
+
end
|
|
1583
1586
|
end
|
|
1584
1587
|
env_yield(ret, default, ignore: ignore, **kwargs, &blk)
|
|
1585
1588
|
end
|
|
@@ -1683,19 +1686,38 @@ module Squared
|
|
|
1683
1686
|
**kwargs)
|
|
1684
1687
|
return unless prefix
|
|
1685
1688
|
|
|
1689
|
+
getarg = ->(key) { ARG[key][s = prefix.downcase] || ARG[key][s.to_sym] }
|
|
1686
1690
|
args.each do |key|
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1691
|
+
ret = case key.downcase
|
|
1692
|
+
when 'force'
|
|
1693
|
+
getarg.call(:FORCE)
|
|
1694
|
+
when 'y'
|
|
1695
|
+
getarg.call(:YES)
|
|
1696
|
+
end
|
|
1697
|
+
return yield(ret) if !ret.nil? && block_given?
|
|
1698
|
+
|
|
1699
|
+
case ret.to_s
|
|
1700
|
+
when '0'
|
|
1701
|
+
next
|
|
1702
|
+
when 'true'
|
|
1703
|
+
return true
|
|
1704
|
+
when 'false'
|
|
1705
|
+
return false
|
|
1706
|
+
else
|
|
1707
|
+
ret ||= env(env_key(prefix.to_s.stripext, key), **kwargs)
|
|
1708
|
+
next unless ret && (!pat || ret.match?(pat))
|
|
1709
|
+
|
|
1710
|
+
if target
|
|
1711
|
+
if path
|
|
1712
|
+
target << quote_option(key, basepath(ret))
|
|
1713
|
+
elsif quote
|
|
1714
|
+
target << quote_option(key, ret)
|
|
1715
|
+
elsif escape
|
|
1716
|
+
target << shell_option(key, ret)
|
|
1717
|
+
end
|
|
1696
1718
|
end
|
|
1719
|
+
return block_given? ? yield(ret) : ret
|
|
1697
1720
|
end
|
|
1698
|
-
return block_given? ? yield(ret) : ret
|
|
1699
1721
|
end
|
|
1700
1722
|
nil
|
|
1701
1723
|
end
|
|
@@ -1808,6 +1830,8 @@ module Squared
|
|
|
1808
1830
|
|
|
1809
1831
|
case from
|
|
1810
1832
|
when :outdated
|
|
1833
|
+
return if ENV['BANNER'] == 'false'
|
|
1834
|
+
|
|
1811
1835
|
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
|
1812
1836
|
sub_style!(out[1], **opt_style(theme[:major], /^( +major )(\d+)(.+)$/, 2))
|
|
1813
1837
|
sub_style!(out[1], **opt_style(theme[:active], /^(.+)(minor )(\d+)(.+)$/, 3))
|
|
@@ -2030,27 +2054,27 @@ module Squared
|
|
|
2030
2054
|
val
|
|
2031
2055
|
end
|
|
2032
2056
|
end
|
|
2033
|
-
base.update(data)
|
|
2034
|
-
.update(ret)
|
|
2057
|
+
base.update(data, ret)
|
|
2035
2058
|
end
|
|
2036
2059
|
|
|
2037
2060
|
def merge_opts(base, data)
|
|
2061
|
+
s = '%s %s'
|
|
2038
2062
|
case data
|
|
2039
2063
|
when String
|
|
2040
2064
|
case base
|
|
2041
2065
|
when String
|
|
2042
|
-
|
|
2066
|
+
s % [base, data]
|
|
2043
2067
|
when Hash
|
|
2044
|
-
|
|
2068
|
+
s % [append_hash(base, target: []).join(' '), data]
|
|
2045
2069
|
when Enumerable
|
|
2046
|
-
|
|
2070
|
+
s % [base.to_a.join(' '), data]
|
|
2047
2071
|
else
|
|
2048
2072
|
data
|
|
2049
2073
|
end
|
|
2050
2074
|
when Hash
|
|
2051
2075
|
case base
|
|
2052
2076
|
when String
|
|
2053
|
-
|
|
2077
|
+
s % [base, append_hash(data, target: []).join(' ')]
|
|
2054
2078
|
when Hash
|
|
2055
2079
|
base.merge(data)
|
|
2056
2080
|
when Enumerable
|
|
@@ -2061,9 +2085,9 @@ module Squared
|
|
|
2061
2085
|
when Enumerable
|
|
2062
2086
|
case base
|
|
2063
2087
|
when String
|
|
2064
|
-
|
|
2088
|
+
s % [base, data.to_a.join(' ')]
|
|
2065
2089
|
when Hash
|
|
2066
|
-
|
|
2090
|
+
s % [append_hash(base, target: []).join(' '), data.to_a.join(' ')]
|
|
2067
2091
|
when Enumerable
|
|
2068
2092
|
Set.new(base.to_a + data.to_a).to_a
|
|
2069
2093
|
else
|
|
@@ -2097,6 +2121,17 @@ module Squared
|
|
|
2097
2121
|
end || []
|
|
2098
2122
|
end
|
|
2099
2123
|
|
|
2124
|
+
def parse_select(kwargs = {})
|
|
2125
|
+
pa, ch = ENV.fetch('SELECT', '0:0').split(':').map(&:to_i)
|
|
2126
|
+
if pa > 0
|
|
2127
|
+
kwargs[:page] = pa
|
|
2128
|
+
elsif !kwargs.key?(:page)
|
|
2129
|
+
kwargs[:page] = ARG[:PAGE]
|
|
2130
|
+
end
|
|
2131
|
+
kwargs[:max] = ch if ch > 0
|
|
2132
|
+
kwargs
|
|
2133
|
+
end
|
|
2134
|
+
|
|
2100
2135
|
def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
|
|
2101
2136
|
if args && key
|
|
2102
2137
|
val = args.fetch(key, nil)
|
|
@@ -2130,9 +2165,9 @@ module Squared
|
|
|
2130
2165
|
end
|
|
2131
2166
|
|
|
2132
2167
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
2133
|
-
force: true, **kwargs)
|
|
2168
|
+
force: true, pipe: self.pipe, **kwargs)
|
|
2134
2169
|
puts unless series || printfirst?
|
|
2135
|
-
ret = choice(msg, list, multiple: multiple, force: force, **kwargs)
|
|
2170
|
+
ret = choice(msg, list, multiple: multiple, force: force, pipe: pipe, **parse_select(kwargs))
|
|
2136
2171
|
unless ret && !ret.empty?
|
|
2137
2172
|
exit 1 if force
|
|
2138
2173
|
return
|
|
@@ -2216,12 +2251,12 @@ module Squared
|
|
|
2216
2251
|
end
|
|
2217
2252
|
|
|
2218
2253
|
def relativepath(*list, all: false)
|
|
2219
|
-
list.
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2254
|
+
list.filter_map do |val|
|
|
2255
|
+
next unless projectpath?(file = Pathname.new(val))
|
|
2256
|
+
|
|
2257
|
+
out = (file.absolute? ? file.relative_path_from(path) : file.cleanpath).to_s
|
|
2258
|
+
all && file.to_s.end_with?('/') ? "#{out}/*" : out
|
|
2259
|
+
end
|
|
2225
2260
|
end
|
|
2226
2261
|
|
|
2227
2262
|
def projectmap(files, resolve: true, parent: false, pass: true)
|
|
@@ -2324,6 +2359,19 @@ module Squared
|
|
|
2324
2359
|
cur[2] == lat[2] ? 3 : 2
|
|
2325
2360
|
end
|
|
2326
2361
|
|
|
2362
|
+
def semapp(name, *args, minor: true, patch: true, pre: false, env: false)
|
|
2363
|
+
if args.empty?
|
|
2364
|
+
args << '--version'
|
|
2365
|
+
else
|
|
2366
|
+
args.map! { |s| shell_quote(s, force: false) }
|
|
2367
|
+
end
|
|
2368
|
+
n = minor ? patch ? pre ? -1 : 4 : 2 : 0
|
|
2369
|
+
IO.popen([shell_bin(name, env: env), *args], chdir: path, &:read).scan(SEM_VER).first
|
|
2370
|
+
&.slice(0..n)&.join or raise
|
|
2371
|
+
rescue
|
|
2372
|
+
'0.0.0'
|
|
2373
|
+
end
|
|
2374
|
+
|
|
2327
2375
|
def semmajor?(cur, want)
|
|
2328
2376
|
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[6]
|
|
2329
2377
|
end
|
|
@@ -2337,7 +2385,7 @@ module Squared
|
|
|
2337
2385
|
end
|
|
2338
2386
|
|
|
2339
2387
|
def indexitem(val)
|
|
2340
|
-
[$1.to_i, $2 && $2[1
|
|
2388
|
+
[$1.to_i, $2 && $2[1..]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
|
|
2341
2389
|
end
|
|
2342
2390
|
|
|
2343
2391
|
def indexerror(val, list = nil)
|
|
@@ -2441,7 +2489,6 @@ module Squared
|
|
|
2441
2489
|
def pwd_set(cmd = nil, pass: false, timeout: nil, from: @on[:from].last, **kwargs, &blk)
|
|
2442
2490
|
return if from == false
|
|
2443
2491
|
|
|
2444
|
-
require 'timeout'
|
|
2445
2492
|
unless (path.to_s == Dir.pwd || pass) && (mri? || !windows?)
|
|
2446
2493
|
pwd = Dir.pwd
|
|
2447
2494
|
Dir.chdir(path)
|
|
@@ -2738,7 +2785,15 @@ module Squared
|
|
|
2738
2785
|
end
|
|
2739
2786
|
|
|
2740
2787
|
def dryrun?(target: @session, prefix: target&.first, **)
|
|
2741
|
-
|
|
2788
|
+
val = ENV['DRY_RUN'] if (val = option('dry-run', target: target, prefix: prefix)).nil?
|
|
2789
|
+
case val.to_s
|
|
2790
|
+
when '0' then nil
|
|
2791
|
+
when 'false'
|
|
2792
|
+
return false
|
|
2793
|
+
else
|
|
2794
|
+
return true if val
|
|
2795
|
+
end
|
|
2796
|
+
Array(target).include?('--dry-run')
|
|
2742
2797
|
end
|
|
2743
2798
|
|
|
2744
2799
|
def pwd?
|