avm-tools 0.102.1 → 0.102.2
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/lib/avm/git/issue/complete.rb +3 -7
- data/lib/avm/git/issue/complete/commits.rb +42 -0
- data/lib/avm/git/issue/complete/git_subrepos.rb +23 -0
- data/lib/avm/git/issue/complete/local_branch.rb +54 -0
- data/lib/avm/git/issue/complete/local_tag.rb +39 -0
- data/lib/avm/git/issue/complete/push.rb +54 -0
- data/lib/avm/git/issue/complete/remote.rb +33 -0
- data/lib/avm/git/issue/complete/test.rb +45 -0
- data/lib/avm/git/issue/complete/tracker.rb +28 -0
- data/lib/avm/git/issue/complete/validations.rb +53 -0
- data/lib/avm/git/issue/complete/working_tree.rb +19 -0
- data/lib/avm/tools/runner/git/issue.rb +4 -75
- data/lib/avm/tools/runner/git/issue/complete.rb +79 -0
- data/lib/avm/tools/runner/git/issue/deliver.rb +35 -0
- data/lib/avm/tools/version.rb +1 -1
- metadata +14 -12
- data/lib/avm/git/issue/complete/_commits.rb +0 -40
- data/lib/avm/git/issue/complete/_git_subrepos.rb +0 -21
- data/lib/avm/git/issue/complete/_local_branch.rb +0 -52
- data/lib/avm/git/issue/complete/_local_tag.rb +0 -37
- data/lib/avm/git/issue/complete/_push.rb +0 -52
- data/lib/avm/git/issue/complete/_remote.rb +0 -31
- data/lib/avm/git/issue/complete/_test.rb +0 -43
- data/lib/avm/git/issue/complete/_tracker.rb +0 -26
- data/lib/avm/git/issue/complete/_validations.rb +0 -51
- data/lib/avm/git/issue/complete/_working_tree.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1dc265a8c8828a917414ea4baac9765139517521d1d137df7893cf71c1c3b89
|
4
|
+
data.tar.gz: 46ec3d56d9ad2420929c24aba726b1a2e476bae418e90a793b106f95740ce5e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2bde9ec40565deaf93c371d8c1df4443ff2ba084d4ab295493a585c4ed82d1f070625747a0ab7ac5fbed0424d1c4d7f2345beae7a03a6ef0efef13a4363e95a
|
7
|
+
data.tar.gz: ebf68de65906d8c17c31f4d49cbc3011afc0e793e25b70f01a25291d0c897526f4ef54beef345ffb9f7e08a49ba0b98e44b825e5feab19803c747d09917eae4c
|
@@ -1,17 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'avm/
|
4
|
-
require 'eac_cli/speaker'
|
5
|
-
require 'eac_ruby_utils/options_consumer'
|
6
|
-
require 'eac_ruby_utils/require_sub'
|
7
|
-
require 'eac_ruby_utils/simple_cache'
|
8
|
-
::EacRubyUtils.require_sub(__FILE__)
|
3
|
+
require 'avm/core_ext'
|
9
4
|
|
10
5
|
module Avm
|
11
6
|
module Git
|
12
7
|
module Issue
|
13
8
|
class Complete
|
14
|
-
|
9
|
+
require_sub __FILE__, include_modules: true
|
10
|
+
enable_simple_cache
|
15
11
|
enable_speaker
|
16
12
|
|
17
13
|
attr_reader :skip_validations
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/result'
|
4
|
+
|
5
|
+
module Avm
|
6
|
+
module Git
|
7
|
+
module Issue
|
8
|
+
class Complete
|
9
|
+
module Commits
|
10
|
+
def commits_result
|
11
|
+
::Avm::Result.success_or_error(commits.any?, 'yes', 'none')
|
12
|
+
end
|
13
|
+
|
14
|
+
def commits_uncached
|
15
|
+
return [] unless branch_hash && follow_master?
|
16
|
+
|
17
|
+
interval = remote_master_hash ? "#{remote_master_hash}..#{branch_hash}" : branch_hash
|
18
|
+
@git.execute!('rev-list', interval).each_line.map(&:strip)
|
19
|
+
end
|
20
|
+
|
21
|
+
def bifurcations_result
|
22
|
+
commits.each do |commit|
|
23
|
+
if multiple_parents?(commit)
|
24
|
+
return ::Avm::Result.error("#{commit} has multiple parents")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
::Avm::Result.success('no')
|
28
|
+
end
|
29
|
+
|
30
|
+
def multiple_parents?(commit)
|
31
|
+
commit_parents(commit).count > 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def commit_parents(commit)
|
35
|
+
@git.execute!('log', '--pretty=%P', '-n', '1', commit).split(' ').map(&:strip)
|
36
|
+
.select(&:present?)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/git/subrepo_checks'
|
4
|
+
require 'eac_git/local'
|
5
|
+
|
6
|
+
module Avm
|
7
|
+
module Git
|
8
|
+
module Issue
|
9
|
+
class Complete
|
10
|
+
module GitSubrepos
|
11
|
+
def git_subrepos_result
|
12
|
+
return ::Avm::Result.error('Unclean workspace') unless clean_workspace?
|
13
|
+
|
14
|
+
infom 'Checking Git subrepos...'
|
15
|
+
r = ::Avm::Git::SubrepoChecks.new(::EacGit::Local.new(@git)).add_all_subrepos
|
16
|
+
r.check_remote = true
|
17
|
+
r.result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/result'
|
4
|
+
|
5
|
+
module Avm
|
6
|
+
module Git
|
7
|
+
module Issue
|
8
|
+
class Complete
|
9
|
+
module LocalBranch
|
10
|
+
def branch_uncached
|
11
|
+
@git.current_branch
|
12
|
+
end
|
13
|
+
|
14
|
+
def branch_hash_uncached
|
15
|
+
@git.rev_parse("refs/heads/#{branch}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def branch_name
|
19
|
+
branch.split('/')[-1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def branch_name_result
|
23
|
+
::Avm::Result.success_or_error(issue_id.present?, branch_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def branch_hash_result
|
27
|
+
::Avm::Result.success_or_error(
|
28
|
+
branch_hash.present?,
|
29
|
+
branch_hash
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def follow_master_result
|
34
|
+
return ::Avm::Result.neutral('No branch hash') unless branch_hash
|
35
|
+
|
36
|
+
r = follow_master?
|
37
|
+
::Avm::Result.success_or_error(r, 'yes', 'no')
|
38
|
+
end
|
39
|
+
|
40
|
+
def follow_master?
|
41
|
+
remote_master_hash ? @git.descendant?(branch_hash, remote_master_hash) : true
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_local_branch
|
45
|
+
info 'Removendo branch local...'
|
46
|
+
bn = branch_name
|
47
|
+
git(['checkout', branch_hash])
|
48
|
+
git(['branch', '-D', bn])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/result'
|
4
|
+
|
5
|
+
module Avm
|
6
|
+
module Git
|
7
|
+
module Issue
|
8
|
+
class Complete
|
9
|
+
module LocalTag
|
10
|
+
def assert_tag
|
11
|
+
if tag_hash
|
12
|
+
return if tag_hash == branch_hash
|
13
|
+
|
14
|
+
delete_tag
|
15
|
+
end
|
16
|
+
create_tag
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete_tag
|
20
|
+
info 'Removendo tag...'
|
21
|
+
git(['tag', '-d', branch_name])
|
22
|
+
end
|
23
|
+
|
24
|
+
def tag
|
25
|
+
"refs/tags/#{branch_name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def tag_hash
|
29
|
+
@git.rev_parse(tag)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_tag
|
33
|
+
git(['tag', branch_name, branch_hash])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avm
|
4
|
+
module Git
|
5
|
+
module Issue
|
6
|
+
class Complete
|
7
|
+
module Push
|
8
|
+
def dry_push_args
|
9
|
+
%w[push --dry-run] + [remote_name] + pushs
|
10
|
+
end
|
11
|
+
|
12
|
+
def dry_push_result
|
13
|
+
return ::Avm::Result.error('Nothing to push') if pushs.empty?
|
14
|
+
|
15
|
+
r = @git.execute(dry_push_args)
|
16
|
+
message = if r.fetch(:exit_code).zero?
|
17
|
+
'ok'
|
18
|
+
else
|
19
|
+
r.fetch(:stderr) + "\n#{::Shellwords.join(dry_push_args)}"
|
20
|
+
end
|
21
|
+
::Avm::Result.success_or_error(r.fetch(:exit_code).zero?, message)
|
22
|
+
end
|
23
|
+
|
24
|
+
def push
|
25
|
+
if pushs.empty?
|
26
|
+
info 'PUSH: Nada a enviar'
|
27
|
+
else
|
28
|
+
info "PUSH: enviando \"#{pushs}\"..."
|
29
|
+
git(%w[push origin] + pushs)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def pushs_uncached
|
34
|
+
[master_push, remove_branch_push, tag_push].reject(&:nil?)
|
35
|
+
end
|
36
|
+
|
37
|
+
def master_push
|
38
|
+
remote_master_hash != branch_hash ? "#{branch_hash}:refs/heads/master" : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_branch_push
|
42
|
+
remote_branch_hash ? ":refs/heads/#{branch}" : nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def tag_push
|
46
|
+
return nil unless !remote_tag_hash || remote_tag_hash != branch_hash
|
47
|
+
|
48
|
+
"#{branch_hash}:#{tag}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avm
|
4
|
+
module Git
|
5
|
+
module Issue
|
6
|
+
class Complete
|
7
|
+
module Remote
|
8
|
+
def remote_master_hash
|
9
|
+
remote_hashs['refs/heads/master']
|
10
|
+
end
|
11
|
+
|
12
|
+
def remote_branch_hash
|
13
|
+
remote_hashs["refs/heads/#{branch}"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def remote_tag_hash
|
17
|
+
remote_hashs[tag]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def remote_name
|
23
|
+
'origin'
|
24
|
+
end
|
25
|
+
|
26
|
+
def remote_hashs_uncached
|
27
|
+
@git.remote_hashs(remote_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/apps/sources/configuration'
|
4
|
+
require 'avm/result'
|
5
|
+
require 'eac_ruby_utils/fs/temp'
|
6
|
+
|
7
|
+
module Avm
|
8
|
+
module Git
|
9
|
+
module Issue
|
10
|
+
class Complete
|
11
|
+
module Test
|
12
|
+
def test_result
|
13
|
+
test_command = configuration.if_present(&:any_test_command)
|
14
|
+
return ::Avm::Result.success('unconfigured') if test_command.blank?
|
15
|
+
|
16
|
+
infom "Running test command \"#{test_command}\"..."
|
17
|
+
result = test_command.execute
|
18
|
+
test_result_log(result)
|
19
|
+
if result.fetch(:exit_code).zero?
|
20
|
+
::Avm::Result.success('yes')
|
21
|
+
else
|
22
|
+
::Avm::Result.error('no')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def test_result_log(result)
|
29
|
+
stdout_file = ::EacRubyUtils::Fs::Temp.file
|
30
|
+
stderr_file = ::EacRubyUtils::Fs::Temp.file
|
31
|
+
stdout_file.write(result.fetch(:stdout))
|
32
|
+
stderr_file.write(result.fetch(:stderr))
|
33
|
+
infov ' * Exit code', result.fetch(:exit_code)
|
34
|
+
infov ' * STDOUT', stdout_file.to_path
|
35
|
+
infov ' * STDERR', stderr_file.to_path
|
36
|
+
end
|
37
|
+
|
38
|
+
def configuration_uncached
|
39
|
+
::Avm::Apps::Sources::Configuration.find_by_path(@git)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'clipboard'
|
4
|
+
|
5
|
+
module Avm
|
6
|
+
module Git
|
7
|
+
module Issue
|
8
|
+
class Complete
|
9
|
+
module Tracker
|
10
|
+
def clipboard_copy_tracker_message
|
11
|
+
::Clipboard.copy(textile_tracker_message)
|
12
|
+
infov 'Copied to clipboard', textile_tracker_message
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def textile_tracker_message_uncached
|
18
|
+
"Revisado para commit:#{branch_short_hash}, ok."
|
19
|
+
end
|
20
|
+
|
21
|
+
def branch_short_hash
|
22
|
+
git(['log', '--pretty=format:%h', '-1', '-q', branch_hash])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/git/issue/complete/validation'
|
4
|
+
require 'avm/result'
|
5
|
+
require 'ostruct'
|
6
|
+
|
7
|
+
module Avm
|
8
|
+
module Git
|
9
|
+
module Issue
|
10
|
+
class Complete
|
11
|
+
module Validations
|
12
|
+
VALIDATIONS = {
|
13
|
+
clean_workspace: 'Clean workspace?',
|
14
|
+
branch_name: 'Branch name',
|
15
|
+
branch_hash: 'Branch hash',
|
16
|
+
follow_master: 'Follow master?',
|
17
|
+
commits: 'Commits?',
|
18
|
+
bifurcations: 'Bifurcations?',
|
19
|
+
dry_push: 'Dry push?',
|
20
|
+
git_subrepos: 'Git subrepos ok?',
|
21
|
+
test: 'Test ok?'
|
22
|
+
}.with_indifferent_access.freeze
|
23
|
+
|
24
|
+
def valid?
|
25
|
+
validations.map(&:result).none?(&:error?)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validations_banner
|
29
|
+
validations.each do |v|
|
30
|
+
infov "[#{v.key}] #{v.label}", v.result.label
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_skip_validations
|
35
|
+
skip_validations.each do |validation|
|
36
|
+
next if VALIDATIONS.keys.include?(validation)
|
37
|
+
|
38
|
+
raise "\"#{validation}\" is not a registered validation"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def validations_uncached
|
45
|
+
VALIDATIONS.map do |key, label|
|
46
|
+
::Avm::Git::Issue::Complete::Validation.new(self, key, label)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avm
|
4
|
+
module Git
|
5
|
+
module Issue
|
6
|
+
class Complete
|
7
|
+
module WorkingTree
|
8
|
+
def clean_workspace_result
|
9
|
+
::Avm::Result.success_or_error(clean_workspace?, 'yes', 'no')
|
10
|
+
end
|
11
|
+
|
12
|
+
def clean_workspace?
|
13
|
+
@git.dirty_files.none?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -8,81 +8,10 @@ module Avm
|
|
8
8
|
class Runner
|
9
9
|
class Git
|
10
10
|
class Issue
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
arg_opt '-s', '--skip-validations', 'Does not validate conditions on <validations>' \
|
16
|
-
' (Comma separated value).'
|
17
|
-
bool_opt '--complete', 'Run complete task.'
|
18
|
-
bool_opt '--deliver', 'Run "deliver" task.'
|
19
|
-
bool_opt '--validate', 'Validate for "complete" task.'
|
20
|
-
end
|
21
|
-
|
22
|
-
def run
|
23
|
-
run_validate if parsed.validate?
|
24
|
-
run_deliver if parsed.deliver?
|
25
|
-
run_complete if parsed.complete?
|
26
|
-
success('Done!')
|
27
|
-
end
|
28
|
-
|
29
|
-
def help_extra_text
|
30
|
-
"Validations:\n#{doc_validations_list}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def run_validate
|
34
|
-
complete.start_banner
|
35
|
-
return true if complete.valid?
|
36
|
-
|
37
|
-
uncomplete_message('Some validation did not pass')
|
38
|
-
end
|
39
|
-
|
40
|
-
def run_complete
|
41
|
-
return complete.run if confirm?('Confirm issue completion?')
|
42
|
-
|
43
|
-
uncomplete_message('Issue was not completed')
|
44
|
-
end
|
45
|
-
|
46
|
-
def run_deliver
|
47
|
-
deliver.start_banner
|
48
|
-
return deliver.run if confirm?('Confirm issue delivery?')
|
49
|
-
|
50
|
-
uncomplete_message('Issue was not delivered')
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def complete_uncached
|
56
|
-
::Avm::Git::Issue::Complete.new(git_complete_issue_options)
|
57
|
-
end
|
58
|
-
|
59
|
-
def deliver_uncached
|
60
|
-
::Avm::Git::Issue::Deliver.new(runner_context.call(:git_repo))
|
61
|
-
end
|
62
|
-
|
63
|
-
def skip_validations
|
64
|
-
parsed.skip_validations.to_s.split(',').map(&:strip).reject(&:blank?)
|
65
|
-
end
|
66
|
-
|
67
|
-
def git_complete_issue_options
|
68
|
-
{ dir: runner_context.call(:repository_path), skip_validations: skip_validations }
|
69
|
-
end
|
70
|
-
|
71
|
-
def doc_validations_list
|
72
|
-
::Avm::Git::Issue::Complete::VALIDATIONS.keys.map { |k| " * #{k}" }.join("\n")
|
73
|
-
end
|
74
|
-
|
75
|
-
def uncomplete_unfail?
|
76
|
-
parsed.uncomplete_unfail?
|
77
|
-
end
|
78
|
-
|
79
|
-
def uncomplete_message(message)
|
80
|
-
if uncomplete_unfail?
|
81
|
-
warn(message)
|
82
|
-
else
|
83
|
-
fatal_error(message)
|
84
|
-
end
|
85
|
-
false
|
11
|
+
require_sub __FILE__
|
12
|
+
runner_with :help, :subcommands do
|
13
|
+
desc 'Issue operations within Git.'
|
14
|
+
subcommands
|
86
15
|
end
|
87
16
|
end
|
88
17
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/core_ext'
|
4
|
+
require 'avm/git/issue/complete'
|
5
|
+
|
6
|
+
module Avm
|
7
|
+
module Tools
|
8
|
+
class Runner
|
9
|
+
class Git
|
10
|
+
class Issue
|
11
|
+
class Complete
|
12
|
+
runner_with :confirmation, :help do
|
13
|
+
desc 'Closes a issue in a Git repository.'
|
14
|
+
bool_opt '-f', '--uncomplete-unfail', 'Do not exit with error if issue is not' \
|
15
|
+
' completed or is invalid.'
|
16
|
+
arg_opt '-s', '--skip-validations', 'Does not validate conditions on <validations>' \
|
17
|
+
' (Comma separated value).'
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
return unless run_validate
|
22
|
+
return unless run_complete
|
23
|
+
|
24
|
+
success('Done!')
|
25
|
+
end
|
26
|
+
|
27
|
+
def help_extra_text
|
28
|
+
"Validations:\n#{doc_validations_list}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_validate
|
32
|
+
complete.start_banner
|
33
|
+
return true if complete.valid?
|
34
|
+
|
35
|
+
uncomplete_message('Some validation did not pass')
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_complete
|
39
|
+
return complete.run if confirm?('Confirm issue completion?')
|
40
|
+
|
41
|
+
uncomplete_message('Issue was not completed')
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def complete_uncached
|
47
|
+
::Avm::Git::Issue::Complete.new(git_complete_issue_options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def skip_validations
|
51
|
+
parsed.skip_validations.to_s.split(',').map(&:strip).reject(&:blank?)
|
52
|
+
end
|
53
|
+
|
54
|
+
def git_complete_issue_options
|
55
|
+
{ dir: runner_context.call(:repository_path), skip_validations: skip_validations }
|
56
|
+
end
|
57
|
+
|
58
|
+
def doc_validations_list
|
59
|
+
::Avm::Git::Issue::Complete::VALIDATIONS.keys.map { |k| " * #{k}" }.join("\n")
|
60
|
+
end
|
61
|
+
|
62
|
+
def uncomplete_unfail?
|
63
|
+
parsed.uncomplete_unfail?
|
64
|
+
end
|
65
|
+
|
66
|
+
def uncomplete_message(message)
|
67
|
+
if uncomplete_unfail?
|
68
|
+
warn(message)
|
69
|
+
else
|
70
|
+
fatal_error(message)
|
71
|
+
end
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'avm/core_ext'
|
4
|
+
require 'avm/git/issue/deliver'
|
5
|
+
|
6
|
+
module Avm
|
7
|
+
module Tools
|
8
|
+
class Runner
|
9
|
+
class Git
|
10
|
+
class Issue
|
11
|
+
class Deliver
|
12
|
+
runner_with :confirmation, :help do
|
13
|
+
desc 'Deliver a issue in a Git repository.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
deliver.start_banner
|
18
|
+
if confirm?('Confirm issue delivery?')
|
19
|
+
deliver.run
|
20
|
+
else
|
21
|
+
fatal_error 'Issue undelivered'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def deliver_uncached
|
28
|
+
::Avm::Git::Issue::Deliver.new(runner_context.call(:git_repo))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/avm/tools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: avm-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.102.
|
4
|
+
version: 0.102.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Esquilo Azul Company
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aranha-parsers
|
@@ -450,17 +450,17 @@ files:
|
|
450
450
|
- lib/avm/git/file_auto_fixup.rb
|
451
451
|
- lib/avm/git/issue.rb
|
452
452
|
- lib/avm/git/issue/complete.rb
|
453
|
-
- lib/avm/git/issue/complete/
|
454
|
-
- lib/avm/git/issue/complete/
|
455
|
-
- lib/avm/git/issue/complete/
|
456
|
-
- lib/avm/git/issue/complete/
|
457
|
-
- lib/avm/git/issue/complete/
|
458
|
-
- lib/avm/git/issue/complete/
|
459
|
-
- lib/avm/git/issue/complete/
|
460
|
-
- lib/avm/git/issue/complete/
|
461
|
-
- lib/avm/git/issue/complete/_validations.rb
|
462
|
-
- lib/avm/git/issue/complete/_working_tree.rb
|
453
|
+
- lib/avm/git/issue/complete/commits.rb
|
454
|
+
- lib/avm/git/issue/complete/git_subrepos.rb
|
455
|
+
- lib/avm/git/issue/complete/local_branch.rb
|
456
|
+
- lib/avm/git/issue/complete/local_tag.rb
|
457
|
+
- lib/avm/git/issue/complete/push.rb
|
458
|
+
- lib/avm/git/issue/complete/remote.rb
|
459
|
+
- lib/avm/git/issue/complete/test.rb
|
460
|
+
- lib/avm/git/issue/complete/tracker.rb
|
463
461
|
- lib/avm/git/issue/complete/validation.rb
|
462
|
+
- lib/avm/git/issue/complete/validations.rb
|
463
|
+
- lib/avm/git/issue/complete/working_tree.rb
|
464
464
|
- lib/avm/git/issue/deliver.rb
|
465
465
|
- lib/avm/git/organize.rb
|
466
466
|
- lib/avm/git/organize/reference_update.rb
|
@@ -635,6 +635,8 @@ files:
|
|
635
635
|
- lib/avm/tools/runner/git/deploy.rb
|
636
636
|
- lib/avm/tools/runner/git/dirty_files.rb
|
637
637
|
- lib/avm/tools/runner/git/issue.rb
|
638
|
+
- lib/avm/tools/runner/git/issue/complete.rb
|
639
|
+
- lib/avm/tools/runner/git/issue/deliver.rb
|
638
640
|
- lib/avm/tools/runner/git/organize.rb
|
639
641
|
- lib/avm/tools/runner/git/revisions_test.rb
|
640
642
|
- lib/avm/tools/runner/git/subrepo.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/result'
|
4
|
-
|
5
|
-
module Avm
|
6
|
-
module Git
|
7
|
-
module Issue
|
8
|
-
class Complete
|
9
|
-
def commits_result
|
10
|
-
::Avm::Result.success_or_error(commits.any?, 'yes', 'none')
|
11
|
-
end
|
12
|
-
|
13
|
-
def commits_uncached
|
14
|
-
return [] unless branch_hash && follow_master?
|
15
|
-
|
16
|
-
interval = remote_master_hash ? "#{remote_master_hash}..#{branch_hash}" : branch_hash
|
17
|
-
@git.execute!('rev-list', interval).each_line.map(&:strip)
|
18
|
-
end
|
19
|
-
|
20
|
-
def bifurcations_result
|
21
|
-
commits.each do |commit|
|
22
|
-
if multiple_parents?(commit)
|
23
|
-
return ::Avm::Result.error("#{commit} has multiple parents")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
::Avm::Result.success('no')
|
27
|
-
end
|
28
|
-
|
29
|
-
def multiple_parents?(commit)
|
30
|
-
commit_parents(commit).count > 1
|
31
|
-
end
|
32
|
-
|
33
|
-
def commit_parents(commit)
|
34
|
-
@git.execute!('log', '--pretty=%P', '-n', '1', commit).split(' ').map(&:strip)
|
35
|
-
.select(&:present?)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/git/subrepo_checks'
|
4
|
-
require 'eac_git/local'
|
5
|
-
|
6
|
-
module Avm
|
7
|
-
module Git
|
8
|
-
module Issue
|
9
|
-
class Complete
|
10
|
-
def git_subrepos_result
|
11
|
-
return ::Avm::Result.error('Unclean workspace') unless clean_workspace?
|
12
|
-
|
13
|
-
infom 'Checking Git subrepos...'
|
14
|
-
r = ::Avm::Git::SubrepoChecks.new(::EacGit::Local.new(@git)).add_all_subrepos
|
15
|
-
r.check_remote = true
|
16
|
-
r.result
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/result'
|
4
|
-
|
5
|
-
module Avm
|
6
|
-
module Git
|
7
|
-
module Issue
|
8
|
-
class Complete
|
9
|
-
def branch_uncached
|
10
|
-
@git.current_branch
|
11
|
-
end
|
12
|
-
|
13
|
-
def branch_hash_uncached
|
14
|
-
@git.rev_parse("refs/heads/#{branch}")
|
15
|
-
end
|
16
|
-
|
17
|
-
def branch_name
|
18
|
-
branch.split('/')[-1]
|
19
|
-
end
|
20
|
-
|
21
|
-
def branch_name_result
|
22
|
-
::Avm::Result.success_or_error(issue_id.present?, branch_name)
|
23
|
-
end
|
24
|
-
|
25
|
-
def branch_hash_result
|
26
|
-
::Avm::Result.success_or_error(
|
27
|
-
branch_hash.present?,
|
28
|
-
branch_hash
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def follow_master_result
|
33
|
-
return ::Avm::Result.neutral('No branch hash') unless branch_hash
|
34
|
-
|
35
|
-
r = follow_master?
|
36
|
-
::Avm::Result.success_or_error(r, 'yes', 'no')
|
37
|
-
end
|
38
|
-
|
39
|
-
def follow_master?
|
40
|
-
remote_master_hash ? @git.descendant?(branch_hash, remote_master_hash) : true
|
41
|
-
end
|
42
|
-
|
43
|
-
def remove_local_branch
|
44
|
-
info 'Removendo branch local...'
|
45
|
-
bn = branch_name
|
46
|
-
git(['checkout', branch_hash])
|
47
|
-
git(['branch', '-D', bn])
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/result'
|
4
|
-
|
5
|
-
module Avm
|
6
|
-
module Git
|
7
|
-
module Issue
|
8
|
-
class Complete
|
9
|
-
def assert_tag
|
10
|
-
if tag_hash
|
11
|
-
return if tag_hash == branch_hash
|
12
|
-
|
13
|
-
delete_tag
|
14
|
-
end
|
15
|
-
create_tag
|
16
|
-
end
|
17
|
-
|
18
|
-
def delete_tag
|
19
|
-
info 'Removendo tag...'
|
20
|
-
git(['tag', '-d', branch_name])
|
21
|
-
end
|
22
|
-
|
23
|
-
def tag
|
24
|
-
"refs/tags/#{branch_name}"
|
25
|
-
end
|
26
|
-
|
27
|
-
def tag_hash
|
28
|
-
@git.rev_parse(tag)
|
29
|
-
end
|
30
|
-
|
31
|
-
def create_tag
|
32
|
-
git(['tag', branch_name, branch_hash])
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Avm
|
4
|
-
module Git
|
5
|
-
module Issue
|
6
|
-
class Complete
|
7
|
-
def dry_push_args
|
8
|
-
%w[push --dry-run] + [remote_name] + pushs
|
9
|
-
end
|
10
|
-
|
11
|
-
def dry_push_result
|
12
|
-
return ::Avm::Result.error('Nothing to push') if pushs.empty?
|
13
|
-
|
14
|
-
r = @git.execute(dry_push_args)
|
15
|
-
message = if r.fetch(:exit_code).zero?
|
16
|
-
'ok'
|
17
|
-
else
|
18
|
-
r.fetch(:stderr) + "\n#{::Shellwords.join(dry_push_args)}"
|
19
|
-
end
|
20
|
-
::Avm::Result.success_or_error(r.fetch(:exit_code).zero?, message)
|
21
|
-
end
|
22
|
-
|
23
|
-
def push
|
24
|
-
if pushs.empty?
|
25
|
-
info 'PUSH: Nada a enviar'
|
26
|
-
else
|
27
|
-
info "PUSH: enviando \"#{pushs}\"..."
|
28
|
-
git(%w[push origin] + pushs)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def pushs_uncached
|
33
|
-
[master_push, remove_branch_push, tag_push].reject(&:nil?)
|
34
|
-
end
|
35
|
-
|
36
|
-
def master_push
|
37
|
-
remote_master_hash != branch_hash ? "#{branch_hash}:refs/heads/master" : nil
|
38
|
-
end
|
39
|
-
|
40
|
-
def remove_branch_push
|
41
|
-
remote_branch_hash ? ":refs/heads/#{branch}" : nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def tag_push
|
45
|
-
return nil unless !remote_tag_hash || remote_tag_hash != branch_hash
|
46
|
-
|
47
|
-
"#{branch_hash}:#{tag}"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Avm
|
4
|
-
module Git
|
5
|
-
module Issue
|
6
|
-
class Complete
|
7
|
-
def remote_master_hash
|
8
|
-
remote_hashs['refs/heads/master']
|
9
|
-
end
|
10
|
-
|
11
|
-
def remote_branch_hash
|
12
|
-
remote_hashs["refs/heads/#{branch}"]
|
13
|
-
end
|
14
|
-
|
15
|
-
def remote_tag_hash
|
16
|
-
remote_hashs[tag]
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def remote_name
|
22
|
-
'origin'
|
23
|
-
end
|
24
|
-
|
25
|
-
def remote_hashs_uncached
|
26
|
-
@git.remote_hashs(remote_name)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/apps/sources/configuration'
|
4
|
-
require 'avm/result'
|
5
|
-
require 'eac_ruby_utils/fs/temp'
|
6
|
-
|
7
|
-
module Avm
|
8
|
-
module Git
|
9
|
-
module Issue
|
10
|
-
class Complete
|
11
|
-
def test_result
|
12
|
-
test_command = configuration.if_present(&:any_test_command)
|
13
|
-
return ::Avm::Result.success('unconfigured') if test_command.blank?
|
14
|
-
|
15
|
-
infom "Running test command \"#{test_command}\"..."
|
16
|
-
result = test_command.execute
|
17
|
-
test_result_log(result)
|
18
|
-
if result.fetch(:exit_code).zero?
|
19
|
-
::Avm::Result.success('yes')
|
20
|
-
else
|
21
|
-
::Avm::Result.error('no')
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def test_result_log(result)
|
28
|
-
stdout_file = ::EacRubyUtils::Fs::Temp.file
|
29
|
-
stderr_file = ::EacRubyUtils::Fs::Temp.file
|
30
|
-
stdout_file.write(result.fetch(:stdout))
|
31
|
-
stderr_file.write(result.fetch(:stderr))
|
32
|
-
infov ' * Exit code', result.fetch(:exit_code)
|
33
|
-
infov ' * STDOUT', stdout_file.to_path
|
34
|
-
infov ' * STDERR', stderr_file.to_path
|
35
|
-
end
|
36
|
-
|
37
|
-
def configuration_uncached
|
38
|
-
::Avm::Apps::Sources::Configuration.find_by_path(@git)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'clipboard'
|
4
|
-
|
5
|
-
module Avm
|
6
|
-
module Git
|
7
|
-
module Issue
|
8
|
-
class Complete
|
9
|
-
def clipboard_copy_tracker_message
|
10
|
-
::Clipboard.copy(textile_tracker_message)
|
11
|
-
infov 'Copied to clipboard', textile_tracker_message
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def textile_tracker_message_uncached
|
17
|
-
"Revisado para commit:#{branch_short_hash}, ok."
|
18
|
-
end
|
19
|
-
|
20
|
-
def branch_short_hash
|
21
|
-
git(['log', '--pretty=format:%h', '-1', '-q', branch_hash])
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'avm/git/issue/complete/validation'
|
4
|
-
require 'avm/result'
|
5
|
-
require 'ostruct'
|
6
|
-
|
7
|
-
module Avm
|
8
|
-
module Git
|
9
|
-
module Issue
|
10
|
-
class Complete
|
11
|
-
VALIDATIONS = {
|
12
|
-
clean_workspace: 'Clean workspace?',
|
13
|
-
branch_name: 'Branch name',
|
14
|
-
branch_hash: 'Branch hash',
|
15
|
-
follow_master: 'Follow master?',
|
16
|
-
commits: 'Commits?',
|
17
|
-
bifurcations: 'Bifurcations?',
|
18
|
-
dry_push: 'Dry push?',
|
19
|
-
git_subrepos: 'Git subrepos ok?',
|
20
|
-
test: 'Test ok?'
|
21
|
-
}.with_indifferent_access.freeze
|
22
|
-
|
23
|
-
def valid?
|
24
|
-
validations.map(&:result).none?(&:error?)
|
25
|
-
end
|
26
|
-
|
27
|
-
def validations_banner
|
28
|
-
validations.each do |v|
|
29
|
-
infov "[#{v.key}] #{v.label}", v.result.label
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def validate_skip_validations
|
34
|
-
skip_validations.each do |validation|
|
35
|
-
next if VALIDATIONS.keys.include?(validation)
|
36
|
-
|
37
|
-
raise "\"#{validation}\" is not a registered validation"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def validations_uncached
|
44
|
-
VALIDATIONS.map do |key, label|
|
45
|
-
::Avm::Git::Issue::Complete::Validation.new(self, key, label)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Avm
|
4
|
-
module Git
|
5
|
-
module Issue
|
6
|
-
class Complete
|
7
|
-
def clean_workspace_result
|
8
|
-
::Avm::Result.success_or_error(clean_workspace?, 'yes', 'no')
|
9
|
-
end
|
10
|
-
|
11
|
-
def clean_workspace?
|
12
|
-
@git.dirty_files.none?
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|