verto 0.9.0 → 0.12.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/.github/workflows/ruby.yml +54 -0
- data/.rubocop.yml +23 -0
- data/.rubocop_todo.yml +50 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +79 -29
- data/README.md +75 -65
- data/Rakefile +7 -5
- data/VERTO_SYNTAX.md +350 -0
- data/Vertofile +5 -19
- data/bin/console +5 -8
- data/djin.yml +50 -0
- data/exe/verto +8 -4
- data/lib/verto/commands/base_command.rb +7 -2
- data/lib/verto/commands/main_command.rb +10 -6
- data/lib/verto/commands/tag_command.rb +65 -26
- data/lib/verto/dsl/built_in_hooks.rb +7 -1
- data/lib/verto/dsl/file.rb +4 -2
- data/lib/verto/dsl/hook.rb +2 -0
- data/lib/verto/dsl/interpreter.rb +8 -7
- data/lib/verto/dsl/syntax.rb +27 -6
- data/lib/verto/dsl/update_changelog/filtered_by.rb +45 -0
- data/lib/verto/dsl/update_changelog/with_commit_messages.rb +30 -0
- data/lib/verto/dsl/update_changelog/with_merged_pull_requests.rb +19 -0
- data/lib/verto/dsl/update_changelog.rb +85 -0
- data/lib/verto/dsl.rb +2 -0
- data/lib/verto/repositories/tag_repository.rb +6 -0
- data/lib/verto/utils/cli_helpers.rb +37 -0
- data/lib/verto/utils/command_options.rb +4 -2
- data/lib/verto/utils/semantic_version.rb +2 -0
- data/lib/verto/utils/strict_hash.rb +9 -0
- data/lib/verto/utils/system_command_executor.rb +4 -2
- data/lib/verto/utils/tag_filter.rb +7 -5
- data/lib/verto/utils/template.rb +2 -0
- data/lib/verto/utils/templates/Vertofile +26 -28
- data/lib/verto/version.rb +3 -1
- data/lib/verto.rb +62 -25
- data/verto.gemspec +33 -25
- metadata +113 -19
- data/.travis.yml +0 -13
@@ -1,6 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
1
4
|
module Verto
|
2
5
|
class TagCommand < BaseCommand
|
3
|
-
desc
|
6
|
+
desc 'init', "Create's the first tag"
|
7
|
+
|
8
|
+
def init
|
9
|
+
load_config_hooks!
|
10
|
+
|
11
|
+
error_message = 'This repository already has tags'
|
12
|
+
raise Verto::ExitError, error_message if tag_repository.any?
|
13
|
+
|
14
|
+
create_git_tag('0.1.0')
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'up', "Create's a new tag"
|
4
18
|
|
5
19
|
option :major, type: :boolean, default: false
|
6
20
|
option :minor, type: :boolean, default: false
|
@@ -13,7 +27,7 @@ module Verto
|
|
13
27
|
def up
|
14
28
|
load_config_hooks!
|
15
29
|
|
16
|
-
call_hooks(%i[before before_tag_up], with_attributes: { command_options: options}
|
30
|
+
call_hooks(%i[before before_tag_up], with_attributes: { command_options: options })
|
17
31
|
|
18
32
|
validate_version_option_presence!
|
19
33
|
|
@@ -27,11 +41,9 @@ module Verto
|
|
27
41
|
|
28
42
|
validate_new_version!(new_version, latest_version)
|
29
43
|
|
30
|
-
call_hooks(:before_tag_creation, with_attributes: { new_version: new_version }
|
44
|
+
call_hooks(:before_tag_creation, with_attributes: { new_version: new_version })
|
31
45
|
|
32
|
-
|
33
|
-
tag_repository.create!("#{version_prefix}#{new_version}")
|
34
|
-
stderr.puts "Tag #{version_prefix}#{new_version} Created!"
|
46
|
+
create_git_tag(new_version)
|
35
47
|
|
36
48
|
call_hooks(:after_tag_up, with_attributes: { new_version: new_version })
|
37
49
|
call_hooks(:after)
|
@@ -42,7 +54,7 @@ module Verto
|
|
42
54
|
include Verto.import['tag_repository']
|
43
55
|
|
44
56
|
def up_version(version, options)
|
45
|
-
up_options = options.select { |_, value| value == true }.keys.map(&:to_sym) & [
|
57
|
+
up_options = options.select { |_, value| value == true }.keys.map(&:to_sym) & %i[major minor patch]
|
46
58
|
up_option = up_options.min
|
47
59
|
|
48
60
|
new_version = version.up(up_option)
|
@@ -50,53 +62,65 @@ module Verto
|
|
50
62
|
if options[:pre_release]
|
51
63
|
identifier = pre_release_configured? ? options[:pre_release] : version.pre_release.name || default_identifier
|
52
64
|
new_version = new_version.with_pre_release(identifier)
|
53
|
-
|
65
|
+
if new_version.pre_release.name == version.pre_release.name && new_version == version
|
66
|
+
new_version = new_version.up(:pre_release)
|
67
|
+
end
|
54
68
|
end
|
55
69
|
|
56
|
-
if options[:release]
|
57
|
-
new_version = new_version.release_version
|
58
|
-
end
|
70
|
+
new_version = new_version.release_version if options[:release]
|
59
71
|
|
60
72
|
new_version
|
61
73
|
end
|
62
74
|
|
75
|
+
def create_git_tag(version)
|
76
|
+
stderr.puts "Creating Tag #{version_prefix}#{version}..."
|
77
|
+
tag_repository.create!("#{version_prefix}#{version}")
|
78
|
+
stderr.puts "Tag #{version_prefix}#{version} Created!"
|
79
|
+
end
|
80
|
+
|
63
81
|
def pre_release_configured?
|
64
82
|
options[:pre_release] != 'pre_release'
|
65
83
|
end
|
66
84
|
|
67
85
|
def validate_latest_tag!(latest_tag)
|
86
|
+
return if latest_tag
|
87
|
+
|
68
88
|
command_error!(
|
69
89
|
<<~TEXT
|
70
90
|
Project doesn't have a previous tag version, create a new tag with git.
|
71
91
|
eg: `git tag #{version_prefix}0.1.0`
|
72
92
|
TEXT
|
73
|
-
)
|
93
|
+
)
|
74
94
|
end
|
75
95
|
|
76
96
|
def validate_new_version!(new_version, latest_version)
|
97
|
+
return unless new_version < latest_version && Verto.config.version.validations.new_version_must_be_bigger
|
98
|
+
|
77
99
|
command_error!(
|
78
100
|
<<~TEXT
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
101
|
+
New version(#{new_version}) can't be equal or lower than latest version(#{latest_version})
|
102
|
+
run up --pre-release with --patch, --minor or --major (eg: verto tag up --patch --pre-release=rc),
|
103
|
+
add filters (eg: verto tag up --pre-release --filter=pre_release_only)
|
104
|
+
or disable tag validation in Vertofile with config.version.validations.new_version_must_be_bigger = false
|
83
105
|
TEXT
|
84
|
-
)
|
106
|
+
)
|
85
107
|
end
|
86
108
|
|
87
109
|
def validate_version_option_presence!
|
110
|
+
return if options[:major] || options[:minor] || options[:patch] || options[:pre_release] || options[:release]
|
111
|
+
|
88
112
|
command_error!(
|
89
113
|
<<~TEXT
|
90
|
-
|
91
|
-
|
114
|
+
You must specify the version number to be increased, use the some of the options(eg: --major, --minor, --patch, --pre_release=rc)
|
115
|
+
or configure a Vertofile to specify a default option for current context, eg:
|
92
116
|
|
93
|
-
|
94
|
-
|
95
|
-
|
117
|
+
context('qa') {
|
118
|
+
before_command('tag_up') {
|
119
|
+
command_options.add(pre_release: 'rc')
|
120
|
+
}
|
96
121
|
}
|
97
|
-
}
|
98
122
|
TEXT
|
99
|
-
)
|
123
|
+
)
|
100
124
|
end
|
101
125
|
|
102
126
|
def load_filter
|
@@ -108,8 +132,22 @@ module Verto
|
|
108
132
|
end
|
109
133
|
|
110
134
|
def load_config_hooks!
|
111
|
-
|
112
|
-
|
135
|
+
enabled_hooks = ->(_, v) { v }
|
136
|
+
|
137
|
+
config_hooks[:before].select(&enabled_hooks).each_key { |hook| Verto.config.hooks.prepend(hook) }
|
138
|
+
config_hooks[:after].select(&enabled_hooks).each_key { |hook| Verto.config.hooks << hook }
|
139
|
+
end
|
140
|
+
|
141
|
+
def config_hooks
|
142
|
+
@config_hooks ||= {
|
143
|
+
before: {
|
144
|
+
Verto::DSL::BuiltInHooks::GitPullCurrentBranch => Verto.config.git.pull_before_tag_creation,
|
145
|
+
Verto::DSL::BuiltInHooks::GitFetch => Verto.config.git.fetch_before_tag_creation
|
146
|
+
},
|
147
|
+
after: {
|
148
|
+
Verto::DSL::BuiltInHooks::GitPushCurrentBranch => Verto.config.git.push_after_tag_creation
|
149
|
+
}
|
150
|
+
}
|
113
151
|
end
|
114
152
|
|
115
153
|
def default_identifier
|
@@ -117,3 +155,4 @@ module Verto
|
|
117
155
|
end
|
118
156
|
end
|
119
157
|
end
|
158
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
module DSL
|
3
5
|
module BuiltInHooks
|
@@ -5,8 +7,12 @@ module Verto
|
|
5
7
|
git!("pull origin #{current_branch}")
|
6
8
|
end
|
7
9
|
|
10
|
+
GitFetch = DSL::Hook.new(moment: :before) do
|
11
|
+
git!('fetch')
|
12
|
+
end
|
13
|
+
|
8
14
|
GitPushTags = DSL::Hook.new(moment: :after) do
|
9
|
-
git!(
|
15
|
+
git!('push --tags')
|
10
16
|
end
|
11
17
|
|
12
18
|
GitPushCurrentBranchCommits = DSL::Hook.new(moment: :after) do
|
data/lib/verto/dsl/file.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
module DSL
|
3
5
|
class File
|
@@ -36,8 +38,8 @@ module Verto
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
alias gsub replace_all
|
42
|
+
alias sub replace
|
41
43
|
|
42
44
|
private
|
43
45
|
|
data/lib/verto/dsl/hook.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
module DSL
|
3
5
|
class Interpreter
|
@@ -6,15 +8,14 @@ module Verto
|
|
6
8
|
# TODO: Wrap stacktrace
|
7
9
|
Error = Class.new(Verto::ExitError)
|
8
10
|
|
9
|
-
def evaluate(vertofile_content=nil, attributes: {}, &block)
|
11
|
+
def evaluate(vertofile_content = nil, attributes: {}, &block)
|
10
12
|
with_attributes(attributes) do
|
11
|
-
vertofile_content ? instance_eval(vertofile_content)
|
13
|
+
vertofile_content ? instance_eval(vertofile_content) : instance_eval(&block)
|
12
14
|
end
|
15
|
+
rescue StandardError => e
|
16
|
+
raise e if e.is_a?(Verto::ExitError)
|
13
17
|
|
14
|
-
|
15
|
-
raise error if error.is_a?(Verto::ExitError)
|
16
|
-
|
17
|
-
raise Error, error.message
|
18
|
+
raise Error, e.message
|
18
19
|
end
|
19
20
|
|
20
21
|
private
|
@@ -27,7 +28,7 @@ module Verto
|
|
27
28
|
|
28
29
|
block.call
|
29
30
|
|
30
|
-
attributes.each do |key,
|
31
|
+
attributes.each do |key, _value|
|
31
32
|
instance_variable_set("@#{key}", nil)
|
32
33
|
singleton_class.remove_method(key)
|
33
34
|
end
|
data/lib/verto/dsl/syntax.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
module DSL
|
3
5
|
module Syntax
|
@@ -100,6 +102,28 @@ module Verto
|
|
100
102
|
Verto.config.hooks << Hook.new(moment: 'before_tag_creation', &block)
|
101
103
|
end
|
102
104
|
|
105
|
+
# Start the flow to Update the CHANGELOG file
|
106
|
+
# @param :with [Symbol] The strategy to search commit messages
|
107
|
+
# Options include:
|
108
|
+
# :merged_pull_requests_with_bracketed_labels -> Uses all PR merged commits after the last tag if they have the [***] pattern
|
109
|
+
# :commits_with_bracketed_labels -> Uses all commits after the last tag if they have the [***] pattern (Exclude merge commits)
|
110
|
+
# :merged_pull_requests_messages -> Uses all merged commit after the last tag
|
111
|
+
# :commit_messages -> Uses all commits after the last tag (Exclude merge commits)
|
112
|
+
# @param :confirmation [Boolean] Adds a confirmation step before updating the CHANGELOG
|
113
|
+
# @param filename [String] The CHANGELOG filename
|
114
|
+
# @param message_pattern [Regexp] A regexp pattern to filter commit messages
|
115
|
+
def update_changelog(with: :merged_pull_requests_with_bracketed_labels, confirmation: true, filename: 'CHANGELOG.md')
|
116
|
+
permitted_moments = %w[before_tag_creation after_tag_up]
|
117
|
+
unless permitted_moments.include? Verto.current_moment.to_s
|
118
|
+
raise ExitError, 'update_changelog is only supported in before_tag_creation or after_command_tag_up'
|
119
|
+
end
|
120
|
+
|
121
|
+
UpdateChangelog.new.call(with: with,
|
122
|
+
new_version: new_version,
|
123
|
+
confirmation: confirmation,
|
124
|
+
filename: filename)
|
125
|
+
end
|
126
|
+
|
103
127
|
def file(filepath)
|
104
128
|
DSL::File.new(filepath)
|
105
129
|
end
|
@@ -108,8 +132,9 @@ module Verto
|
|
108
132
|
ENV[environment_name]
|
109
133
|
end
|
110
134
|
|
135
|
+
# TODO: Use delegator
|
111
136
|
def confirm(text)
|
112
|
-
|
137
|
+
CliHelpers.confirm(text)
|
113
138
|
end
|
114
139
|
|
115
140
|
def error(text)
|
@@ -128,16 +153,12 @@ module Verto
|
|
128
153
|
@executors ||= {
|
129
154
|
from_config: Verto::SystemCommandExecutor.new,
|
130
155
|
true => Verto::SystemCommandExecutor.new(stdout: $stdout, stderr: $stderr),
|
131
|
-
false => Verto::SystemCommandExecutor.new(stdout: nil, stderr: nil)
|
156
|
+
false => Verto::SystemCommandExecutor.new(stdout: nil, stderr: nil)
|
132
157
|
}
|
133
158
|
|
134
159
|
@executors[output]
|
135
160
|
end
|
136
161
|
|
137
|
-
def shell_basic
|
138
|
-
@shell_basic ||= Thor::Shell::Basic.new
|
139
|
-
end
|
140
|
-
|
141
162
|
def stderr
|
142
163
|
Verto.stderr
|
143
164
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verto
|
4
|
+
module DSL
|
5
|
+
class UpdateChangelog
|
6
|
+
module FilteredBy
|
7
|
+
def self.included(klass)
|
8
|
+
klass.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def filtered_by(filter)
|
13
|
+
Proxy.new(self, filter)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Proxy
|
18
|
+
def initialize(filter_class, final_filter)
|
19
|
+
@filter_class = filter_class
|
20
|
+
@final_filter = final_filter
|
21
|
+
end
|
22
|
+
|
23
|
+
def new
|
24
|
+
filter_object
|
25
|
+
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def call(*args)
|
30
|
+
filter_object
|
31
|
+
.call(*args)
|
32
|
+
.select { |message| @final_filter.match?(message) }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Lazy evaluete object to load Verto dependencies only at the last
|
38
|
+
def filter_object
|
39
|
+
@filter_object ||= @filter_class.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verto
|
4
|
+
module DSL
|
5
|
+
class UpdateChangelog
|
6
|
+
class WithCommitMessages
|
7
|
+
include Verto.import[executor: 'system_command_executor_without_output', tag_repository: 'tag_repository']
|
8
|
+
include FilteredBy
|
9
|
+
|
10
|
+
def call(message_pattern = /.+/)
|
11
|
+
executor.run(
|
12
|
+
"git log --no-merges --pretty=format:%s #{commit_range}"
|
13
|
+
).output.split("\n").map(&:strip).select { |message| message_pattern.match? message }
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def commit_range
|
19
|
+
return unless latest_tag
|
20
|
+
|
21
|
+
"HEAD ^#{latest_tag}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def latest_tag
|
25
|
+
tag_repository.latest
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verto
|
4
|
+
module DSL
|
5
|
+
class UpdateChangelog
|
6
|
+
class WithMergedPullRequests
|
7
|
+
include Verto.import[executor: 'system_command_executor_without_output']
|
8
|
+
include FilteredBy
|
9
|
+
|
10
|
+
def call(message_pattern = /.+/)
|
11
|
+
# FIXME: Format the command
|
12
|
+
executor.run(
|
13
|
+
%q(git log --oneline --decorate | grep -B 100 -m 1 "tag:" | grep "pull request" | awk '{print $1}' | xargs -r git show --format='%b' | grep -v Approved | grep -v "^$") # rubocop:disable Layout/LineLength
|
14
|
+
).output.split("\n").map(&:strip).select { |pr_message| message_pattern.match? pr_message }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verto
|
4
|
+
module DSL
|
5
|
+
class UpdateChangelog
|
6
|
+
include Verto.import[:cli_helpers, :stdout, changelog_format: 'changelog.format']
|
7
|
+
|
8
|
+
InvalidChangelogSource = Class.new(Verto::ExitError)
|
9
|
+
|
10
|
+
BRACKETED_LABELS_REGEXP = /^[[:space:]]*\[.*\]/.freeze
|
11
|
+
|
12
|
+
SOURCES = StrictHash.new(
|
13
|
+
{
|
14
|
+
merged_pull_requests_with_bracketed_labels: WithMergedPullRequests.filtered_by(BRACKETED_LABELS_REGEXP),
|
15
|
+
commits_with_bracketed_labels: WithCommitMessages.filtered_by(BRACKETED_LABELS_REGEXP),
|
16
|
+
merged_pull_requests_messages: WithMergedPullRequests,
|
17
|
+
commit_messages: WithCommitMessages
|
18
|
+
},
|
19
|
+
default_proc: ->(hash, _) { raise InvalidChangelogSource, "Invalid CHANGELOG Source, avaliable options: '#{hash.keys.join(',')}'" }
|
20
|
+
)
|
21
|
+
|
22
|
+
def call(new_version:, confirmation: true, filename: 'CHANGELOG.md', with: :merged_pull_requests_with_bracketed_labels, message_pattern: nil)
|
23
|
+
verify_file_presence!(filename)
|
24
|
+
|
25
|
+
changelog_changes = format_changes(new_version, version_changes(with, message_pattern))
|
26
|
+
|
27
|
+
if confirmation
|
28
|
+
stdout.puts separator
|
29
|
+
stdout.puts changelog_changes
|
30
|
+
stdout.puts separator
|
31
|
+
changelog_changes = select_changelog_text(changelog_changes)
|
32
|
+
end
|
33
|
+
|
34
|
+
update_file(filename, changelog_changes)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# TODO: Refactor
|
40
|
+
def select_changelog_text(changelog_changes) # rubocop:disable Metrics/MethodLength
|
41
|
+
choices = [
|
42
|
+
{ key: 'y', name: 'Create a new Release CHANGELOG', value: :yes },
|
43
|
+
{ key: 'n', name: 'Cancel the Release CHANGELOG', value: :no },
|
44
|
+
{ key: 'e', name: 'Edit the Release CHANGELOG before continuing', value: :edit }
|
45
|
+
]
|
46
|
+
case cli_helpers.select_options('Create new Release?', choices)
|
47
|
+
when :no
|
48
|
+
exit
|
49
|
+
when :edit
|
50
|
+
cli_helpers.edit_text(changelog_changes)
|
51
|
+
else
|
52
|
+
changelog_changes
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify_file_presence!(filename)
|
57
|
+
return if Verto.project_path.join(filename).exist?
|
58
|
+
|
59
|
+
raise Verto::ExitError, "changelog file '#{filename}' doesnt exist"
|
60
|
+
end
|
61
|
+
|
62
|
+
def version_changes(with, message_pattern)
|
63
|
+
SOURCES[with.to_sym].new.call(*args_if_any(message_pattern))
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_file(filename, changelog_changes)
|
67
|
+
DSL::File.new(filename).prepend(changelog_changes)
|
68
|
+
end
|
69
|
+
|
70
|
+
def format_changes(new_version, version_changes)
|
71
|
+
changes = Mustache.render(changelog_format,
|
72
|
+
{ new_version: new_version, version_changes: version_changes })
|
73
|
+
"#{changes}\n"
|
74
|
+
end
|
75
|
+
|
76
|
+
def separator
|
77
|
+
'---------------------------'
|
78
|
+
end
|
79
|
+
|
80
|
+
def args_if_any(arg)
|
81
|
+
[arg].compact
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/verto/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
class TagRepository
|
3
5
|
include Verto.import[executor: 'system_command_executor_without_output']
|
@@ -11,6 +13,10 @@ module Verto
|
|
11
13
|
executor.run! "git tag #{tag}"
|
12
14
|
end
|
13
15
|
|
16
|
+
def any?
|
17
|
+
all.any?
|
18
|
+
end
|
19
|
+
|
14
20
|
def all(filter: nil)
|
15
21
|
results = executor.run("git tag | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+(-.+\.[0-9]+)*' | sed 's/\([0-9]\.[0-9]\.[0-9]$\)/\1-zzzzzzzzzz/' | sort -V | sed 's/-zzzzzzzzzz//' | cat").output.split
|
16
22
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verto
|
4
|
+
module CliHelpers
|
5
|
+
class << self
|
6
|
+
def confirm(text)
|
7
|
+
shell_basic.yes?("#{text} (y/n)")
|
8
|
+
end
|
9
|
+
|
10
|
+
def select_options(question, choices)
|
11
|
+
tty_prompt.expand(question, choices)
|
12
|
+
end
|
13
|
+
|
14
|
+
def edit_text(text)
|
15
|
+
tempfile = "/tmp/verto-changelog-edit-#{SecureRandom.hex}"
|
16
|
+
|
17
|
+
TTY::Editor.open(tempfile, text: text)
|
18
|
+
|
19
|
+
edited_text = File.read(tempfile)
|
20
|
+
|
21
|
+
File.delete(tempfile)
|
22
|
+
|
23
|
+
edited_text
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def shell_basic
|
29
|
+
@shell_basic ||= Thor::Shell::Basic.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def tty_prompt
|
33
|
+
@tty_prompt = TTY::Prompt.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Verto
|
2
4
|
class CommandOptions < Thor::CoreExt::HashWithIndifferentAccess
|
3
|
-
|
5
|
+
alias add merge!
|
4
6
|
|
5
7
|
def except(*keys)
|
6
|
-
|
8
|
+
reject { |key, _v| keys.include?(key) }
|
7
9
|
end
|
8
10
|
end
|
9
11
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'open3'
|
2
4
|
|
3
5
|
module Verto
|
4
6
|
class SystemCommandExecutor
|
5
7
|
include Verto.import['project.path', 'stdout', 'stderr']
|
6
8
|
|
7
|
-
|
9
|
+
Result = Struct.new(:output, :error, :result) do
|
8
10
|
def success?
|
9
11
|
result.success?
|
10
12
|
end
|
@@ -16,7 +18,7 @@ module Verto
|
|
16
18
|
Error = Class.new(StandardError)
|
17
19
|
|
18
20
|
def run(command)
|
19
|
-
stderr
|
21
|
+
stderr&.puts running_log(command, path)
|
20
22
|
|
21
23
|
Open3.popen3(command, chdir: path.to_s) do |_, stdout, stderr, wait_thread|
|
22
24
|
@output = stdout.read
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TagFilter
|
2
|
-
|
3
|
-
|
4
|
+
RELEASE_ONLY = /\d+\.\d+\.\d+$/.freeze
|
5
|
+
PRE_RELEASE_ONLY = /\d+\.\d+\.\d+-.*\d+/.freeze
|
4
6
|
|
5
7
|
FILTERS = {
|
6
|
-
release_only:
|
7
|
-
pre_release_only:
|
8
|
+
release_only: RELEASE_ONLY,
|
9
|
+
pre_release_only: PRE_RELEASE_ONLY,
|
8
10
|
all: nil
|
9
|
-
}
|
11
|
+
}.freeze
|
10
12
|
|
11
13
|
def self.for(tag_key)
|
12
14
|
FILTERS[tag_key.to_sym] if tag_key
|