verto 0.6.1 → 0.10.1

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.
@@ -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
@@ -55,17 +57,13 @@ module Verto
55
57
  end
56
58
 
57
59
  def sh!(command, output: :from_config)
58
- raise Verto::ExitError unless sh(command, output: output).success?
60
+ raise Verto::ExitError, command unless sh(command, output: output).success?
59
61
  end
60
62
 
61
63
  def command_options
62
64
  Verto.config.command_options
63
65
  end
64
66
 
65
- def on(moment, &block)
66
- Verto.config.hooks << Hook.new(moment: moment, &block)
67
- end
68
-
69
67
  def before(&block)
70
68
  Verto.config.hooks << Hook.new(moment: :before, &block)
71
69
  end
@@ -74,14 +72,48 @@ module Verto
74
72
  Verto.config.hooks << Hook.new(moment: :after, &block)
75
73
  end
76
74
 
75
+ def on(moment, &block)
76
+ deprecate('on', use: 'before_tag_creation')
77
+
78
+ Verto.config.hooks << Hook.new(moment: moment, &block)
79
+ end
80
+
77
81
  def before_command(command_name, &block)
82
+ deprecate('before_command', use: 'before_command_tag_up')
83
+
78
84
  Verto.config.hooks << Hook.new(moment: "before_#{command_name}", &block)
79
85
  end
80
86
 
81
87
  def after_command(command_name, &block)
88
+ deprecate('after_command', use: 'after_command_tag_up')
89
+
82
90
  Verto.config.hooks << Hook.new(moment: "after_#{command_name}", &block)
83
91
  end
84
92
 
93
+ def before_command_tag_up(&block)
94
+ Verto.config.hooks << Hook.new(moment: 'before_tag_up', &block)
95
+ end
96
+
97
+ def after_command_tag_up(&block)
98
+ Verto.config.hooks << Hook.new(moment: 'after_tag_up', &block)
99
+ end
100
+
101
+ def before_tag_creation(&block)
102
+ Verto.config.hooks << Hook.new(moment: 'before_tag_creation', &block)
103
+ end
104
+
105
+ def update_changelog(with: :merged_pull_requests_with_bracketed_labels, confirmation: true, filename: 'CHANGELOG.md')
106
+ permitted_moments = %w[before_tag_creation after_tag_up]
107
+ unless permitted_moments.include? Verto.current_moment.to_s
108
+ raise ExitError, 'update_changelog is only supported in before_tag_creation or after_command_tag_up'
109
+ end
110
+
111
+ UpdateChangelog.new.call(with: with,
112
+ new_version: new_version,
113
+ confirmation: confirmation,
114
+ filename: filename)
115
+ end
116
+
85
117
  def file(filepath)
86
118
  DSL::File.new(filepath)
87
119
  end
@@ -90,8 +122,9 @@ module Verto
90
122
  ENV[environment_name]
91
123
  end
92
124
 
125
+ # TODO: Use delegator
93
126
  def confirm(text)
94
- shell_basic.yes?("#{text} (y/n)")
127
+ CliHelpers.confirm(text)
95
128
  end
96
129
 
97
130
  def error(text)
@@ -110,16 +143,12 @@ module Verto
110
143
  @executors ||= {
111
144
  from_config: Verto::SystemCommandExecutor.new,
112
145
  true => Verto::SystemCommandExecutor.new(stdout: $stdout, stderr: $stderr),
113
- false => Verto::SystemCommandExecutor.new(stdout: nil, stderr: nil),
146
+ false => Verto::SystemCommandExecutor.new(stdout: nil, stderr: nil)
114
147
  }
115
148
 
116
149
  @executors[output]
117
150
  end
118
151
 
119
- def shell_basic
120
- @shell_basic ||= Thor::Shell::Basic.new
121
- end
122
-
123
152
  def stderr
124
153
  Verto.stderr
125
154
  end
@@ -135,6 +164,10 @@ module Verto
135
164
 
136
165
  SemanticVersion.new(tag_version)
137
166
  end
167
+
168
+ def deprecate(current, use:)
169
+ warn "[DEPRECATED] `#{current}` is deprecated and will be removed in a future release, use `#{use}` instead"
170
+ end
138
171
  end
139
172
  end
140
173
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Verto
4
+ module DSL
5
+ class UpdateChangelog
6
+ include Verto.import[:cli_helpers, :stdout,
7
+ executor: 'system_command_executor_without_output', changelog_format: 'changelog.format']
8
+
9
+ InvalidChangelogSource = Class.new(Verto::ExitError)
10
+
11
+ SOURCES = StrictHash.new(
12
+ {
13
+ merged_pull_requests_with_bracketed_labels: lambda do |executor|
14
+ executor.run(
15
+ %q(git log --oneline --decorate | grep -B 100 -m 1 "tag:" | grep "pull request" | awk '{print $1}' | xargs git show --format='%b' | grep -v Approved | grep -v "^$" | grep -E "^[[:space:]]*\[.*\]")
16
+ ).output.split("\n").map(&:strip)
17
+ end
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)
23
+ verify_file_presence!(filename)
24
+
25
+ stdout.puts separator
26
+ changelog_changes = format_changes(new_version, version_changes(with))
27
+
28
+ exit if confirmation && !cli_helpers.confirm("Create new Realease?\n" \
29
+ "#{separator}\n" \
30
+ "#{changelog_changes}" \
31
+ "#{separator}\n")
32
+ update_file(filename, changelog_changes)
33
+ end
34
+
35
+ private
36
+
37
+ def verify_file_presence!(filename)
38
+ return if Verto.project_path.join(filename).exist?
39
+
40
+ raise Verto::ExitError, "changelog file '#{filename}' doesnt exist"
41
+ end
42
+
43
+ def version_changes(with)
44
+ SOURCES[with].call(executor)
45
+ end
46
+
47
+ def update_file(filename, changelog_changes)
48
+ DSL::File.new(filename).prepend(changelog_changes)
49
+ end
50
+
51
+ def format_changes(new_version, version_changes)
52
+ Mustache.render(changelog_format, { new_version: new_version, version_changes: version_changes }) + "\n"
53
+ end
54
+
55
+ def separator
56
+ '---------------------------'
57
+ end
58
+ end
59
+ end
60
+ end
@@ -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']
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CliHelpers
4
+ class << self
5
+ def confirm(text)
6
+ shell_basic.yes?("#{text} (y/n)")
7
+ end
8
+
9
+ private
10
+
11
+ def shell_basic
12
+ @shell_basic ||= Thor::Shell::Basic.new
13
+ end
14
+ end
15
+ 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
+ REALEASE_ONLY = /\d+\.\d+\.\d+$/.freeze
5
+ PRE_REALEASE_ONLY = /\d+\.\d+\.\d+-.*\d+/.freeze
4
6
 
5
7
  FILTERS = {
6
8
  release_only: REALEASE_ONLY,
7
9
  pre_release_only: PRE_REALEASE_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:)
@@ -1,36 +1,40 @@
1
- verto_version '0.6.1'
1
+ verto_version '0.10.1'
2
2
 
3
3
  config {
4
4
  # version.prefix = 'v' # Adds a version_prefix
5
5
  # pre_release.initial_number = 0 # Configures pre_release initial number, defaults to 1
6
6
  # project.path = "#{project_path}" # Configures a custom project path
7
+ # git.pull_before_tag_creation = true # Pull Changes before tag creation
8
+ # git.push_after_tag_creation = true # Push changes after tag creation
9
+
10
+ ## CHANGELOG FORMAT
11
+ ## Verto uses Mustache template rendering to render changelog updates, the default value is:
12
+ ##
13
+ ## ## {{new_version}} - #{Time.now.strftime('%d/%m/%Y')}
14
+ ## {{#version_changes}}
15
+ ## * {{.}}
16
+ ## {{/version_changes}}
17
+ ##
18
+ ## A custom format can be specified, eg:
19
+ # changelog.format = <<~CHANGELOG
20
+ # ## {{new_version}}
21
+ # {{#version_changes}}
22
+ # * {{.}}
23
+ # {{/version_changes}}
24
+ # CHANGELOG
7
25
  }
8
26
 
9
27
  context(branch('master')) {
10
- before_command('tag_up') {
11
- git!('pull origin master')
28
+ before_command_tag_up {
12
29
  command_options.add(filter: 'release_only')
13
30
  }
14
31
 
15
- on('before_tag_creation') {
16
-
17
- version_changes = ""
18
- # Uncomment to get Merged PRs Titles as changes to add in CHANGELOG.
19
- # version_changes = sh(
20
- # %q#git log --oneline --decorate | grep -B 100 -m 1 "tag:" | grep "pull request" | awk '{print $1}' | xargs git show --format='%b' | grep -v Approved | grep -v "^$" | grep -E "^[[:space:]]*\[.*\]" | sed 's/^[[:space:]]*\(.*\)/ * \1/'#, output: false
21
- # ).output
22
-
23
- puts "---------------------------"
24
- version_changes = "## #{new_version} - #{Time.now.strftime('%d/%m/%Y')}\n#{version_changes}\n"
25
- exit unless confirm("Create new Realease?\n" \
26
- "---------------------------\n" \
27
- "#{version_changes}" \
28
- "---------------------------\n"
29
- )
30
-
31
- # CHANGELOG
32
- file('CHANGELOG.md').prepend(version_changes)
33
- git('add CHANGELOG.md')
32
+ before_tag_creation {
33
+ # Uncomment to update CHANGELOG file
34
+ # update_changelog(with: :merged_pull_requests_with_bracketed_labels,
35
+ # confirmation: true,
36
+ # filename: 'CHANGELOG.md')
37
+ # git('add CHANGELOG.md')
34
38
 
35
39
  # Uncomment to update the version in other files, like package.json
36
40
  # file('package.json').replace(/"(\d+)\.(\d+)\.(\d+)(-?.*)"/, %Q{"#{new_version}"})
@@ -38,34 +42,28 @@ context(branch('master')) {
38
42
 
39
43
  git('commit -m "Updates CHANGELOG"')
40
44
  }
41
-
42
- after_command('tag_up') {
43
- git('push --tags')
44
- git('push origin master')
45
- }
46
45
  }
47
46
 
48
47
  # Uncomment to get a specific pre_release proccess, like a staging or qa branch
49
48
  # context(branch('staging')) {
50
- # before_command('tag_up') {
49
+ # before_command_tag_up {
51
50
  # git!('pull origin staging')
52
51
  # command_options.add(pre_release: 'rc')
53
52
  # }
54
53
  #
55
- # on('before_tag_creation') {
54
+ # before_tag_creation {
56
55
  # file('package.json').replace(/"(\d+)\.(\d+)\.(\d+)(-?.*)"/, %Q{"#{new_version}"}) # Atualiza versão do package.json
57
56
  # git('add package.json')
58
57
  # git('commit --allow-empty -m "Staging Release"')
59
58
  # }
60
59
 
61
- # after_command('tag_up') {
62
- # git('push --tags')
63
- # git('push origin staging')
60
+ # after_command_tag_up {
61
+ # sh('some command')
64
62
  # }
65
63
  #}
66
64
 
67
65
  # Uncomment to block tag creation in other branchs
68
66
  #context(!branch('master', 'staging')) {
69
- # error "Tags only can be created in master or staging branch"
67
+ # error 'Tags only can be created in master or staging branch'
70
68
  # exit
71
69
  #}
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
- VERSION = "0.6.1"
4
+ VERSION = '0.10.1'
3
5
  end
@@ -1,40 +1,44 @@
1
- lib = File.expand_path("lib", __dir__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "verto/version"
5
+ require 'verto/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "verto"
8
+ spec.name = 'verto'
7
9
  spec.version = Verto::VERSION
8
- spec.authors = ["Carlos Atkinson"]
9
- spec.email = ["carlos.atks@gmail.com"]
10
-
11
- spec.summary = %q{Verto helps you to versionate your project}
12
- spec.homepage = "https://github.com/catks/verto"
13
- spec.license = "MIT"
10
+ spec.authors = ['Carlos Atkinson']
11
+ spec.email = ['carlos.atks@gmail.com']
14
12
 
13
+ spec.summary = 'Verto helps you to versionate your project'
14
+ spec.homepage = 'https://github.com/catks/verto'
15
+ spec.license = 'MIT'
15
16
 
16
- # spec.metadata["homepage_uri"] = spec.homepage
17
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
18
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/catks/verto'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/catks/verto/blob/master/CHANGELOG.md'
19
20
 
20
21
  # Specify which files should be added to the gem when it is released.
21
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
24
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
25
  end
25
- spec.bindir = "exe"
26
+ spec.bindir = 'exe'
26
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
28
+ spec.require_paths = ['lib']
29
+ spec.required_ruby_version = '~> 2.5'
28
30
 
29
- spec.add_dependency "thor", "~> 1.0.1"
30
- spec.add_dependency "dry-configurable", "~> 0.8"
31
- spec.add_dependency "dry-container", "~> 0.7"
32
- spec.add_dependency "dry-auto_inject", "~> 0.7"
33
- spec.add_dependency "vseries", "~> 0.2"
31
+ spec.add_dependency 'dry-auto_inject', '~> 0.7'
32
+ spec.add_dependency 'dry-configurable', '~> 0.8'
33
+ spec.add_dependency 'dry-container', '~> 0.7'
34
+ spec.add_dependency 'mustache', '~> 1.1.1'
35
+ spec.add_dependency 'thor', '~> 1.0.1'
36
+ spec.add_dependency 'vseries', '~> 0.2'
34
37
 
35
- spec.add_development_dependency "byebug"
36
- spec.add_development_dependency "bundler", "~> 2.0"
37
- spec.add_development_dependency "rake", "~> 13.0"
38
- spec.add_development_dependency "rspec", "~> 3.0"
39
- spec.add_development_dependency "simplecov", "~> 0.18.0"
38
+ spec.add_development_dependency 'bundler', '~> 2.0'
39
+ spec.add_development_dependency 'byebug'
40
+ spec.add_development_dependency 'rake', '~> 13.0'
41
+ spec.add_development_dependency 'rspec', '~> 3.0'
42
+ spec.add_development_dependency 'rubocop'
43
+ spec.add_development_dependency 'simplecov', '~> 0.17.0'
40
44
  end