squared 0.3.5 → 0.4.0
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 +53 -2
- data/README.md +13 -2
- data/README.ruby.md +168 -88
- data/lib/squared/app.rb +1 -0
- data/lib/squared/common/base.rb +6 -1
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +24 -12
- data/lib/squared/common/prompt.rb +2 -2
- data/lib/squared/common/shell.rb +52 -39
- data/lib/squared/common/utils.rb +54 -1
- data/lib/squared/config.rb +1 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +16 -13
- data/lib/squared/workspace/project/base.rb +429 -123
- data/lib/squared/workspace/project/docker.rb +572 -0
- data/lib/squared/workspace/project/git.rb +405 -157
- data/lib/squared/workspace/project/node.rb +51 -51
- data/lib/squared/workspace/project/python.rb +115 -24
- data/lib/squared/workspace/project/ruby.rb +33 -34
- data/lib/squared/workspace/project.rb +7 -1
- data/lib/squared/workspace/repo.rb +9 -4
- data/lib/squared/workspace/series.rb +1 -1
- metadata +2 -1
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'date'
|
4
|
+
require 'time'
|
5
|
+
require 'digest'
|
6
|
+
|
3
7
|
module Squared
|
4
8
|
module Workspace
|
5
9
|
module Git
|
@@ -7,7 +11,9 @@ module Squared
|
|
7
11
|
GIT_PROTO = %r{^(?:https?|ssh|git|file)://}i.freeze
|
8
12
|
private_constant :GIT_REPO, :GIT_PROTO
|
9
13
|
|
10
|
-
|
14
|
+
attr_reader :revfile
|
15
|
+
|
16
|
+
def git(name, uri = nil, base: nil, repo: [], options: {}, cache: nil)
|
11
17
|
data = {}
|
12
18
|
check = ->(proj) { proj.is_a?(Project::Git) && !proj.exclude?(Project::Git.ref) && git_clone?(proj.path) }
|
13
19
|
if uri.is_a?(Array)
|
@@ -17,15 +23,15 @@ module Squared
|
|
17
23
|
data[name.to_s] = uri
|
18
24
|
elsif name.is_a?(Enumerable)
|
19
25
|
data = name.to_h
|
20
|
-
elsif name.is_a?(String) && name
|
26
|
+
elsif name.is_a?(String) && name.match?(GIT_PROTO)
|
21
27
|
base = name
|
22
28
|
@project.each_value { |proj| repo << proj if !proj.parent && check.(proj) }
|
23
29
|
else
|
24
|
-
warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid') if warning
|
30
|
+
warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid', pass: true) if warning
|
25
31
|
return self
|
26
32
|
end
|
27
33
|
if base
|
28
|
-
base = base
|
34
|
+
base = base.match?(GIT_PROTO) ? "#{base.chomp('/')}/" : @root.join(base)
|
29
35
|
repo.each do |target|
|
30
36
|
if target.is_a?(Project::Git)
|
31
37
|
data[target.localname] = target.project
|
@@ -55,6 +61,23 @@ module Squared
|
|
55
61
|
(GIT_REPO[main] ||= {})[key] = [uri.to_s, opts]
|
56
62
|
(@kind[key] ||= []) << Project::Git
|
57
63
|
end
|
64
|
+
if cache == true
|
65
|
+
revbuild
|
66
|
+
elsif cache
|
67
|
+
revbuild(file: cache)
|
68
|
+
end
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def revbuild(file: nil)
|
73
|
+
@revfile = @home.join(file || "#{@main}.revb")
|
74
|
+
@revdoc = JSON.parse(@revfile.read) if @revfile.exist?
|
75
|
+
rescue StandardError => e
|
76
|
+
@revfile = nil
|
77
|
+
warn log_message(Logger::WARN, e, pass: true) if @warning
|
78
|
+
self
|
79
|
+
else
|
80
|
+
@revdoc = {} unless @revdoc.is_a?(Hash)
|
58
81
|
self
|
59
82
|
end
|
60
83
|
|
@@ -62,23 +85,76 @@ module Squared
|
|
62
85
|
(ret = GIT_REPO[main]) && ret[name]
|
63
86
|
end
|
64
87
|
|
88
|
+
def rev_entry(*keys, val: nil, create: true)
|
89
|
+
return unless @revdoc
|
90
|
+
return @revdoc.dig(*keys) unless val
|
91
|
+
|
92
|
+
data = @revdoc
|
93
|
+
last = keys.pop
|
94
|
+
for key in keys
|
95
|
+
if data[key].is_a?(Hash)
|
96
|
+
data = data[key]
|
97
|
+
elsif create
|
98
|
+
data = data[key] = {}
|
99
|
+
else
|
100
|
+
return
|
101
|
+
end
|
102
|
+
end
|
103
|
+
data[last] = val
|
104
|
+
end
|
105
|
+
|
106
|
+
def rev_timeutc(*keys)
|
107
|
+
rev_entry(*keys, val: rev_timenow)
|
108
|
+
end
|
109
|
+
|
110
|
+
def rev_timesince(*keys, clock: false)
|
111
|
+
epoch = rev_timenow - rev_entry(*keys).to_i
|
112
|
+
rescue StandardError
|
113
|
+
nil
|
114
|
+
else
|
115
|
+
time_format(epoch, clock: clock)
|
116
|
+
end
|
117
|
+
|
118
|
+
def rev_clear(name)
|
119
|
+
rev_write if rev_entry(name, 'revision', val: '', create: false)
|
120
|
+
end
|
121
|
+
|
122
|
+
def rev_write(name = nil, data = nil, utc: nil)
|
123
|
+
return unless @revfile
|
124
|
+
|
125
|
+
if name
|
126
|
+
data&.each { |key, val| rev_entry(name, key, val: val) }
|
127
|
+
rev_timeutc(name, utc) if utc
|
128
|
+
end
|
129
|
+
File.write(@revfile, JSON.pretty_generate(@revdoc))
|
130
|
+
end
|
131
|
+
|
65
132
|
def git_clone?(path, name = nil)
|
66
133
|
return false if name && !git_repo(name)
|
67
134
|
|
68
135
|
!path.exist? || path.empty?
|
69
136
|
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def rev_timenow
|
141
|
+
DateTime.now.strftime('%Q').to_i + time_offset
|
142
|
+
end
|
70
143
|
end
|
71
144
|
Application.include Git
|
72
145
|
|
73
146
|
module Project
|
74
147
|
class Git < Base
|
75
148
|
OPT_GIT = {
|
149
|
+
common: %w[bare p|paginate P|no-pager glob-pathspecs icase-pathspecs literal-pathspecs no-optional-locks
|
150
|
+
no-replace-objects noglob-pathspecs c=q config-env=q exec-path=p namespace=p].freeze,
|
76
151
|
branch: %w[a|all create-reflog i|ignore-case q|quiet r|remotes v|verbose abbrev=i color=b column=b
|
77
|
-
contains=
|
152
|
+
contains=b format=q merged=b no-contains=b no-merged=b points-at=e u|set-upstream-to=e sort=q
|
78
153
|
t|track=b].freeze,
|
79
154
|
checkout: %w[l d|detach f|force ignore-other-worktrees ignore-skip-worktree-bits m|merge p|patch
|
80
155
|
pathspec-file-nul q quiet orphan=e ours theirs conflict=b pathspec-from-file=p
|
81
156
|
t|track=b].freeze,
|
157
|
+
clean: %w[d x X f|force i|interactive n|dry-run q|quiet e|exlcude=q].freeze,
|
82
158
|
diff: {
|
83
159
|
base: %w[0 1|base 2|ours 3|theirs].freeze,
|
84
160
|
show: %w[s exit-code histogram].freeze
|
@@ -88,7 +164,7 @@ module Squared
|
|
88
164
|
recurse-submodules-default=b].freeze,
|
89
165
|
pull: %w[4 6 n t a|append atomic dry-run f|force k|keep n|negotiate-only prefetch p|prune q|quiet
|
90
166
|
set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
|
91
|
-
refmap=q o|server-option=
|
167
|
+
refmap=q o|server-option=q shallow-exclude=e shallow-since=b upload-pack=q].freeze
|
92
168
|
}.freeze,
|
93
169
|
log: {
|
94
170
|
base: %w[all all-match alternate-refs author-date-order basic-regexp bisect boundary cherry cherry-mark
|
@@ -96,7 +172,7 @@ module Squared
|
|
96
172
|
first-parent F|fixed-strings follow full-diff full-history ignore-missing invert-grep left-only
|
97
173
|
merge log-size no-max-parents no-min-parents not P|perl-regexp reflog i|regexp-ignore-case
|
98
174
|
remove-empty reverse right-only simplify-by-decoration simplify-merges single-worktree show-pulls
|
99
|
-
source sparse stdin topo-order g|walk-reflogs after=q ancestry-path=
|
175
|
+
source sparse stdin topo-order g|walk-reflogs after=q ancestry-path=b? author=q before=q
|
100
176
|
branches=q? committer=q decorate=b decorate-refs=q decorate-refs-exclude=q exclude=q
|
101
177
|
exclude-hidden=b? glob=q grep=q grep-reflog=q L=q n|max-count=i max-parents=i min-parents=i
|
102
178
|
no-walk=b? remotes=q? since=q since-as-filter=q skip=i tags=q? until=q].freeze,
|
@@ -107,9 +183,9 @@ module Squared
|
|
107
183
|
W|function-context w|ignore-all-space ignore-blank-lines ignore-cr-at-eol ignore-space-at-eol
|
108
184
|
b|ignore-space-change D|irreversible-delete graph ita-invisible-in-index minimal name-only
|
109
185
|
name-status no-color-moved-ws no-prefix no-renames numstat patch-with-raw patch-with-stat patience
|
110
|
-
pickaxe-all pickaxe-regex raw shortstat summary a|text abbrev=i? anchored=q B|break-rewrites=
|
186
|
+
pickaxe-all pickaxe-regex raw shortstat summary a|text abbrev=i? anchored=q B|break-rewrites=b?
|
111
187
|
color=b color-moved=b color-moved-ws=b color-words=q? diff-algorithm=b diff-filter=e? X|dirstat=q?
|
112
|
-
dirstat-by-file=q? dst-prefix=q C|find-copies=i? find-object=
|
188
|
+
dirstat-by-file=q? dst-prefix=q C|find-copies=i? find-object=b M|find-renames=i?
|
113
189
|
I|ignore-matching-lines=q ignore-submodules=b inter-hunk-context=i line-prefix=q output=p
|
114
190
|
output-indicator-context=q output-indicator-new=q output-indicator-old=q relative=p rotate-to=p
|
115
191
|
skip-to=p src-prefix=q stat=q? stat-width=i stat-name-width=i stat-count=i submodule=b? U|unified=i
|
@@ -118,25 +194,32 @@ module Squared
|
|
118
194
|
ls_files: %w[z debug deduplicate directory eol error-unmatch exclude-standard full-name k|killed
|
119
195
|
no-empty-directory recurse-submodules sparse s|stage u|unmerged abbrev=i x|exclude=q
|
120
196
|
X|exclude-from=p exclude-per-directory=p format=q with-tree=q].freeze,
|
121
|
-
ls_remote: %w[exit-code get-url q|quiet o|server-option=
|
122
|
-
|
123
|
-
|
197
|
+
ls_remote: %w[exit-code get-url q|quiet o|server-option=q symref sort=q upload-pack=q].freeze,
|
198
|
+
mv: %w[k f|force n|dry-run v|verbose].freeze,
|
199
|
+
pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=qq log=i r|rebase=b? s|strategy=b
|
200
|
+
X|strategy-option=b].freeze,
|
201
|
+
merge: %w[e n allow-unrelated-histories ff-only m=q q|quiet v|verbose cleanup=b F|file=p S|gpg-sign=qq
|
202
|
+
into-name=e log=i s|strategy=b X|strategy-option=b].freeze,
|
124
203
|
rebase: %w[n C=i allow-empty-message apply committer-date-is-author-date edit-todo f|force-rebase ignore-date
|
125
204
|
ignore-whitespace i|interactive keep-base m merge no-ff q|quiet quit r|rebase-merges=b?
|
126
|
-
reset-author-date root show-current-patch signoff v|verbose empty=b S|gpg-sign=
|
127
|
-
s|strategy=b X|strategy-option=b whitespace=
|
205
|
+
reset-author-date root show-current-patch signoff v|verbose empty=b S|gpg-sign=qq onto=e
|
206
|
+
s|strategy=b X|strategy-option=b whitespace=b].freeze,
|
128
207
|
reset: %w[N pathspec-file-nul q|quiet pathspec-from-file=p].freeze,
|
129
208
|
restore: %w[ignore-unmerged ignore-skip-worktree-bits m|merge ours p|patch pathspec-file-nul S|staged theirs
|
130
209
|
W|worktree conflict=b pathspec-from-file=p s|source=q].freeze,
|
210
|
+
revert: %w[e abort continue no-commit quit reference skip cleanup=b S|gpg-sign=qq m|mainline=i s|signoff
|
211
|
+
strategy=b X|strategy-option=b].freeze,
|
131
212
|
rev_parse: {
|
132
213
|
output: %w[absolute-git-dir all flags git-common-dir git-dir is-bare-repository is-inside-git-dir
|
133
214
|
is-inside-work-tree is-shallow-repository local-env-vars no-flags no-revs not q|quiet sq
|
134
215
|
revs-only shared-index-path show-cdup show-prefix show-toplevel show-superproject-working-tree
|
135
|
-
sq-quote symbolic symbolic-full-name verify abbrev-ref=b? after=q before=q default=
|
216
|
+
sq-quote symbolic symbolic-full-name verify abbrev-ref=b? after=q before=q default=q
|
136
217
|
disambiguate=b exclude=q exclude-hidden=b glob=q git-path=p path-format=b? prefix=q branches=q?
|
137
218
|
remotes=q? resolve-git-dir=p short=i? show-object-format=b? since=q tags=q? until=q].freeze,
|
138
219
|
parseopt: %w[keep-dashdash stop-at-non-option stuck-long].freeze
|
139
220
|
}.freeze,
|
221
|
+
rm: %w[r cached f|force n|dry-run ignore-unmatch pathspec-file-nul q|quiet sparse v|verbose
|
222
|
+
pathspec-from-file=p].freeze,
|
140
223
|
show: %w[t combined-all-paths no-diff-merges remerge-diff show-signature diff-merges=b encoding=b
|
141
224
|
expand-tabs=i notes=q show-notes=q?].freeze,
|
142
225
|
stash: {
|
@@ -146,7 +229,8 @@ module Squared
|
|
146
229
|
pop: %w[index].freeze,
|
147
230
|
apply: %w[index].freeze
|
148
231
|
}.freeze,
|
149
|
-
|
232
|
+
status: %w[untracked-files=b? u|ignore-submodules=m? ignored=b?],
|
233
|
+
tag: %w[create-reflog column=b contains=b? format=q merged=b? n=i no-contains=b? no-merged=b? points-at=q
|
150
234
|
sort=q].freeze,
|
151
235
|
no: {
|
152
236
|
fetch: {
|
@@ -162,20 +246,26 @@ module Squared
|
|
162
246
|
tag: %w[column].freeze,
|
163
247
|
branch: %w[color-moved column color track].freeze,
|
164
248
|
checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
|
249
|
+
merge: %w[autostash edit ff gpg-sign log progress overwrite-ignore rerere-autoupdate signoff squash stat
|
250
|
+
verify verify-signatures].freeze,
|
165
251
|
rebase: %w[autosquash autostash fork-point gpg-sign keep-empty reapply-cherry-picks reschedule-failed-exec
|
166
252
|
rerere-autoupdate stat update-refs verify].freeze,
|
167
253
|
reset: %w[refresh].freeze,
|
168
254
|
restore: %w[overlay progress recurse-submodules].freeze,
|
255
|
+
revert: %w[edit gpg-sign rerere-autoupdate].freeze,
|
169
256
|
show: %w[standard-notes].freeze
|
170
257
|
}.freeze
|
171
|
-
}
|
258
|
+
}.freeze
|
172
259
|
VAL_GIT = {
|
260
|
+
merge: {
|
261
|
+
send: %w[continue abort quit].freeze
|
262
|
+
}.freeze,
|
173
263
|
rebase: {
|
174
264
|
send: %w[continue skip abort quit].freeze,
|
175
265
|
value: %w[true false merges interactive].freeze
|
176
266
|
}.freeze,
|
177
267
|
reset: %w[soft mixed hard merge keep recurse-submodules no-recurse-submodules].freeze
|
178
|
-
}
|
268
|
+
}.freeze
|
179
269
|
private_constant :OPT_GIT, :VAL_GIT
|
180
270
|
|
181
271
|
class << self
|
@@ -207,7 +297,7 @@ module Squared
|
|
207
297
|
end
|
208
298
|
|
209
299
|
def tasks
|
210
|
-
%i[pull rebase fetch clone stash status].freeze
|
300
|
+
%i[pull rebase fetch clone stash status branch revbuild].freeze
|
211
301
|
end
|
212
302
|
|
213
303
|
def batchargs
|
@@ -225,16 +315,17 @@ module Squared
|
|
225
315
|
'branch' => %i[create set delete move copy list edit current].freeze,
|
226
316
|
'checkout' => %i[commit branch track detach path].freeze,
|
227
317
|
'commit' => %i[add all amend amend-orig].freeze,
|
228
|
-
'diff' => %i[head
|
318
|
+
'diff' => %i[head branch files view between contain].freeze,
|
229
319
|
'fetch' => %i[origin remote].freeze,
|
230
320
|
'files' => %i[cached modified deleted others ignored].freeze,
|
321
|
+
'git' => %i[clean mv restore revert rm].freeze,
|
231
322
|
'log' => %i[view between contain].freeze,
|
323
|
+
'merge' => %i[commit no-commit send].freeze,
|
232
324
|
'pull' => %i[origin remote].freeze,
|
233
325
|
'rebase' => %i[branch onto send].freeze,
|
234
326
|
'refs' => %i[heads tags remote].freeze,
|
235
327
|
'reset' => %i[commit index patch mode].freeze,
|
236
|
-
'
|
237
|
-
'rev' => %i[commit branch output parseopt].freeze,
|
328
|
+
'rev' => %i[commit branch output parseopt build].freeze,
|
238
329
|
'show' => %i[format oneline].freeze,
|
239
330
|
'stash' => %i[push pop apply drop list].freeze,
|
240
331
|
'tag' => %i[add delete list].freeze
|
@@ -242,7 +333,7 @@ module Squared
|
|
242
333
|
|
243
334
|
def initialize(*, **)
|
244
335
|
super
|
245
|
-
initialize_ref
|
336
|
+
initialize_ref Git.ref if gitpath.exist?
|
246
337
|
end
|
247
338
|
|
248
339
|
def ref
|
@@ -287,19 +378,6 @@ module Squared
|
|
287
378
|
commit(flag, refs: refs)
|
288
379
|
end
|
289
380
|
end
|
290
|
-
when 'restore'
|
291
|
-
if flag == :source
|
292
|
-
format_desc action, flag, 'tree,opts*,pathspec*'
|
293
|
-
task flag, [:tree] do |_, args|
|
294
|
-
tree = param_guard(action, flag, args: args, key: :tree)
|
295
|
-
restore(flag, args.extras, tree: tree)
|
296
|
-
end
|
297
|
-
else
|
298
|
-
format_desc action, flag, 'opts*,pathspec+'
|
299
|
-
task flag do |_, args|
|
300
|
-
restore flag, args.to_a
|
301
|
-
end
|
302
|
-
end
|
303
381
|
when 'tag'
|
304
382
|
case flag
|
305
383
|
when :list
|
@@ -333,9 +411,19 @@ module Squared
|
|
333
411
|
case flag
|
334
412
|
when :view, :between, :contain
|
335
413
|
if flag == :view && action == 'log'
|
336
|
-
format_desc action, flag, '(^)commit*,pathspec*,opts*'
|
414
|
+
format_desc action, flag, '(^)commit/H0*,pathspec*,opts*'
|
337
415
|
task flag do |_, args|
|
338
|
-
|
416
|
+
index = []
|
417
|
+
args.to_a.each do |val|
|
418
|
+
if val =~ /^H(\d+)$/
|
419
|
+
index << "HEAD~#{$1}"
|
420
|
+
elsif (sha = commithash(val))
|
421
|
+
index << sha
|
422
|
+
elsif val.start_with?('^') || (!%r{^[.\\/]}.match?(val) && !%r{[\\/]$}.match?(val))
|
423
|
+
index << shell_quote(val)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
logx(flag, args.to_a.drop(index.size), index: index)
|
339
427
|
end
|
340
428
|
else
|
341
429
|
format_desc action, flag, 'commit1,commit2,pathspec*,opts*'
|
@@ -345,10 +433,16 @@ module Squared
|
|
345
433
|
__send__(action == 'log' ? :logx : :diff, flag, args.extras, range: [commit1, commit2])
|
346
434
|
end
|
347
435
|
end
|
348
|
-
when :head
|
349
|
-
format_desc action, flag, 'opts*,pathspec*'
|
436
|
+
when :head
|
437
|
+
format_desc action, flag, 'commit/H0*,opts*,pathspec*'
|
350
438
|
task flag do |_, args|
|
351
|
-
|
439
|
+
index = []
|
440
|
+
args.to_a.each do |val|
|
441
|
+
break unless val =~ /^H(\d+)$/ || (sha = commithash(val))
|
442
|
+
|
443
|
+
index << ($1 ? "HEAD~#{$1}" : sha)
|
444
|
+
end
|
445
|
+
diff(flag, args.to_a.drop(index.size), index: index)
|
352
446
|
end
|
353
447
|
when :branch
|
354
448
|
format_desc action, flag, 'name,opts*,pathspec*'
|
@@ -493,7 +587,7 @@ module Squared
|
|
493
587
|
show args.format, args.extras
|
494
588
|
end
|
495
589
|
end
|
496
|
-
when 'rebase'
|
590
|
+
when 'rebase', 'merge'
|
497
591
|
case flag
|
498
592
|
when :branch
|
499
593
|
format_desc action, flag, 'opts*,upstream?,branch?'
|
@@ -508,11 +602,18 @@ module Squared
|
|
508
602
|
upstream = param_guard(action, flag, args: args, key: :upstream)
|
509
603
|
rebase(flag, commit: commit, upstream: upstream, branch: args.branch)
|
510
604
|
end
|
605
|
+
when :commit, :'no-commit'
|
606
|
+
format_desc action, flag, 'branch/commit+,opts*'
|
607
|
+
task flag do |_, args|
|
608
|
+
args = param_guard(action, flag, args: args.to_a)
|
609
|
+
merge flag, args
|
610
|
+
end
|
511
611
|
when :send
|
512
|
-
format_desc(action, flag, VAL_GIT[
|
612
|
+
format_desc(action, flag, VAL_GIT[action.to_sym][:send], arg: nil)
|
513
613
|
task flag, [:command] do |_, args|
|
514
|
-
command = param_guard(action, flag, args: args, key: :command
|
515
|
-
|
614
|
+
command = param_guard(action, flag, args: args, key: :command,
|
615
|
+
values: VAL_GIT[action.to_sym][:send])
|
616
|
+
__send__(action, flag, command: command)
|
516
617
|
end
|
517
618
|
end
|
518
619
|
when 'rev'
|
@@ -533,6 +634,11 @@ module Squared
|
|
533
634
|
task flag, [:ref] do |_, args|
|
534
635
|
rev_parse(flag, ref: args.ref)
|
535
636
|
end
|
637
|
+
when :build
|
638
|
+
format_desc action, flag, OPT_GIT[:status]
|
639
|
+
task flag do |_, args|
|
640
|
+
revbuild flag, args.to_a
|
641
|
+
end
|
536
642
|
else
|
537
643
|
format_desc action, flag, 'opts*,args*'
|
538
644
|
task flag do |_, args|
|
@@ -552,6 +658,18 @@ module Squared
|
|
552
658
|
__send__(action == 'refs' ? :ls_remote : :ls_files, flag, args.to_a)
|
553
659
|
end
|
554
660
|
end
|
661
|
+
when 'git'
|
662
|
+
format_desc(action, flag, 'opts*', before: case flag
|
663
|
+
when :rm
|
664
|
+
'source+,destination'
|
665
|
+
when :revert
|
666
|
+
'commit+'
|
667
|
+
else
|
668
|
+
'pathspec*'
|
669
|
+
end)
|
670
|
+
task flag do |_, args|
|
671
|
+
git(flag, args.to_a)
|
672
|
+
end
|
555
673
|
end
|
556
674
|
end
|
557
675
|
end
|
@@ -564,8 +682,18 @@ module Squared
|
|
564
682
|
super
|
565
683
|
end
|
566
684
|
|
685
|
+
def depend(*, **)
|
686
|
+
workspace.rev_clear name
|
687
|
+
super
|
688
|
+
end
|
689
|
+
|
690
|
+
def clean(*, **)
|
691
|
+
workspace.rev_clear name
|
692
|
+
super
|
693
|
+
end
|
694
|
+
|
567
695
|
def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
|
568
|
-
cmd = git_session
|
696
|
+
cmd, opts = git_session('pull', flag && "--#{flag}", opts: opts)
|
569
697
|
if (val = option('rebase', ignore: false))
|
570
698
|
cmd << case val
|
571
699
|
when '0'
|
@@ -578,8 +706,8 @@ module Squared
|
|
578
706
|
no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag)
|
579
707
|
source(sync: sync, sub: if verbose
|
580
708
|
[
|
581
|
-
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: :red, index: 4 },
|
582
|
-
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(-*)(.*)$/, styles: :green, index: 3 }
|
709
|
+
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
|
710
|
+
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(-*)(.*)$/, styles: color(:green), index: 3 }
|
583
711
|
]
|
584
712
|
end, **threadargs)
|
585
713
|
end
|
@@ -588,7 +716,7 @@ module Squared
|
|
588
716
|
command: nil)
|
589
717
|
return pull(:rebase, sync: sync) unless flag
|
590
718
|
|
591
|
-
cmd = git_session
|
719
|
+
cmd, opts = git_session('rebase', opts: opts)
|
592
720
|
case flag
|
593
721
|
when :branch
|
594
722
|
branch = option_sanitize(opts, OPT_GIT[:rebase], no: OPT_GIT[:no][:rebase]).first
|
@@ -617,7 +745,7 @@ module Squared
|
|
617
745
|
end
|
618
746
|
|
619
747
|
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
|
620
|
-
cmd = git_session
|
748
|
+
cmd, opts = git_session('fetch', opts: opts)
|
621
749
|
cmd << '--all' if !remote && !opts.include?('multiple') && option('all')
|
622
750
|
cmd << '--verbose' if verbose && !opts.include?('quiet')
|
623
751
|
append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
|
@@ -649,9 +777,8 @@ module Squared
|
|
649
777
|
|
650
778
|
def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
|
651
779
|
if flag
|
652
|
-
cmd = git_session
|
653
|
-
|
654
|
-
refs = option_sanitize(opts, list).first
|
780
|
+
cmd, opts = git_session('stash', flag, opts: opts)
|
781
|
+
refs = option_sanitize(opts, OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, [])).first
|
655
782
|
case flag
|
656
783
|
when :push
|
657
784
|
append_pathspec refs
|
@@ -666,14 +793,14 @@ module Squared
|
|
666
793
|
return
|
667
794
|
end
|
668
795
|
else
|
669
|
-
git_session
|
796
|
+
git_session('stash', 'push', opts: opts)
|
670
797
|
append_option(%w[all keep-index include-untracked staged].freeze, no: true, ignore: false)
|
671
798
|
append_message option('message', 'm', ignore: false)
|
672
799
|
end
|
673
800
|
source(banner: !quiet?, sync: sync, **threadargs)
|
674
801
|
end
|
675
802
|
|
676
|
-
def status(
|
803
|
+
def status(*)
|
677
804
|
cmd = git_session 'status'
|
678
805
|
cmd << (option('long') ? '--long' : '--short')
|
679
806
|
if (val = option('ignore-submodules', ignore: false))
|
@@ -690,24 +817,76 @@ module Squared
|
|
690
817
|
end
|
691
818
|
append_pathspec
|
692
819
|
out, banner, from = source(io: true)
|
693
|
-
if sync
|
694
|
-
print_item banner
|
695
|
-
banner = nil
|
696
|
-
end
|
697
820
|
ret = write_lines(out, banner: banner, sub: if verbose
|
821
|
+
r = color(:red)
|
822
|
+
g = color(:green)
|
698
823
|
[
|
699
|
-
{ pat: /^(.)([A-Z?!])(.+)$/, styles:
|
700
|
-
{ pat: /^([A-Z?!])(.+)$/, styles:
|
701
|
-
{ pat: /^(\?\?)(.+)$/, styles:
|
824
|
+
{ pat: /^(.)([A-Z?!])(.+)$/, styles: r, index: 2 },
|
825
|
+
{ pat: /^([A-Z?!])(.+)$/, styles: g },
|
826
|
+
{ pat: /^(\?\?)(.+)$/, styles: r },
|
702
827
|
{ pat: /^(## )(.+)(\.{3})(.+)$/,
|
703
|
-
styles: [nil,
|
828
|
+
styles: [nil, g, nil, r], index: -1 }
|
704
829
|
]
|
705
830
|
end)
|
706
831
|
list_result(ret, 'files', from: from, action: 'modified')
|
707
832
|
end
|
708
833
|
|
834
|
+
def revbuild(flag = nil, opts = [], sync: invoked_sync?('revbuild', flag), **kwargs)
|
835
|
+
statusargs = lambda do
|
836
|
+
{
|
837
|
+
include: relativepath(as_a(kwargs[:include]), all: true),
|
838
|
+
exclude: relativepath(as_a(kwargs[:exclude]), all: true)
|
839
|
+
}
|
840
|
+
end
|
841
|
+
unless workspace.closed
|
842
|
+
if @revbuild
|
843
|
+
statusargs.().each { |key, val| @revbuild[key] += val }
|
844
|
+
else
|
845
|
+
@revbuild = statusargs.()
|
846
|
+
end
|
847
|
+
return
|
848
|
+
end
|
849
|
+
sha = source(git_output('rev-parse --verify HEAD'), io: true, banner: false, stdout: true).first.to_s.chomp
|
850
|
+
return if sha.empty?
|
851
|
+
|
852
|
+
args = []
|
853
|
+
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.() : @revbuild || {}
|
854
|
+
case flag
|
855
|
+
when :build
|
856
|
+
opts = option_sanitize(opts, OPT_GIT[:status], target: args).first
|
857
|
+
option_clear opts
|
858
|
+
else
|
859
|
+
args << basic_option('untracked-files', flag) if (flag = option('untracked-files', prefix: 'git'))
|
860
|
+
args << basic_option('ignore-submodules', flag) if (flag = option('ignore-submodules', prefix: 'git'))
|
861
|
+
args << basic_option('ignored', flag) if (flag = option('ignored', prefix: 'git'))
|
862
|
+
end
|
863
|
+
if (cur = workspace.rev_entry(name)) && cur['revision'] == sha
|
864
|
+
files = status_digest(*args, **kwargs)
|
865
|
+
if cur['files'].size == files.size && cur['files'].find { |key, val| files[key] != val }.nil?
|
866
|
+
if verbose
|
867
|
+
if (since = workspace.rev_timesince(name, 'build'))
|
868
|
+
puts log_message(Logger::INFO, name, 'no changes', subject: 'revbuild', hint: "#{since} ago")
|
869
|
+
else
|
870
|
+
workspace.rev_timeutc(name, 'build')
|
871
|
+
end
|
872
|
+
end
|
873
|
+
return
|
874
|
+
end
|
875
|
+
end
|
876
|
+
start = epochtime
|
877
|
+
build(@output, sync: sync, from: :'git:revbuild')
|
878
|
+
rescue StandardError => e
|
879
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
880
|
+
else
|
881
|
+
if verbose
|
882
|
+
msg = sub_style('completed', styles: theme[:active])
|
883
|
+
puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
|
884
|
+
end
|
885
|
+
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) }, utc: 'build')
|
886
|
+
end
|
887
|
+
|
709
888
|
def reset(flag, opts = [], refs: nil, ref: nil, mode: nil, commit: nil)
|
710
|
-
cmd = git_session
|
889
|
+
cmd, opts = git_session('reset', opts: opts)
|
711
890
|
case flag
|
712
891
|
when :commit, :index
|
713
892
|
out = option_sanitize(opts, OPT_GIT[:reset] + VAL_GIT[:reset], no: OPT_GIT[:no][:reset]).first
|
@@ -732,21 +911,19 @@ module Squared
|
|
732
911
|
return
|
733
912
|
end
|
734
913
|
unless ref == false
|
735
|
-
append_commit
|
914
|
+
append_commit(ref, head: true)
|
736
915
|
append_pathspec refs if refs
|
737
916
|
end
|
738
917
|
source
|
739
918
|
end
|
740
919
|
|
741
920
|
def checkout(flag, opts = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil)
|
742
|
-
cmd = git_session
|
921
|
+
cmd, opts = git_session('checkout', opts: opts)
|
743
922
|
append_option 'force', 'merge'
|
744
923
|
case flag
|
745
924
|
when :branch
|
746
925
|
cmd << '--detach' if detach == 'd' || option('detach')
|
747
|
-
|
748
|
-
cmd << shell_option('track', val)
|
749
|
-
end
|
926
|
+
append_option('track', equals: true)
|
750
927
|
cmd << if create
|
751
928
|
shell_option(create, branch)
|
752
929
|
else
|
@@ -778,7 +955,7 @@ module Squared
|
|
778
955
|
end
|
779
956
|
|
780
957
|
def tag(flag, opts = [], refs: [], message: nil, commit: nil)
|
781
|
-
cmd = git_session
|
958
|
+
cmd, opts = git_session('tag', opts: opts)
|
782
959
|
case flag
|
783
960
|
when :add
|
784
961
|
if option('sign')
|
@@ -786,8 +963,8 @@ module Squared
|
|
786
963
|
elsif !session_arg?('s', 'sign', 'u', 'local-user')
|
787
964
|
cmd << '--annotate'
|
788
965
|
end
|
789
|
-
if !commit && message && (
|
790
|
-
commit =
|
966
|
+
if !commit && message && (sha = commithash(message))
|
967
|
+
commit = sha
|
791
968
|
else
|
792
969
|
append_message message
|
793
970
|
end
|
@@ -810,41 +987,27 @@ module Squared
|
|
810
987
|
source
|
811
988
|
end
|
812
989
|
|
813
|
-
def logx(flag, opts = [], range: [])
|
814
|
-
cmd = git_session
|
815
|
-
|
990
|
+
def logx(flag, opts = [], range: [], index: [])
|
991
|
+
cmd, opts = git_session('log', opts: opts)
|
992
|
+
refs = option_sanitize(opts, collect_hash(OPT_GIT[:log]), no: collect_hash(OPT_GIT[:no][:log])).first
|
816
993
|
case flag
|
817
994
|
when :between, :contain
|
818
995
|
cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
|
819
996
|
else
|
820
|
-
|
821
|
-
val.start_with?('^') || (!%r{^[.\\/]}.match?(val) && !%r{[\\/]$}.match?(val)) || commithash(val)
|
822
|
-
end
|
823
|
-
cmd.merge(commit.map { |val| commithash(val) || shell_quote(val) }) unless commit.empty?
|
997
|
+
cmd.merge(index)
|
824
998
|
end
|
825
999
|
append_nocolor
|
826
|
-
append_pathspec
|
1000
|
+
append_pathspec refs
|
827
1001
|
source(exception: false)
|
828
1002
|
end
|
829
1003
|
|
830
|
-
def diff(flag, opts = [], refs: [], branch: nil, range: [])
|
831
|
-
cmd = git_session
|
1004
|
+
def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [])
|
1005
|
+
cmd, opts = git_session('diff', opts: opts)
|
832
1006
|
files = option_sanitize(opts, collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff],
|
833
1007
|
no: OPT_GIT[:no][:log][:diff]).first
|
834
1008
|
case flag
|
835
1009
|
when :files, :view, :between, :contain
|
836
1010
|
cmd.delete('--cached')
|
837
|
-
else
|
838
|
-
items = files.dup
|
839
|
-
sha = nil
|
840
|
-
files.clear
|
841
|
-
items.each do |val|
|
842
|
-
if (s = commithash(val))
|
843
|
-
(sha ||= []).push(s)
|
844
|
-
else
|
845
|
-
files << val
|
846
|
-
end
|
847
|
-
end
|
848
1011
|
end
|
849
1012
|
append_nocolor
|
850
1013
|
if flag == :files
|
@@ -859,15 +1022,14 @@ module Squared
|
|
859
1022
|
cmd.delete('--merge-base')
|
860
1023
|
cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
|
861
1024
|
else
|
862
|
-
cmd << '--cached' if flag == :cached
|
863
1025
|
cmd << '--merge-base' if option('merge-base')
|
864
1026
|
cmd << shell_quote(branch) if branch
|
865
|
-
if
|
1027
|
+
if !index.empty?
|
866
1028
|
if session_arg?('cached')
|
867
|
-
raise_error(
|
868
|
-
cmd <<
|
1029
|
+
raise_error("one commit only: #{index.join(', ')}", hint: '--cached') if index.size > 1
|
1030
|
+
cmd << index.first
|
869
1031
|
else
|
870
|
-
cmd.merge(
|
1032
|
+
cmd.merge(index)
|
871
1033
|
end
|
872
1034
|
elsif (n = option('index'))
|
873
1035
|
cmd << "HEAD~#{n}"
|
@@ -884,12 +1046,12 @@ module Squared
|
|
884
1046
|
if !message && !amend
|
885
1047
|
return if pass
|
886
1048
|
|
887
|
-
raise_error('
|
1049
|
+
raise_error('missing message', hint: 'GIT_MESSAGE="description"')
|
888
1050
|
end
|
889
1051
|
pathspec = if flag == :all || (amend && refs.size == 1 && refs.first == '*')
|
890
1052
|
'--all'
|
891
1053
|
elsif (refs = projectmap(refs)).empty?
|
892
|
-
raise_error
|
1054
|
+
raise_error 'no qualified pathspec'
|
893
1055
|
else
|
894
1056
|
"-- #{refs.join(' ')}"
|
895
1057
|
end
|
@@ -898,13 +1060,15 @@ module Squared
|
|
898
1060
|
upstream = nil
|
899
1061
|
source(git_output('fetch --no-tags --quiet'), io: true, banner: false)
|
900
1062
|
source(git_output('branch -vv --list'), io: true, banner: false).first.each do |val|
|
901
|
-
next unless (
|
1063
|
+
next unless (r = /^\*\s(\S+)\s+(\h+)(?:\s\[(.+?)(?=\]\s)\])?\s/.match(val))
|
902
1064
|
|
903
|
-
branch =
|
904
|
-
if
|
1065
|
+
branch = r[1]
|
1066
|
+
if r[3]
|
1067
|
+
origin = r[3][%r{^(.+)/#{Regexp.escape(branch)}$}, 1]
|
1068
|
+
else
|
905
1069
|
unless (origin = option('repository', prefix: 'git', ignore: false))
|
906
|
-
out = source(git_output('log -n1 --format=%h%d'), io: true,
|
907
|
-
if out =~ /^#{
|
1070
|
+
out = source(git_output('log -n1 --format=%h%d'), io: true, banner: false, stdout: true).first
|
1071
|
+
if out =~ /^#{r[2]} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/
|
908
1072
|
split_escape($1).each do |val|
|
909
1073
|
next unless val.end_with?("/#{branch}")
|
910
1074
|
|
@@ -914,12 +1078,10 @@ module Squared
|
|
914
1078
|
end
|
915
1079
|
end
|
916
1080
|
upstream = true if origin
|
917
|
-
elsif data[3] =~ %r{^(.+)/#{Regexp.escape(branch)}$}
|
918
|
-
origin = $1
|
919
1081
|
end
|
920
1082
|
break
|
921
1083
|
end
|
922
|
-
raise_error
|
1084
|
+
raise_error 'work tree is not usable' unless origin && branch
|
923
1085
|
cmd = git_session('commit', option('dry-run') && '--dry-run', options: false)
|
924
1086
|
if amend
|
925
1087
|
cmd << '--amend'
|
@@ -946,8 +1108,24 @@ module Squared
|
|
946
1108
|
source b
|
947
1109
|
end
|
948
1110
|
|
949
|
-
def
|
950
|
-
cmd = git_session
|
1111
|
+
def merge(flag, opts = [], command: nil)
|
1112
|
+
cmd, opts = git_session('merge', opts: opts)
|
1113
|
+
case flag
|
1114
|
+
when :commit, :'no-commit'
|
1115
|
+
refs = option_sanitize(opts, OPT_GIT[:merge], no: OPT_GIT[:no][:merge]).first
|
1116
|
+
raise_error 'no branch/commit' if refs.empty?
|
1117
|
+
cmd << "--#{flag}" << '--'
|
1118
|
+
append_commit(*refs)
|
1119
|
+
else
|
1120
|
+
return unless VAL_GIT[:merge][:send].include?(command)
|
1121
|
+
|
1122
|
+
cmd << "--#{command}"
|
1123
|
+
end
|
1124
|
+
source
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
def branch(flag = nil, opts = [], refs: [], ref: nil, target: nil)
|
1128
|
+
cmd, opts = git_session('branch', opts: opts)
|
951
1129
|
stdout = false
|
952
1130
|
case flag
|
953
1131
|
when :create
|
@@ -974,7 +1152,7 @@ module Squared
|
|
974
1152
|
end
|
975
1153
|
ref = nil
|
976
1154
|
when :delete
|
977
|
-
force, list = refs.partition { |val| val
|
1155
|
+
force, list = refs.partition { |val| val.match?(/^[\^~]/) }
|
978
1156
|
force.each do |val|
|
979
1157
|
dr = val[0, 3]
|
980
1158
|
d = dr.include?('^') ? '-D' : '-d'
|
@@ -994,10 +1172,9 @@ module Squared
|
|
994
1172
|
cmd << '--edit-description'
|
995
1173
|
when :current
|
996
1174
|
cmd << '--show-current'
|
997
|
-
|
998
|
-
opts = option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch]).first
|
1175
|
+
when :list
|
999
1176
|
grep = []
|
1000
|
-
opts.each do |opt|
|
1177
|
+
option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch]).first.each do |opt|
|
1001
1178
|
if opt =~ /^(v+)$/
|
1002
1179
|
cmd << "-#{$1}"
|
1003
1180
|
else
|
@@ -1009,42 +1186,46 @@ module Squared
|
|
1009
1186
|
out, banner, from = source(io: true)
|
1010
1187
|
print_item banner
|
1011
1188
|
ret = write_lines(out, sub: [
|
1012
|
-
{ pat: /^(\*\s+)(\S+)(\s*)$/, styles: :green, index: 2 },
|
1013
|
-
{ pat: %r{^(\s*)(remotes/\S+)(.*)$}, styles: :red, index: 2 }
|
1189
|
+
{ pat: /^(\*\s+)(\S+)(\s*)$/, styles: color(:green), index: 2 },
|
1190
|
+
{ pat: %r{^(\s*)(remotes/\S+)(.*)$}, styles: color(:red), index: 2 }
|
1014
1191
|
])
|
1015
1192
|
list_result(ret, 'branches', from: from)
|
1016
1193
|
return
|
1194
|
+
else
|
1195
|
+
head = source(git_output('rev-parse --abbrev-ref HEAD'), io: true, banner: false, stdout: true).first.chomp
|
1196
|
+
if head.empty?
|
1197
|
+
ret = 0
|
1198
|
+
else
|
1199
|
+
out, banner, from = source(cmd << '-vv --no-abbrev --list', io: true)
|
1200
|
+
ret = write_lines(out, grep: /^\*\s+#{Regexp.escape(head)}\s/, banner: banner, first: true) do |line|
|
1201
|
+
next line if stdin?
|
1202
|
+
|
1203
|
+
data = line.sub(/^\*\s+/, '').split(/\s+/)
|
1204
|
+
a = sub_style(data[0], styles: theme[:inline])
|
1205
|
+
b = sub_style(data[1], styles: theme[:extra])
|
1206
|
+
r = /\A(?:\[(.+?)(?=\]\s)\]\s)?(.+)\z/m.match(data[2..-1].join(' '))
|
1207
|
+
[" Branch: #{a + (r[1] ? " (#{r[1]})" : '')}", " Commit: #{b}", "Message: #{r[2]}"].compact.join("\n")
|
1208
|
+
end
|
1209
|
+
on :last, from
|
1210
|
+
end
|
1211
|
+
if ret == 0
|
1212
|
+
warn log_message(Logger::WARN, name, 'no ref found', subject: 'branch', hint: 'head', pass: true)
|
1213
|
+
end
|
1214
|
+
return
|
1017
1215
|
end
|
1018
1216
|
cmd << shell_escape(target) if target
|
1019
1217
|
cmd << shell_escape(ref) if ref
|
1020
1218
|
source(stdout: stdout)
|
1021
1219
|
end
|
1022
1220
|
|
1023
|
-
def restore(flag, opts = [], tree: nil)
|
1024
|
-
cmd = git_session 'restore'
|
1025
|
-
refs = option_sanitize(opts, OPT_GIT[:restore], no: OPT_GIT[:no][:restore]).first
|
1026
|
-
if flag == :source
|
1027
|
-
cmd << '--patch' if refs.empty?
|
1028
|
-
cmd << shell_option('source', tree)
|
1029
|
-
else
|
1030
|
-
cmd << "--#{flag}"
|
1031
|
-
end
|
1032
|
-
if session_arg?('p', 'patch')
|
1033
|
-
option_clear refs
|
1034
|
-
else
|
1035
|
-
append_pathspec(refs, expect: true)
|
1036
|
-
end
|
1037
|
-
source(sync: false, stderr: true)
|
1038
|
-
end
|
1039
|
-
|
1040
1221
|
def show(format, opts = [])
|
1041
|
-
cmd = git_session
|
1222
|
+
cmd, opts = git_session('show', opts: opts)
|
1042
1223
|
if format
|
1043
1224
|
case (val = format.downcase)
|
1044
1225
|
when 'oneline', 'short', 'medium', 'full', 'fuller', 'reference', 'email', 'raw'
|
1045
1226
|
cmd << basic_option('format', val)
|
1046
1227
|
else
|
1047
|
-
if format
|
1228
|
+
if format.match?(/^t?format:/) || format.include?('%')
|
1048
1229
|
cmd << quote_option('pretty', format)
|
1049
1230
|
else
|
1050
1231
|
opts << format
|
@@ -1062,18 +1243,19 @@ module Squared
|
|
1062
1243
|
end
|
1063
1244
|
|
1064
1245
|
def rev_parse(flag, opts = [], ref: nil, size: nil)
|
1065
|
-
cmd = git_session
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1246
|
+
cmd, opts = git_session('rev-parse', opts: opts)
|
1247
|
+
cmd << if flag == :parseopt
|
1248
|
+
'--parseopt'
|
1249
|
+
elsif opts.delete('sq-quote')
|
1250
|
+
'--sq-quote'
|
1251
|
+
end
|
1070
1252
|
case flag
|
1071
1253
|
when :commit
|
1072
1254
|
cmd << ((n = size.to_i) > 0 ? basic_option('short', [n, 5].max) : '--verify')
|
1073
|
-
append_commit
|
1255
|
+
append_commit(ref, head: true)
|
1074
1256
|
when :branch
|
1075
1257
|
cmd << '--abbrev-ref'
|
1076
|
-
append_commit
|
1258
|
+
append_commit(ref, head: true)
|
1077
1259
|
else
|
1078
1260
|
args = option_sanitize(opts, OPT_GIT[:rev_parse][flag]).first
|
1079
1261
|
append_value(args, escape: session_arg?('sq-quote'))
|
@@ -1082,7 +1264,7 @@ module Squared
|
|
1082
1264
|
end
|
1083
1265
|
|
1084
1266
|
def ls_remote(flag, opts = [], remote: nil)
|
1085
|
-
cmd = git_session
|
1267
|
+
cmd, opts = git_session('ls-remote', '--refs', opts: opts)
|
1086
1268
|
cmd << "--#{flag}" unless flag == :remote
|
1087
1269
|
grep = option_sanitize(opts, OPT_GIT[:ls_remote]).first
|
1088
1270
|
cmd << shell_quote(remote) if remote
|
@@ -1093,7 +1275,7 @@ module Squared
|
|
1093
1275
|
end
|
1094
1276
|
|
1095
1277
|
def ls_files(flag, opts = [])
|
1096
|
-
git_session
|
1278
|
+
opts = git_session('ls-files', "--#{flag}", opts: opts).last
|
1097
1279
|
grep = option_sanitize(opts, OPT_GIT[:ls_files]).first
|
1098
1280
|
out, banner, from = source(io: true)
|
1099
1281
|
print_item banner
|
@@ -1101,10 +1283,51 @@ module Squared
|
|
1101
1283
|
list_result(ret, 'files', from: from, grep: grep)
|
1102
1284
|
end
|
1103
1285
|
|
1286
|
+
def git(flag, opts = [])
|
1287
|
+
cmd, opts = git_session(flag, opts: opts)
|
1288
|
+
refs = option_sanitize(opts, OPT_GIT[flag], no: OPT_GIT[:no][flag]).first
|
1289
|
+
refs = projectmap(refs) unless flag == :revert
|
1290
|
+
sync = false
|
1291
|
+
stderr = true
|
1292
|
+
case flag
|
1293
|
+
when :clean
|
1294
|
+
unless refs.empty?
|
1295
|
+
cmd << '--'
|
1296
|
+
cmd.merge(refs)
|
1297
|
+
end
|
1298
|
+
sync = true
|
1299
|
+
stderr = false
|
1300
|
+
when :restore
|
1301
|
+
if session_arg?('p', 'patch')
|
1302
|
+
option_clear refs
|
1303
|
+
else
|
1304
|
+
append_pathspec(refs, expect: true)
|
1305
|
+
end
|
1306
|
+
when :revert
|
1307
|
+
if VAL_GIT[:rebase][:send].any? { |val| session_arg?(val) }
|
1308
|
+
option_clear refs
|
1309
|
+
elsif refs.empty?
|
1310
|
+
raise_error 'no commit given'
|
1311
|
+
else
|
1312
|
+
append_commit(*refs)
|
1313
|
+
end
|
1314
|
+
when :mv
|
1315
|
+
raise_error 'no source/destination' unless refs.size > 1
|
1316
|
+
cmd.merge(refs)
|
1317
|
+
when :rm
|
1318
|
+
append_pathspec(refs, expect: true)
|
1319
|
+
end
|
1320
|
+
source(sync: sync, stderr: stderr)
|
1321
|
+
end
|
1322
|
+
|
1104
1323
|
def clone?
|
1105
1324
|
ref?(workspace.baseref) && workspace.git_clone?(path, name) ? 1 : false
|
1106
1325
|
end
|
1107
1326
|
|
1327
|
+
def revbuild?
|
1328
|
+
build? && !!workspace.revfile
|
1329
|
+
end
|
1330
|
+
|
1108
1331
|
def enabled?(*, **kwargs)
|
1109
1332
|
super || (kwargs[:base] == false && !!clone?)
|
1110
1333
|
end
|
@@ -1117,7 +1340,7 @@ module Squared
|
|
1117
1340
|
if cmd.respond_to?(:done)
|
1118
1341
|
if io && banner == false
|
1119
1342
|
from = nil
|
1120
|
-
elsif !from && (from = cmd.drop(1).find { |val| val
|
1343
|
+
elsif !from && (from = cmd.drop(1).find { |val| val.match?(/^[a-z][a-z\-]{2,}$/) })
|
1121
1344
|
from = :"git:#{from}"
|
1122
1345
|
end
|
1123
1346
|
banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
|
@@ -1163,13 +1386,13 @@ module Squared
|
|
1163
1386
|
ret = on(:error, from, e)
|
1164
1387
|
raise if exception && ret != true
|
1165
1388
|
|
1166
|
-
warn log_message(Logger::WARN, e) if warning?
|
1389
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
1167
1390
|
else
|
1168
1391
|
on :last, from
|
1169
1392
|
end
|
1170
1393
|
end
|
1171
1394
|
|
1172
|
-
def write_lines(data, banner: nil, loglevel: nil, grep: nil, sub: nil, pass: false)
|
1395
|
+
def write_lines(data, banner: nil, loglevel: nil, grep: nil, sub: nil, pass: false, first: false)
|
1173
1396
|
grep = as_a(grep).map do |val|
|
1174
1397
|
next val if val.is_a?(Regexp)
|
1175
1398
|
|
@@ -1182,6 +1405,7 @@ module Squared
|
|
1182
1405
|
data.each do |line|
|
1183
1406
|
next if grep&.none? { |pat| pat.match?(line) }
|
1184
1407
|
|
1408
|
+
line = yield line if block_given?
|
1185
1409
|
if loglevel
|
1186
1410
|
log&.add loglevel, line
|
1187
1411
|
else
|
@@ -1193,8 +1417,9 @@ module Squared
|
|
1193
1417
|
end
|
1194
1418
|
end
|
1195
1419
|
ret += 1
|
1420
|
+
break if first
|
1196
1421
|
end
|
1197
|
-
print_item banner, out if banner && (ret > 0 || !pass)
|
1422
|
+
print_item banner, out if banner && (ret > 0 || (!pass && !first))
|
1198
1423
|
ret
|
1199
1424
|
end
|
1200
1425
|
|
@@ -1217,6 +1442,21 @@ module Squared
|
|
1217
1442
|
on :last, from
|
1218
1443
|
end
|
1219
1444
|
|
1445
|
+
def status_digest(*args, algorithm: Digest::SHA256, **kwargs)
|
1446
|
+
glob = kwargs.fetch(:include, [])
|
1447
|
+
pass = kwargs.fetch(:exclude, [])
|
1448
|
+
ret = {}
|
1449
|
+
out = source(git_output('status -s --porcelain', *args), io: true, banner: false).first
|
1450
|
+
out.each do |line|
|
1451
|
+
next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
|
1452
|
+
next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1453
|
+
next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1454
|
+
|
1455
|
+
ret[file] = algorithm.hexdigest(File.read(basepath(file)))
|
1456
|
+
end
|
1457
|
+
ret
|
1458
|
+
end
|
1459
|
+
|
1220
1460
|
def append_pull(opts, list, target: @session, no: nil, flag: nil, remote: nil)
|
1221
1461
|
cmd << '--force' if option('force')
|
1222
1462
|
rsm = append_submodules(target: target)
|
@@ -1256,9 +1496,13 @@ module Squared
|
|
1256
1496
|
option_clear(out, target: target, subject: flag.to_s) if flag
|
1257
1497
|
end
|
1258
1498
|
|
1259
|
-
def append_commit(val, target: @session)
|
1260
|
-
val
|
1261
|
-
|
1499
|
+
def append_commit(*val, target: @session, head: false)
|
1500
|
+
val.compact!
|
1501
|
+
if !val.empty?
|
1502
|
+
val.each { |ref| target << (commithash(ref) || shell_quote(ref)) }
|
1503
|
+
elsif head
|
1504
|
+
target << (append_head(target: target) || 'HEAD')
|
1505
|
+
end
|
1262
1506
|
end
|
1263
1507
|
|
1264
1508
|
def append_pathspec(files = [], target: @session, expect: false, parent: false)
|
@@ -1270,9 +1514,9 @@ module Squared
|
|
1270
1514
|
end
|
1271
1515
|
files = projectmap(files, parent: parent)
|
1272
1516
|
if !files.empty?
|
1273
|
-
target <<
|
1517
|
+
target << '--' << files.join(' ')
|
1274
1518
|
elsif expect
|
1275
|
-
raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree'
|
1519
|
+
raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree')
|
1276
1520
|
end
|
1277
1521
|
end
|
1278
1522
|
end
|
@@ -1307,9 +1551,13 @@ module Squared
|
|
1307
1551
|
end
|
1308
1552
|
end
|
1309
1553
|
|
1310
|
-
def git_session(*cmd, worktree: true, **kwargs)
|
1554
|
+
def git_session(*cmd, opts: nil, worktree: true, **kwargs)
|
1311
1555
|
dir = worktree ? ["--work-tree=#{shell_quote(path)}", "--git-dir=#{shell_quote(gitpath)}"] : []
|
1312
|
-
session('git', *dir,
|
1556
|
+
ret = session('git', *dir, **kwargs)
|
1557
|
+
return ret.merge(cmd) unless opts
|
1558
|
+
|
1559
|
+
opts = option_sanitize(opts, OPT_GIT[:common]).first
|
1560
|
+
[ret.merge(cmd), opts]
|
1313
1561
|
end
|
1314
1562
|
|
1315
1563
|
def git_output(*cmd, **kwargs)
|
@@ -1327,11 +1575,11 @@ module Squared
|
|
1327
1575
|
end
|
1328
1576
|
|
1329
1577
|
def gitpath
|
1330
|
-
basepath
|
1578
|
+
basepath '.git'
|
1331
1579
|
end
|
1332
1580
|
|
1333
1581
|
def commithash(val)
|
1334
|
-
val
|
1582
|
+
val[/^#\{(\h{5,40})\}$/, 1]
|
1335
1583
|
end
|
1336
1584
|
|
1337
1585
|
def threadargs
|