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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +54 -0
  3. data/.rubocop.yml +23 -0
  4. data/.rubocop_todo.yml +50 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +22 -0
  7. data/Gemfile +3 -1
  8. data/Gemfile.lock +79 -29
  9. data/README.md +75 -65
  10. data/Rakefile +7 -5
  11. data/VERTO_SYNTAX.md +350 -0
  12. data/Vertofile +5 -19
  13. data/bin/console +5 -8
  14. data/djin.yml +50 -0
  15. data/exe/verto +8 -4
  16. data/lib/verto/commands/base_command.rb +7 -2
  17. data/lib/verto/commands/main_command.rb +10 -6
  18. data/lib/verto/commands/tag_command.rb +65 -26
  19. data/lib/verto/dsl/built_in_hooks.rb +7 -1
  20. data/lib/verto/dsl/file.rb +4 -2
  21. data/lib/verto/dsl/hook.rb +2 -0
  22. data/lib/verto/dsl/interpreter.rb +8 -7
  23. data/lib/verto/dsl/syntax.rb +27 -6
  24. data/lib/verto/dsl/update_changelog/filtered_by.rb +45 -0
  25. data/lib/verto/dsl/update_changelog/with_commit_messages.rb +30 -0
  26. data/lib/verto/dsl/update_changelog/with_merged_pull_requests.rb +19 -0
  27. data/lib/verto/dsl/update_changelog.rb +85 -0
  28. data/lib/verto/dsl.rb +2 -0
  29. data/lib/verto/repositories/tag_repository.rb +6 -0
  30. data/lib/verto/utils/cli_helpers.rb +37 -0
  31. data/lib/verto/utils/command_options.rb +4 -2
  32. data/lib/verto/utils/semantic_version.rb +2 -0
  33. data/lib/verto/utils/strict_hash.rb +9 -0
  34. data/lib/verto/utils/system_command_executor.rb +4 -2
  35. data/lib/verto/utils/tag_filter.rb +7 -5
  36. data/lib/verto/utils/template.rb +2 -0
  37. data/lib/verto/utils/templates/Vertofile +26 -28
  38. data/lib/verto/version.rb +3 -1
  39. data/lib/verto.rb +62 -25
  40. data/verto.gemspec +33 -25
  41. metadata +113 -19
  42. 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 "up", "Create's a new tag"
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
- stderr.puts "Creating Tag #{version_prefix}#{new_version}..."
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) & [:major, :minor, :patch]
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
- new_version = new_version.up(:pre_release) if new_version.pre_release.name == version.pre_release.name && new_version == version
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
- ) unless latest_tag
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
- New version(#{new_version}) can't be equal or lower than latest version(#{latest_version})
80
- run up --pre-release with --patch, --minor or --major (eg: verto tag up --patch --pre-release=rc),
81
- add filters (eg: verto tag up --pre-release --filter=pre_release_only)
82
- or disable tag validation in Vertofile with config.version.validations.new_version_must_be_bigger = false
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
- ) if new_version < latest_version && Verto.config.version.validations.new_version_must_be_bigger
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
- You must specify the version number to be increased, use the some of the options(eg: --major, --minor, --patch, --pre_release=rc)
91
- or configure a Vertofile to specify a default option for current context, eg:
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
- context('qa') {
94
- before_command('tag_up') {
95
- command_options.add(pre_release: 'rc')
117
+ context('qa') {
118
+ before_command('tag_up') {
119
+ command_options.add(pre_release: 'rc')
120
+ }
96
121
  }
97
- }
98
122
  TEXT
99
- ) unless options[:major] || options[:minor] || options[:patch] || options[:pre_release] || options[:release]
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
- Verto.config.hooks.prepend Verto::DSL::BuiltInHooks::GitPullCurrentBranch if Verto.config.git.pull_before_tag_creation
112
- Verto.config.hooks << Verto::DSL::BuiltInHooks::GitPushCurrentBranch if Verto.config.git.push_after_tag_creation
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!("push --tags")
15
+ git!('push --tags')
10
16
  end
11
17
 
12
18
  GitPushCurrentBranchCommits = DSL::Hook.new(moment: :after) do
@@ -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
- alias_method :gsub, :replace_all
40
- alias_method :sub, :replace
41
+ alias gsub replace_all
42
+ alias sub replace
41
43
 
42
44
  private
43
45
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
4
  module DSL
3
5
  class Hook
@@ -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) : instance_eval(&block)
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
- rescue StandardError => error
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, value|
31
+ attributes.each do |key, _value|
31
32
  instance_variable_set("@#{key}", nil)
32
33
  singleton_class.remove_method(key)
33
34
  end
@@ -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
- shell_basic.yes?("#{text} (y/n)")
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
  module DSL
3
5
  def self.load_file(filepath)
@@ -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
- alias_method :add, :merge!
5
+ alias add merge!
4
6
 
5
7
  def except(*keys)
6
- self.reject { |key, v| keys.include?(key) }
8
+ reject { |key, _v| keys.include?(key) }
7
9
  end
8
10
  end
9
11
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
4
  class SemanticVersion < Vseries::SemanticVersion
3
5
  DEFAULT_PRE_RELEASE_INITIAL_NUMBER = Verto.config.pre_release.initial_number
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class StrictHash < Hash
4
+ def initialize(hash, default_proc: nil)
5
+ super()
6
+ self.default_proc = default_proc if default_proc
7
+ merge!(hash)
8
+ end
9
+ 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
- class Result < Struct.new(:output, :error, :result)
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.puts running_log(command, path) if 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
- REALEASE_ONLY = /\d+\.\d+\.\d+$/
3
- PRE_REALEASE_ONLY = /\d+\.\d+\.\d+-.*\d+/
4
+ RELEASE_ONLY = /\d+\.\d+\.\d+$/.freeze
5
+ PRE_RELEASE_ONLY = /\d+\.\d+\.\d+-.*\d+/.freeze
4
6
 
5
7
  FILTERS = {
6
- release_only: REALEASE_ONLY,
7
- pre_release_only: PRE_REALEASE_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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
4
  class Template
3
5
  def self.render(template_name, to:)