releasinator 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99035e7fd8c9c4f656989abf3691c485f9e68bd8
4
- data.tar.gz: 6a473481db9b7a4f66195c70f398e0fbc0b6cc01
3
+ metadata.gz: 7c50b2ca2d8e7f05c2cfdcfb7e6277e88dbe9566
4
+ data.tar.gz: bff4e52e4c64da30a0100041af927320366b2263
5
5
  SHA512:
6
- metadata.gz: cc52ac52529e6437ffae30a61db4395eb2485e81d8d2e9825ea204decb16624dd03f2b5f71697232387639950c5694686417649f2a96bc258fd6cc7f544d2789
7
- data.tar.gz: 1383396a3df9378566522756524e3913f736ab582ebdb40382a4219da2c6298921fe61cbf70e298ee12751faa98b81d311cca8aa933bab341dbc694c10526f4a
6
+ metadata.gz: e59589a4510ae9d20c6c484c852b3d43968ff90c9eae075942ed7d11da245fce889f78208382ac649a6304cd76f74bddb9d62eb7eb4021fa312b2773d66dbd95
7
+ data.tar.gz: c7e3f660cf30e2d6d5db862a87dfe46f8027b40befd2a51869c8f1d1b4dcb8ecd694659b7425e9a1168999bd78c4b06873b0453a881bc3bcfa08542fa1646c28
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  Releasinator release notes
2
2
  ==========================
3
3
 
4
+ 0.6.2
5
+ -----
6
+ * Re-enable bullet punctuation detection, now handling multi-line comments correctly!
7
+ * Add new utility task, `import:changelog` for creating a changelog from a GitHub repo using the contents of existing GitHub releases.
8
+
4
9
  0.6.1
5
10
  -----
6
11
  * Improve some error messages.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- releasinator (0.6.1)
4
+ releasinator (0.6.2)
5
5
  colorize (~> 0.7)
6
6
  configatron (~> 4.5)
7
7
  json (~> 1.8)
data/README.md CHANGED
@@ -74,6 +74,8 @@ release
74
74
  --> docs:package
75
75
  --> docs:push
76
76
 
77
+ import:changelog (utility that creates a CHANGELOG.md.tmp from existing GitHub releases)
78
+
77
79
  ```
78
80
 
79
81
  ### Config
@@ -115,11 +117,12 @@ This will 'append' the task `validate:changelog`, running the code block after t
115
117
  The releasinator enforces certain conventions. If a filename closely matches the convention, it is renamed and automatically committed. The conventions are documented below:
116
118
 
117
119
  1. `README.md`
118
- 2. `LICENSE`: See [here](http://stackoverflow.com/questions/5678462/should-i-provide-a-license-txt-or-copying-txt-file-in-my-project) for a relevant StackOverflow post on this discussion. This project has chosen to exclude the `.txt` extension to match other popular projects, and GitHub defaults.
119
- 3. `CONTRIBUTING.md`: See [a relevant GitHub blog post](https://github.com/blog/1184-contributing-guidelines) for relevant information. This project has chosen to include the `.md` extension, as these files can get a bit unwieldy without formatting.
120
+ 2. `LICENSE`: See [here](http://stackoverflow.com/questions/5678462/should-i-provide-a-license-txt-or-copying-txt-file-in-my-project) for a relevant StackOverflow post on this discussion. The authors of this project have chosen to exclude the `.txt` extension to match other popular projects, and GitHub defaults.
121
+ 3. `CONTRIBUTING.md`: See [a relevant GitHub blog post](https://github.com/blog/1184-contributing-guidelines) for relevant information. The authors of this project have have chosen to include the `.md` extension, as these files can get a bit unwieldy without formatting.
120
122
  4. `CHANGELOG.md` - This file is the source of truth for the releasinator. The file should be organized with the most recent release on top, and formatted correctly. The latest release is the one used when the releasinator executes, so it is a precondition that the `CHANGELOG.md` has been edited and committed **prior to releasing**.
121
123
  1. Releases either are contained within an Alt-H2 (`------`) or `##H2` format. Any other format will be rejected.
122
124
  2. Each release MUST start with the release version, and may contain any following text, such as the date, and/or any release summary.
125
+ 5. `.gitignore` and `.DS_store`: While this file is Mac-specific, many repos contain this entry in their `.gitignore` files because it's quite common for developers to not have their global `.gitignore` configured correctly. Therefore, the authors of this project have made the decision to force this entry in all `.gitignores`, as a gesture of goodwill to all these new git users.
123
126
 
124
127
  ## Behind the Scenes
125
128
 
@@ -0,0 +1,43 @@
1
+ require_relative '../git_util'
2
+ require_relative '../command_processor'
3
+
4
+
5
+ module Releasinator
6
+ module Changelog
7
+ class Importer
8
+ def initialize(releasinator_config)
9
+ @releasinator_config = releasinator_config
10
+ end
11
+
12
+ def import(repo_url)
13
+ # create tempfile
14
+ File.open('CHANGELOG.md.tmp', 'w') do |f|
15
+ title_string = "#{@releasinator_config[:product_name]} release notes"
16
+ f.puts title_string
17
+
18
+ # print ====== with the length of the previous line for prettiness
19
+ title_string.length.times { f.print "=" }
20
+ f.puts
21
+
22
+ # read releases
23
+ github_repo = GitHubRepo.new(repo_url)
24
+
25
+ begin
26
+ github_releases = github_repo.client.releases "#{github_repo.org}/#{github_repo.repo}"
27
+ github_releases.each do |github_release|
28
+ puts github_release.inspect if @releasinator_config[:trace]
29
+ f.puts
30
+ f.puts github_release.name
31
+ f.puts "-----"
32
+ f.puts github_release.body
33
+ end
34
+ rescue => error
35
+ f.puts "<could not read releases from github>"
36
+ Printer.fail(error.inspect)
37
+ abort()
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,152 @@
1
+ require 'colorize'
2
+ require 'Vandamme'
3
+ require 'semantic'
4
+ require_relative "../current_release"
5
+ require_relative '../printer'
6
+
7
+ module Releasinator
8
+ module Changelog
9
+ class Validator
10
+ RELEASE_REGEX = /\d+\.\d+\.\d+/
11
+
12
+ def initialize(releasinator_config)
13
+ @releasinator_config = releasinator_config
14
+ end
15
+
16
+ # assume changelog_hash is not empty
17
+ def validate_semver(changelog_hash)
18
+ latest_release, latest_release_changelog = changelog_hash.first
19
+ # extract prefix from first release to use on all subsequent releases
20
+ latest_release_prefix = latest_release.partition(RELEASE_REGEX)[0]
21
+
22
+ newer_version = nil
23
+ changelog_hash.each do |key,value|
24
+ prefix, version, suffix = key.partition(RELEASE_REGEX)
25
+ puts "Checking version with prefix:'#{prefix}', version:'#{version}', suffix:'#{suffix}'." if @releasinator_config[:verbose]
26
+ if prefix != latest_release_prefix
27
+ Printer.fail("version #{key} does not start with extracted prefix '#{latest_release_prefix}'.")
28
+ abort()
29
+ end
30
+ older_version = Semantic::Version.new version
31
+
32
+ if nil != newer_version
33
+ version_comp = newer_version <=> older_version
34
+ if version_comp < 0
35
+ Printer.fail("Semver releases out of order: #{older_version} should be smaller than #{newer_version}")
36
+ abort()
37
+ elsif version_comp == 0
38
+ # this case cannot be found with Vandamme library because 2 versions in a row get overwritten in the underlying hash
39
+ if suffix.empty?
40
+ Printer.fail("2 semver releases in a row without a suffix (like -beta, -rc1, etc...) is not allowed.")
41
+ abort()
42
+ end
43
+ else
44
+ error_suffix = "version increment error - comparing #{newer_version} to #{older_version} does not pass semver validation."
45
+ # validate the next sequence in semver
46
+ if newer_version.major == older_version.major
47
+ if newer_version.minor == older_version.minor
48
+ check_semver_criteria(newer_version.patch == older_version.patch + 1, "patch #{error_suffix}")
49
+ else
50
+ check_semver_criteria(newer_version.minor == older_version.minor + 1 && newer_version.patch == 0, "minor #{error_suffix}")
51
+ end
52
+ else
53
+ check_semver_criteria(newer_version.major == older_version.major + 1 && newer_version.minor == 0 && newer_version.patch == 0, "major #{error_suffix}")
54
+ end
55
+ end
56
+ end
57
+ newer_version = older_version
58
+ end
59
+ end
60
+
61
+ def check_semver_criteria(condition, message)
62
+ if !condition
63
+ Printer.fail(message)
64
+ abort()
65
+ end
66
+ end
67
+
68
+ def validate_changelog_contents(changelog_contents)
69
+ version_header_regexes = [
70
+ ## h2 using --- separator. Example:
71
+ # 1.0.0
72
+ # -----
73
+ # First release!
74
+ '(^#{RELEASE_REGEX}).*\n----.*',
75
+
76
+ # h1/h2 header retrieved from https://github.com/tech-angels/vandamme/#format and modified to skip headers with dots in the name
77
+ '^#{0,3} ?([\w\d\.-]+\.[\d\.-]+[a-zA-Z0-9])(?: \W (\w+ \d{1,2}(?:st|nd|rd|th)?,\s\d{4}|\d{4}-\d{2}-\d{2}|\w+))?\n?[=-]*'
78
+ ]
79
+
80
+ changelog_hash = nil
81
+ version_header_regexes.each do |version_header_regex|
82
+ parser = Vandamme::Parser.new(changelog: changelog_contents, version_header_exp: version_header_regex, format: 'markdown')
83
+ changelog_hash = parser.parse
84
+
85
+ break if !changelog_hash.empty?
86
+ end
87
+
88
+ if changelog_hash.empty?
89
+ Printer.fail("Unable to find any releases in the CHANGELOG.md. Please check that your formatting is correct.")
90
+ abort()
91
+ end
92
+
93
+ Printer.success("Found " + changelog_hash.count.to_s.bold + " release(s) in CHANGELOG.md.")
94
+
95
+ validate_semver(changelog_hash)
96
+
97
+ changelog_hash.each { |release, changelog|
98
+ validate_single_changelog_entry(changelog)
99
+ }
100
+
101
+ latest_release, latest_release_changelog = changelog_hash.first
102
+ CurrentRelease.new(latest_release, latest_release_changelog)
103
+ end
104
+
105
+ def validate_single_changelog_entry(entry)
106
+ previous_line_in_progress = nil
107
+
108
+ lines = entry.chomp.split(/\r?\n/)
109
+ lines.each{ |line|
110
+
111
+ if starts_with_bullet? line
112
+ if previous_line_in_progress
113
+ Printer.fail("'#{previous_line_in_progress}' is invalid. Bulleted points should end in punctuation.")
114
+ abort()
115
+ elsif ends_with_punctuation? line
116
+ # self-contained line is a-ok, and the usual use-case
117
+ previous_line_in_progress = nil
118
+ else
119
+ # line starts with bullet, but did not end with punctuation
120
+ previous_line_in_progress = line
121
+ end
122
+ elsif previous_line_in_progress
123
+ # does not start with bullet, and is continuing from previous line
124
+ if ends_with_punctuation? line
125
+ # multi-line ending with punctuation is ok!
126
+ previous_line_in_progress = nil
127
+ else
128
+ # middle of multi-line - neither starts with bullet, nor ends with punctuation.
129
+ previous_line_in_progress = line
130
+ end
131
+ else
132
+ # don't care about empty or code lines interspersed in a changelog entry
133
+ end
134
+ }
135
+
136
+ # the last line may not be clean. Handle it.
137
+ if previous_line_in_progress
138
+ Printer.fail("'#{previous_line_in_progress}' is invalid. Bulleted points should end in punctuation.")
139
+ abort()
140
+ end
141
+ end
142
+
143
+ def starts_with_bullet?(line)
144
+ line.match /^\s*\*\s+.*$/
145
+ end
146
+
147
+ def ends_with_punctuation?(line)
148
+ line.match /.*[\!,\?:\.]$/
149
+ end
150
+ end
151
+ end
152
+ end
@@ -1,3 +1,3 @@
1
1
  module Releasinator
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
@@ -11,6 +11,7 @@ require_relative '../downstream'
11
11
  require_relative '../downstream_repo'
12
12
  require_relative '../publisher'
13
13
  require_relative '../validator'
14
+ require_relative '../changelog/importer.rb'
14
15
 
15
16
  include Releasinator
16
17
 
@@ -154,6 +155,13 @@ task :release => [:"validate:all",:"local:build",:"pm:all",:"downstream:all",:"l
154
155
  Printer.success("Done releasing.")
155
156
  end
156
157
 
158
+ namespace :import do
159
+ desc "import a changelog from release notes contained within GitHub releases"
160
+ task :changelog => [:config] do
161
+ Changelog::Importer.new(@releasinator_config).import(GitUtil.repo_url)
162
+ end
163
+ end
164
+
157
165
  namespace :local do
158
166
  desc "ask user whether to proceed with release"
159
167
  task :confirm => [:config, :"validate:changelog"] do
data/lib/validator.rb CHANGED
@@ -6,7 +6,7 @@ require_relative 'command_processor'
6
6
  require_relative 'downstream_repo'
7
7
  require_relative 'github_repo'
8
8
  require_relative 'printer'
9
- require_relative 'validator_changelog'
9
+ require_relative 'changelog/validator'
10
10
  require_relative 'releasinator/version'
11
11
 
12
12
  TEXT_FILE_EXTENSIONS = [
@@ -108,7 +108,7 @@ module Releasinator
108
108
  validate_exist(@releasinator_config.base_dir, "CHANGELOG.md", search_ignore_path, ["release_notes.md"])
109
109
 
110
110
  changelog_contents = get_changelog_contents
111
- ValidatorChangelog.new(@releasinator_config).validate_changelog_contents(changelog_contents)
111
+ Changelog::Validator.new(@releasinator_config).validate_changelog_contents(changelog_contents)
112
112
  end
113
113
 
114
114
  def validate_is_type(obj, type)
@@ -1,116 +1 @@
1
- require 'colorize'
2
- require 'Vandamme'
3
- require 'semantic'
4
- require_relative "current_release"
5
- require_relative 'printer'
6
1
 
7
- module Releasinator
8
- class ValidatorChangelog
9
-
10
- RELEASE_REGEX = /\d+\.\d+\.\d+/
11
-
12
- def initialize(releasinator_config)
13
- @releasinator_config = releasinator_config
14
- end
15
-
16
- # assume changelog_hash is not empty
17
- def validate_semver(changelog_hash)
18
- latest_release, latest_release_changelog = changelog_hash.first
19
- # extract prefix from first release to use on all subsequent releases
20
- latest_release_prefix = latest_release.partition(RELEASE_REGEX)[0]
21
-
22
- newer_version = nil
23
- changelog_hash.each do |key,value|
24
- prefix, version, suffix = key.partition(RELEASE_REGEX)
25
- puts "Checking version with prefix:'#{prefix}', version:'#{version}', suffix:'#{suffix}'." if @releasinator_config[:verbose]
26
- if prefix != latest_release_prefix
27
- Printer.fail("version #{key} does not start with extracted prefix '#{latest_release_prefix}'.")
28
- abort()
29
- end
30
- older_version = Semantic::Version.new version
31
-
32
- if nil != newer_version
33
- version_comp = newer_version <=> older_version
34
- if version_comp < 0
35
- Printer.fail("Semver releases out of order: #{older_version} should be smaller than #{newer_version}")
36
- abort()
37
- elsif version_comp == 0
38
- # this case cannot be found with Vandamme library because 2 versions in a row get overwritten in the underlying hash
39
- if suffix.empty?
40
- Printer.fail("2 semver releases in a row without a suffix (like -beta, -rc1, etc...) is not allowed.")
41
- abort()
42
- end
43
- else
44
- error_suffix = "version increment error - comparing #{newer_version} to #{older_version} does not pass semver validation."
45
- # validate the next sequence in semver
46
- if newer_version.major == older_version.major
47
- if newer_version.minor == older_version.minor
48
- check_semver_criteria(newer_version.patch == older_version.patch + 1, "patch #{error_suffix}")
49
- else
50
- check_semver_criteria(newer_version.minor == older_version.minor + 1 && newer_version.patch == 0, "minor #{error_suffix}")
51
- end
52
- else
53
- check_semver_criteria(newer_version.major == older_version.major + 1 && newer_version.minor == 0 && newer_version.patch == 0, "major #{error_suffix}")
54
- end
55
- end
56
- end
57
- newer_version = older_version
58
- end
59
- end
60
-
61
- def check_semver_criteria(condition, message)
62
- if !condition
63
- Printer.fail(message)
64
- abort()
65
- end
66
- end
67
-
68
- def validate_changelog_contents(changelog_contents)
69
- version_header_regexes = [
70
- ## h2 using --- separator. Example:
71
- # 1.0.0
72
- # -----
73
- # First release!
74
- '(^#{RELEASE_REGEX}).*\n----.*',
75
-
76
- # h1/h2 header retrieved from https://github.com/tech-angels/vandamme/#format and modified to skip headers with dots in the name
77
- '^#{0,3} ?([\w\d\.-]+\.[\d\.-]+[a-zA-Z0-9])(?: \W (\w+ \d{1,2}(?:st|nd|rd|th)?,\s\d{4}|\d{4}-\d{2}-\d{2}|\w+))?\n?[=-]*'
78
- ]
79
-
80
- changelog_hash = nil
81
- version_header_regexes.each do |version_header_regex|
82
- parser = Vandamme::Parser.new(changelog: changelog_contents, version_header_exp: version_header_regex, format: 'markdown')
83
- changelog_hash = parser.parse
84
-
85
- break if !changelog_hash.empty?
86
- end
87
-
88
- if changelog_hash.empty?
89
- Printer.fail("Unable to find any releases in the CHANGELOG.md. Please check that your formatting is correct.")
90
- abort()
91
- end
92
-
93
- Printer.success("Found " + changelog_hash.count.to_s.bold + " release(s) in CHANGELOG.md.")
94
-
95
- validate_semver(changelog_hash)
96
-
97
- changelog_hash.each { |release, changelog|
98
- validate_single_changelog_entry(changelog)
99
- }
100
-
101
- latest_release, latest_release_changelog = changelog_hash.first
102
- CurrentRelease.new(latest_release, latest_release_changelog)
103
- end
104
-
105
- def validate_single_changelog_entry(entry)
106
- lines = entry.split(/\r?\n/)
107
- lines.each{ |line|
108
- if line.match /^\s*\*\s+.*$/ # regex matches bulleted points
109
- if !line.match /^\s*\*\s+.*[\!,\?:\.]$/ # regex matches bullet points with punctuation
110
- Printer.fail("'#{line}' is invalid. Bulleted points should end in punctuation.")
111
- end
112
- end
113
- }
114
- end
115
- end
116
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: releasinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - PayPal
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-07-13 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -153,6 +153,8 @@ files:
153
153
  - LICENSE
154
154
  - README.md
155
155
  - Rakefile
156
+ - lib/changelog/importer.rb
157
+ - lib/changelog/validator.rb
156
158
  - lib/command_processor.rb
157
159
  - lib/config_hash.rb
158
160
  - lib/copy_file.rb