verto 0.9.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/VERTO_SYNTAX.md ADDED
@@ -0,0 +1,350 @@
1
+ # Verto Syntax
2
+
3
+ ## verto_version
4
+
5
+ Set the minimal verto version compatible with Vertofile
6
+
7
+ ```ruby
8
+ # Vertofile
9
+ verto_version '0.11.0'
10
+ ```
11
+
12
+ ## config
13
+
14
+ Allows you to customize the behavior for verto commands.
15
+
16
+ Example:
17
+ ```ruby
18
+ # Vertofile
19
+ config {
20
+ version.prefix = 'v' # Adds a version_prefix
21
+ pre_release.default_identifier = 'alpha' # Defaults to 'rc'
22
+ git.pull_before_tag_creation = true # Pull Changes before tag creation
23
+ git.fetch_before_tag_creation = true # Fetch Branches and Tags before tag creation
24
+ git.push_after_tag_creation = true # Push changes after tag creation
25
+
26
+ ## CHANGELOG FORMAT
27
+ ## Verto uses Mustache template rendering to render changelog updates, the default value is:
28
+ ##
29
+ ## ## {{new_version}} - #{Time.now.strftime('%d/%m/%Y')}
30
+ ## {{#version_changes}}
31
+ ## * {{.}}
32
+ ## {{/version_changes}}
33
+ ##
34
+ ## A custom format can be specified, eg:
35
+ changelog.format = <<~CHANGELOG
36
+ ## {{new_version}}
37
+ {{#version_changes}}
38
+ * {{.}}
39
+ {{/version_changes}}
40
+ CHANGELOG
41
+ }
42
+
43
+ ```
44
+
45
+ ## context
46
+
47
+ In the context block you can create a scope that will only run if the statment it's true.
48
+
49
+ Example:
50
+
51
+ ```ruby
52
+ # Vertofile
53
+
54
+ # Only runs on master branch
55
+ context(branch('master')) {
56
+ ...
57
+ }
58
+
59
+ # Only runs on staging branch
60
+ context(branch('staging')) {
61
+ ...
62
+ }
63
+ # Only runs if the branch is not master or staging
64
+ context(!branch('master', 'staging')) {
65
+ ...
66
+ }
67
+
68
+ # You can also run with a custom conditional (With ruby code)
69
+ context(current_branch.match?(/feature\/.+/)) {
70
+ ...
71
+ }
72
+ ```
73
+
74
+ ## before
75
+
76
+ Runs before executing a verto command
77
+
78
+ ```ruby
79
+ # Vertofile
80
+
81
+ before {
82
+ puts "Before a command"
83
+ }
84
+ context(branch('master')) {
85
+ before {
86
+ puts "Before a command in master branch"
87
+ }
88
+ }
89
+ ```
90
+ ## after
91
+ Runs after executing a verto command
92
+
93
+ Example:
94
+ ```ruby
95
+ # Vertofile
96
+
97
+ after {
98
+ puts "After a command"
99
+ }
100
+ context(branch('master')) {
101
+ before {
102
+ puts "After a command in master branch"
103
+ }
104
+ }
105
+ ```
106
+
107
+ ## before_command_tag_up
108
+
109
+ Almost the same as before but run before the tag creation, the new tag can be accessible with as `new_version`
110
+
111
+ Example:
112
+ ```ruby
113
+ # Vertofile
114
+
115
+ before_tag_creation {
116
+ puts "New version is #{new_version}"
117
+ ...
118
+ }
119
+ ```
120
+
121
+ ## after_command_tag_up
122
+
123
+ The same as before_command_tag_up but run after the tag creation, the new tag can be accessible with as `new_version`
124
+
125
+ Example:
126
+ ```ruby
127
+ # Vertofile
128
+
129
+ after_tag_creation {
130
+ puts "New version is #{new_version}"
131
+ ...
132
+ }
133
+ ```
134
+
135
+ ## command_options
136
+
137
+ Allows you to set a specific option without the need to pass it explicity in the verto command (See `verto tag up --help` to see the options).
138
+
139
+ Example:
140
+ ```ruby
141
+ # Vertofile
142
+
143
+ context(branch('master')) {
144
+ before_command_tag_up {
145
+ command_options.add(filter: 'release_only')
146
+ }
147
+ ...
148
+ }
149
+
150
+ context(branch('staging')) {
151
+ before_command_tag_up {
152
+ command_options.add(pre_release: 'rc')
153
+ }
154
+ ...
155
+ }
156
+ ```
157
+
158
+ ## update_changelog
159
+
160
+ Start a flow to update the changelog (must be in `before_command_tag_up` or `after_command_tag_up)`
161
+
162
+ Options include:
163
+
164
+ * `:merged_pull_requests_with_bracketed_labels`: Uses all PR merged commits after the last tag if they have the [***] pattern
165
+ * `:commits_with_bracketed_labels` : Uses all commits after the last tag if they have the [***] pattern (Exclude merge commits)
166
+ * `:merged_pull_requests_messages` : Uses all merged commit after the last tag
167
+ * `:commit_messages`: Uses all commits after the last tag (Exclude merge commits)
168
+
169
+ Example:
170
+ ```ruby
171
+ # Vertofile
172
+ ...
173
+ context(branch('master')) {
174
+ before_tag_creation {
175
+ update_changelog(with: :merged_pull_requests_with_bracketed_labels,
176
+ confirmation: true, # Asks for confirmation (you can also edit the generated CHANGELOG)
177
+ filename: 'CHANGELOG.md')
178
+ git('add CHANGELOG.md')
179
+
180
+ git('commit -m "Updates CHANGELOG"')
181
+ }
182
+ }
183
+ ...
184
+ ```
185
+
186
+ ## file
187
+
188
+ Allows you to do some operations in a specific file.
189
+
190
+ Example:
191
+ ```ruby
192
+ # Vertofile
193
+ ...
194
+ context(branch('master')) {
195
+ before_tag_creation {
196
+ file('package.json').replace(/"(\d+)\.(\d+)\.(\d+)(-?.*)"/, %Q{"#{new_version}"})
197
+ git!('add package.json')
198
+
199
+ file('README.md').replace_all(latest_version.to_s, new_version.to_s)
200
+ git!('add README.md')
201
+ git!('commit -m "Bumps Version"')
202
+
203
+ file('versions_asc').append("#{new_version} - #{Time.now}")
204
+ file('versions_desc').prepend("#{new_version} - #{Time.now}")
205
+ }
206
+ }
207
+ ...
208
+ ```
209
+
210
+ ## env
211
+
212
+ Allows you to access a specifc environment variable
213
+
214
+ Example:
215
+ ```ruby
216
+ # Vertofile
217
+ ...
218
+ context(branch('staging')) {
219
+ before_tag_creation {
220
+ file('ci.log').append(env('CI_WORKER'))
221
+ ...
222
+ }
223
+ }
224
+ ...
225
+ ```
226
+
227
+ ## confirm
228
+
229
+ Ask for confirmation before executing anything
230
+
231
+ Example:
232
+ ```ruby
233
+ # Vertofile
234
+ ...
235
+ context(branch('master')) {
236
+ before_tag_creation {
237
+ confirm('Are you sure?')
238
+ ...
239
+ }
240
+ }
241
+ ...
242
+ ```
243
+
244
+ ## error
245
+
246
+ Sends an error to **stderr**
247
+
248
+ Example:
249
+ ```ruby
250
+ # Vertofile
251
+ ...
252
+ context(!branch('master')) {
253
+ error('Not at master')
254
+ }
255
+ ...
256
+ ```
257
+
258
+ ## error!
259
+
260
+ The same as error but exits verto (without creating a tag)
261
+
262
+ Example:
263
+ ```ruby
264
+ # Vertofile
265
+ ...
266
+ context(!branch('master')) {
267
+ error!('Not at master')
268
+ }
269
+ ...
270
+ ```
271
+
272
+ ## sh
273
+
274
+ Runs any shell command.
275
+
276
+ Example:
277
+ ```ruby
278
+ # Vertofile
279
+ ...
280
+ context(branch('master')) {
281
+ before_tag_creation {
282
+ ...
283
+ sh('bundle install')
284
+ sh('rake install')
285
+ git!('add Gemfile.lock')
286
+
287
+ git!('commit -m "Bumps Version"')
288
+ }
289
+ }
290
+ ...
291
+ ```
292
+
293
+ ## sh!
294
+
295
+ The same as sh but exits verto in case of errors
296
+
297
+ Example:
298
+ ```ruby
299
+ # Vertofile
300
+ ...
301
+ context(branch('master')) {
302
+ before_tag_creation {
303
+ ...
304
+ sh!('bundle install')
305
+ sh!('rake install')
306
+ git!('add Gemfile.lock')
307
+
308
+ git!('commit -m "Bumps Version"')
309
+ }
310
+ }
311
+ ...
312
+ ```
313
+
314
+ ## git
315
+
316
+ Runs git commands in verto
317
+
318
+ Example:
319
+ ```ruby
320
+ # Vertofile
321
+ ...
322
+ context(branch('master')) {
323
+ before_tag_creation {
324
+ ...
325
+ update_changelog
326
+ git('add CHANGELOG.md')
327
+ git('commit -m "Bumps Version"')
328
+ }
329
+ }
330
+ ...
331
+ ```
332
+
333
+ ## git!
334
+
335
+ The same as **git** but exits verto in case of errors
336
+
337
+ Example:
338
+ ```ruby
339
+ # Vertofile
340
+ ...
341
+ context(branch('master')) {
342
+ before_tag_creation {
343
+ ...
344
+ update_changelog
345
+ git!('add CHANGELOG.md')
346
+ git!('commit -m "Bumps Version"')
347
+ }
348
+ }
349
+ ...
350
+ ```
data/Vertofile CHANGED
@@ -1,4 +1,4 @@
1
- verto_version '0.7.0'
1
+ verto_version '0.12.0'
2
2
 
3
3
  config {
4
4
  version.prefix = 'v' # Adds a version_prefix
@@ -12,22 +12,7 @@ context(branch('master')) {
12
12
  }
13
13
 
14
14
  before_tag_creation {
15
- version_changes = ""
16
- bitbucket_changes = sh(
17
- %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
18
- ).output
19
- version_changes = bitbucket_changes
20
-
21
- puts "---------------------------"
22
- version_changes = "## #{new_version} - #{Time.now.strftime('%d/%m/%Y')}\n#{version_changes}\n"
23
- exit unless confirm("Create new Realease?\n" \
24
- "---------------------------\n" \
25
- "#{version_changes}" \
26
- "---------------------------\n"
27
- )
28
-
29
- # CHANGELOG
30
- file('CHANGELOG.md').prepend(version_changes)
15
+ update_changelog
31
16
  git!('add CHANGELOG.md')
32
17
 
33
18
  file('lib/verto/version.rb').replace(latest_version.to_s, new_version.to_s)
@@ -37,7 +22,9 @@ context(branch('master')) {
37
22
  git!('add README.md')
38
23
 
39
24
  file('lib/verto/utils/templates/Vertofile').replace(latest_version.to_s, new_version.to_s)
40
- git!('add lib/verto/utils/templates/Vertofile')
25
+ file('Vertofile').replace(latest_version.to_s, new_version.to_s)
26
+
27
+ git!('add Vertofile lib/verto/utils/templates/Vertofile')
41
28
 
42
29
  sh!('bundle install')
43
30
  sh!('rake install')
@@ -46,4 +33,3 @@ context(branch('master')) {
46
33
  git!('commit -m "Bumps Version"')
47
34
  }
48
35
  }
49
-
data/bin/console CHANGED
@@ -1,14 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "verto"
4
+ require 'bundler/setup'
5
+ require 'verto'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
8
9
 
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
10
+ require 'pry'
11
+ Pry.start
data/djin.yml ADDED
@@ -0,0 +1,50 @@
1
+ djin_version: '0.10.0'
2
+
3
+ tasks:
4
+ run:
5
+ local:
6
+ run:
7
+ - {{args}}
8
+
9
+ set_verto_version:
10
+ local:
11
+ run:
12
+ - VERTO_BUILD_VERSION=$(cat lib/verto/version.rb | grep -ohE '\d+\.\d+\.\d+')
13
+
14
+ tag_up:
15
+ docker:
16
+ image: "catks/verto:0.10.1"
17
+ run:
18
+ commands:
19
+ - "verto tag up {{args}}"
20
+ options: |
21
+ -v ~/.gitconfig:/etc/gitconfig -v $(pwd):/usr/src/project \
22
+ -v $HOME/.ssh/known_hosts:/root/.ssh/known_hosts -v $HOME/.ssh/id_rsa:/root/.ssh/id_rsa \
23
+ -e SSH_PRIVATE_KEY=/root/.ssh/id_rsa \
24
+ --entrypoint='' \
25
+ depends_on:
26
+ - set_verto_version
27
+
28
+ release:
29
+ depends_on:
30
+ - 'release:gem'
31
+ - 'release:docker'
32
+
33
+ 'release:gem':
34
+ local:
35
+ run:
36
+ - bundle exec rake release
37
+ depends_on:
38
+ - set_verto_version
39
+ - tag_up
40
+
41
+ 'release:docker':
42
+ local:
43
+ run:
44
+ - bundle exec rake release
45
+ - docker build . -t verto
46
+ - docker tag verto catks/verto:$VERTO_BUILD_VERSION
47
+ - docker push catks/verto:$VERTO_BUILD_VERSION
48
+ depends_on:
49
+ - set_verto_version
50
+ - tag_up
data/exe/verto CHANGED
@@ -1,17 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
- Signal.trap("INT") { exit 2 }
2
+ # frozen_string_literal: true
3
+
4
+ Signal.trap('INT') { exit 2 }
3
5
 
4
6
  require_relative '../lib/verto'
5
7
 
6
8
  vertofile_path = ENV['VERTOFILE_PATH'] || Pathname.new(Dir.pwd).join('Vertofile').to_s
7
9
  begin
8
- Verto::DSL.load_file(vertofile_path) if File.exists?(vertofile_path)
10
+ Verto::DSL.load_file(vertofile_path) if File.exist?(vertofile_path)
9
11
 
10
12
  Verto::MainCommand.start(ARGV)
11
13
 
14
+ # TODO: Check why we can't handle this error on CliHelpers
15
+ rescue TTY::Reader::InputInterrupt
12
16
  # TODO: Improve error Message Handling
13
- rescue Verto::ExitError => ex
14
- Verto.stderr.puts ex.message
17
+ rescue Verto::ExitError => e
18
+ Verto.stderr.puts e.message
15
19
  Verto.stderr.puts 'Exiting Verto...'
16
20
  exit 1
17
21
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
4
  class BaseCommand < Thor
3
5
  def self.exit_on_failure?
@@ -23,8 +25,11 @@ module Verto
23
25
 
24
26
  moments_to_call.each do |moment|
25
27
  Verto.config.hooks
26
- .select { |hook| hook.moment == moment.to_sym }
27
- .each { |hook| hook.call(with_attributes: with_attributes) }
28
+ .select { |hook| hook.moment == moment.to_sym }
29
+ .each do |hook|
30
+ Verto.current_moment = hook.moment
31
+ hook.call(with_attributes: with_attributes)
32
+ end
28
33
  end
29
34
  end
30
35
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Verto
2
4
  class MainCommand < BaseCommand
3
- desc "tag SUBCOMMAND ...ARGS", "manage the repository tags"
5
+ desc 'tag SUBCOMMAND ...ARGS', 'manage the repository tags'
4
6
  subcommand 'tag', Verto::TagCommand
5
7
 
6
- desc "init", "Initialize a Vertofile in your repository"
8
+ desc 'init', 'Initialize a Vertofile in your repository'
7
9
 
8
10
  option :path, type: :string, default: nil
9
11
  def init
@@ -14,7 +16,7 @@ module Verto
14
16
  Template.render('Vertofile', to: path)
15
17
  end
16
18
 
17
- desc "version", "Shows Verto version"
19
+ desc 'version', 'Shows Verto version'
18
20
 
19
21
  def version
20
22
  Verto.stdout.puts Verto::VERSION
@@ -23,12 +25,14 @@ module Verto
23
25
  private
24
26
 
25
27
  def validate_current_vertofile!(path)
28
+ return unless Pathname.new(path).join('Vertofile').exist?
29
+
26
30
  command_error!(
27
31
  <<~ERROR
28
- Project already have a Vertofile.
29
- If you want to generate a new with verto init, delete the current one with: `rm Vertofile`
32
+ Project already have a Vertofile.
33
+ If you want to generate a new with verto init, delete the current one with: `rm Vertofile`
30
34
  ERROR
31
- ) if Pathname.new(path).join('Vertofile').exist?
35
+ )
32
36
  end
33
37
  end
34
38
  end