semmy 0.4.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e37930e9fb640ca1d09d44ad75a455267528fdcb
4
- data.tar.gz: d9b8a83c5b32ed68a8409b40107709676ec24aef
3
+ metadata.gz: e2863f4f726ca7e693eb807b85361216b13d6888
4
+ data.tar.gz: 25ea8f2c9cd7e1800e6b5aac5b183df255d2d8ef
5
5
  SHA512:
6
- metadata.gz: 97963c7d57e85aa7f04d94f0fbb9c3def74e5a387163f390e0764b8cff55ed2762693d3bafded2206f2fa5a5666c58b0a9a73eae1b27f3492e62a0adeb09c0ce
7
- data.tar.gz: bf42378f8c9817d88923613b9daab2c37fb96fae91ca1a262cc3f39fb9e3b2c58be477d6e758b04ddd4288e87ca26a761088431837422b015d467cca5fb17c5f
6
+ metadata.gz: 1182968ffa50bdc64b6023186cf8ef994dab8aa39c61c408a2822c2e07163860bba9f3b987911b47f613fb93eb61fb0267a104bbf7c10b03425d08a05501d4e2
7
+ data.tar.gz: e2fd0ec272420a10a2e4e8f2698e5120986eccec10b8c311b703a88ef1cf6e0402cf5c6187cfebb21669a178abf72b3cd8cc84006ab11455b4ede10e16cd9704
@@ -1,34 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
- ### Version 0.4.0
3
+ ### Version 1.0.0
4
4
 
5
5
  2017-07-13
6
6
 
7
- [Compare changes](https://github.com/tf/semmy/compare/0-3-stable...v0.4.0)
7
+ [Compare changes](https://github.com/tf/semmy/compare/0-x-stable...v1.0.0)
8
8
 
9
- - Only keep sections for current minor version in changelog and link
10
- to previous stable branch.
11
- - Compare minor versions to previous stable branch.
9
+ ##### Breaking Changes
12
10
 
13
- ### Version 0.3.0
11
+ - A typo in the name of the `changelog_unreleased_section_heading` and
12
+ `changelog_unreleased_section_blank_slate` options was fixed.
13
+ - The default value of `changelog_unreleased_section_heading` changed
14
+ to "Unreleased Changes". You need to update the header in your
15
+ changelog or manually set the previous value via the configuration option.
14
16
 
15
- 2016-09-09
17
+ ##### New Features
16
18
 
17
- [Compare changes](https://github.com/tf/semmy/compare/v0.2.0...v0.3.0)
19
+ - Add `bump:patch` task which begins a patch level release.
20
+ - Add `bump:mahor` task which updates the major version.
18
21
 
19
- - Fix default GitHub compare url.
20
- - Add link comparing to last patch level for stable release.
22
+ ##### Bug Fixes
21
23
 
22
- ### Version 0.2.0
24
+ - Fix indentation of generated unreleased changes section.
23
25
 
24
- 2016-06-09
25
-
26
- [Compare changes](https://github.com/tf/semmy/compare/v0.1.0...v0.2.0)
27
-
28
- - Fine tune default commit messages.
29
-
30
- ### Version 0.1.0
31
-
32
- 2016-06-09
33
-
34
- - Initial release
26
+ See
27
+ [0-x-stable branch](https://github.com/tf/semmy/blob/0-x-stable/CHANGELOG.md)
28
+ for previous changes.
data/README.md CHANGED
@@ -9,12 +9,52 @@
9
9
  An opinionated set of rake tasks to maintain gems following semantic
10
10
  versioning principles.
11
11
 
12
+ ## Assumptions
13
+
14
+ ### Git Branches and Tags
15
+
16
+ Development happens directly on `master` or by merging pull
17
+ requests. When a release is made, a stable branch called `x-y-stable`
18
+ is created. Semmy relies on Bundler's `release` task to create version
19
+ tags.
20
+
21
+ Patch level versions are released via backports to the stable
22
+ branches.
23
+
24
+ ### Version Suffix
25
+
26
+ The version in the gem's version file is increased in a separate
27
+ commit right after release. The version always has an `dev` suffix
28
+ (i.e. `1.1.0.dev`), which is only removed in the last commit
29
+ preparing the release. That way it is easy to see in a project's
30
+ `Gemfile.lock` whether an unreleased version is used.
31
+
32
+ Patch level versions are expected to be released immediately after
33
+ backporting bug fixes. So there are never commits with a version
34
+ suffix on stable branches.
35
+
36
+ ### Doc Tags
37
+
38
+ Pull requests introducing new features, are expected to markup new
39
+ code elements with a `@since edge` doc tag. When a release is
40
+ prepared, `edge` is replaced with the current version string. That way
41
+ pull request authors do not have to guess, which version will merge
42
+ their commits.
43
+
44
+ ### Changelog
45
+
46
+ Unreleased changes are listed in a section at the top. When preparing
47
+ a release this section is closed by placing a version heading above it
48
+ and inserting a compare link. Changelog entries for patch level
49
+ versions are only committed on the stable branches since they only
50
+ backport bug fixes from master.
51
+
12
52
  ## Installation
13
53
 
14
54
  Add development dependency to your gemspec:
15
55
 
16
56
  # your.gemspec
17
- s.add_development_dependency 'semmy', '~> 0.2'
57
+ s.add_development_dependency 'semmy', '~> 1.0'
18
58
 
19
59
  Install gems:
20
60
 
@@ -35,10 +75,11 @@ Semmy defines a new task to prepare a release:
35
75
 
36
76
  This task:
37
77
 
38
- * Removes the `dev` version suffix from the version file
39
- * Rewrites doc tags
78
+ * Ensures the gem can be installed.
79
+ * Removes the `dev` version suffix from the version file.
80
+ * Rewrites doc tags.
40
81
  * Closes the section of the new version in the changelog.
41
- * Commits the changes
82
+ * Commits the changes.
42
83
 
43
84
  It is expected that a `release` task exists. Normally this tasks is
44
85
  provided by Bundler.
@@ -48,67 +89,91 @@ provided by Bundler.
48
89
  Semmy registers additional actions which shall be
49
90
  executed right after the release:
50
91
 
51
- * Creates a stable branch
92
+ * Creates a stable branch.
52
93
  * Bumps the version to the next minor version with `alpha` version
53
94
  suffix.
54
- * Inserts an "Changes on master" section in the changelog.
95
+ * Inserts an "Unreleased Changes" section in the changelog.
55
96
 
56
- ## Assumptions
97
+ The resulting commit graph looks like:
57
98
 
58
- ### Git Branches and Tags
99
+ * (master) Bump version to 1.3.0.dev
100
+ * (v1.2.0, 1-2-stable) Prepare 1.2.0 release
101
+ * Some new feature
59
102
 
60
- Development happens directly on `master` or by merging pull
61
- requests. When a release is made, a stable branch called `x-y-stable`
62
- is created. Semmy relies on Bundler's `release` task to create version
63
- tags.
103
+ ### Releasing a Patch Level Version
64
104
 
65
- Patch level versions are released via backports to the stable
66
- branches.
105
+ Assume an important bug fix has been added to `master`:
67
106
 
68
- ### Version Suffix
107
+ * (master) Important bug fix
108
+ * First new feature
109
+ * Bump version to 1.3.0.dev
110
+ * (v1.0.0, 1-2-stable) Prepare 1.2.0 release
69
111
 
70
- The version in the gem's version file is increased in a separate
71
- commit right after release. The version always has an `alpha` suffix
72
- (i.e. `1.1.0.alpha`), which is only removed in the last commit
73
- preparing the release. That way it is easy to see in a project's
74
- `Gemfile.lock` whether an unreleased version is used.
112
+ check out the stable branch and cherry pick commits:
75
113
 
76
- Patch level versions are expected to be released immediately after
77
- backporting bug fixes. So there are never commits with a version
78
- suffix on stable branches.
114
+ $ git checkout 1-2-stable
115
+ $ git cherry-pick master
79
116
 
80
- ### Doc Tags
117
+ Then run:
81
118
 
82
- Pull requests introducing new features, are expected to markup new
83
- code elements with a `@since edge` doc tag. When a release is
84
- prepared, `edge` is replaced with the current version string. That way
85
- pull request authors do not have to guess, which version will merge
86
- their commits.
119
+ $ rake bump:patch
87
120
 
88
- ### Changelog
121
+ This task:
89
122
 
90
- Unreleased changes are listed in a section at the top. When preparing
91
- a release this section is closed by placing a version heading above it
92
- and inserting a compare link. Changelog entries for patch level
93
- versions are only committed on the stable branches since they only
94
- backport bug fixes from master.
123
+ * Bumps the version to `1.2.1` in the version file.
124
+ * Inserts an "Unreleased Changes" section in the changelog.
95
125
 
96
- ## Example Life Cycle
126
+ Add items to the new changelog section, then run:
97
127
 
98
- ### Releasing a Minor Version
128
+ $ rake release:prepare
99
129
 
100
- 1: * (master) Other important bug fix
101
- 2: * Minor bug fix
102
- 3: * First new feature
103
- 4: * Important bug fix
104
- 5: * Begin work on 1.1
105
- 6: | * (1-0-stable, v1.0.2) Prepare 1.0.2 release
106
- 7: | * Backport of other bug fix
107
- 8: | * (v1.0.1) Prepare 1.0.1 release
108
- 9: | * Backport of important bug fix
109
- 10: |/
110
- 11: * (v1.0.0) Prepare 1.0.0 release
130
+ This task detects that we are currently on a stable branch and
131
+ performs the following subset of the normal prepare tasks:
111
132
 
112
- ### Releasing a Patch Level Version
133
+ * Closes the section of the new version in the changelog.
134
+ * Commits the changes
135
+
136
+ You can now run `rake release`, leaving you with the following commit
137
+ graph:
138
+
139
+ * (master) Important bug fix
140
+ * First new feature
141
+ * Bump version to 1.3.0.dev
142
+ | * (v1.2.1, 1-2-stable) Prepare 1.2.1 release
143
+ | * Important bug fix
144
+ |/
145
+ * (v1.2.0) Prepare 1.2.0 release
146
+
147
+ ### Releasing a Major Version
148
+
149
+ If breaking changes have been merged to master, run:
150
+
151
+ $ rake bump:major
152
+
153
+ Assuming the version was `1.2.0.dev` before, This bumps the major
154
+ version in the version file to `2.0.0.dev` and updates the changelog
155
+ to reference `1-x-stable` for comparison.
156
+
157
+ The branch `1-x-stable` has to be created and managed manually. It
158
+ should always point to the same commit as the lastest minor version
159
+ stable branch of the major version.
160
+
161
+ The rest of the release can be performed like a normal minor version
162
+ release.
163
+
164
+ ## Development
165
+
166
+ After checking out the repo, run `bin/setup` to install
167
+ dependencies. You can also run `bin/console` for an interactive prompt
168
+ that will allow you to experiment. Run `bin/rspec` to execute the test
169
+ suite.
170
+
171
+ ## Contributing
172
+
173
+ Bug reports and pull requests are welcome on GitHub at
174
+ https://github.com/tf/semmy.
113
175
 
176
+ ## License
114
177
 
178
+ The gem is available as open source under the terms of the
179
+ [MIT License](http://opensource.org/licenses/MIT).
@@ -22,7 +22,7 @@ module Semmy
22
22
  private
23
23
 
24
24
  def unreleased_section_matcher
25
- /#{config.changelog_unrelased_section_heading}(\s*#{compare_link_matcher})?/
25
+ /#{config.changelog_unreleased_section_heading}(\s*#{compare_link_matcher})?/
26
26
  end
27
27
 
28
28
  def compare_link_matcher
@@ -72,7 +72,7 @@ module Semmy
72
72
 
73
73
  UpdateForMinor = Struct.new(:config, :options) do
74
74
  def call(contents)
75
- replace_starting_at(version_line_matcher,
75
+ replace_starting_at(Changelog.version_line_matcher(config),
76
76
  contents,
77
77
  unreleased_section)
78
78
  end
@@ -80,15 +80,26 @@ module Semmy
80
80
  private
81
81
 
82
82
  def unreleased_section
83
- <<-END.unindent
84
- #{config.changelog_unrelased_section_heading}
85
-
86
- #{compare_link_for_master}
87
-
88
- #{config.changelog_unrelased_section_blank_slate}
89
-
90
- #{link_to_changelog_on_previous_minor_stable_branch}
91
- END
83
+ # Once Ruby < 2.3 support is dropped, this can be rewritten
84
+ # as:
85
+ #
86
+ # <<~END
87
+ # #{config.changelog_unreleased_section_heading}
88
+ #
89
+ # #{compare_link_for_master}
90
+ #
91
+ # #{config.changelog_unreleased_section_blank_slate}
92
+ #
93
+ # #{link_to_changelog_on_previous_minor_stable_branch}
94
+ # END
95
+ #
96
+ # `unindent` cannot handle line breaks in interpolated values correctly.
97
+ [
98
+ config.changelog_unreleased_section_heading,
99
+ compare_link_for_master,
100
+ config.changelog_unreleased_section_blank_slate,
101
+ link_to_changelog_on_previous_minor_stable_branch
102
+ ].join("\n\n") << "\n"
92
103
  end
93
104
 
94
105
  def compare_link_for_master
@@ -112,12 +123,6 @@ module Semmy
112
123
  config.stable_branch_name)
113
124
  end
114
125
 
115
- def version_line_matcher
116
- Regexp.new(config.changelog_version_section_heading % {
117
- version: '([0-9.]+)'
118
- })
119
- end
120
-
121
126
  def replace_starting_at(line_matcher, text, inserted_text)
122
127
  unless text =~ line_matcher
123
128
  fail(InsertPointNotFound, 'Insert point not found.')
@@ -127,10 +132,52 @@ module Semmy
127
132
  end
128
133
  end
129
134
 
135
+ InsertUnreleasedSection = Struct.new(:config) do
136
+ def call(contents)
137
+ insert_before(Changelog.version_line_matcher(config),
138
+ contents,
139
+ config.changelog_unreleased_section_heading << "\n")
140
+ end
141
+
142
+ private
143
+
144
+ def insert_before(line_matcher, text, inserted_text)
145
+ text.dup.tap do |result|
146
+ unless (result.sub!(line_matcher, inserted_text + "\n\\0"))
147
+ fail(InsertPointNotFound,
148
+ 'Insert point not found.')
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ ReplaceMinorStableBranchWithMajorStableBranch = Struct.new(:config, :options) do
155
+ def call(contents)
156
+ contents.gsub(minor_stable_branch(options[:version]),
157
+ major_stable_branch(options[:version]))
158
+ end
159
+
160
+ private
161
+
162
+ def minor_stable_branch(version)
163
+ VersionString.previous_stable_branch_name(version, config.stable_branch_name)
164
+ end
165
+
166
+ def major_stable_branch(version)
167
+ config.stable_branch_name % VersionString.components(version).merge(minor: 'x')
168
+ end
169
+ end
170
+
130
171
  def version_tag(version)
131
172
  "v#{version}"
132
173
  end
133
174
 
175
+ def version_line_matcher(config)
176
+ Regexp.new(config.changelog_version_section_heading % {
177
+ version: '([0-9.]+)'
178
+ })
179
+ end
180
+
134
181
  def compare_link(config, interpolations)
135
182
  "[Compare changes](#{compare_url(config, interpolations)})"
136
183
  end
@@ -14,8 +14,8 @@ module Semmy
14
14
 
15
15
  attr_accessor :changelog_path
16
16
  attr_accessor :changelog_version_section_heading
17
- attr_accessor :changelog_unrelased_section_heading
18
- attr_accessor :changelog_unrelased_section_blank_slate
17
+ attr_accessor :changelog_unreleased_section_heading
18
+ attr_accessor :changelog_unreleased_section_blank_slate
19
19
  attr_accessor :changelog_previous_changes_link
20
20
 
21
21
  attr_accessor :source_files_with_docs_tags
@@ -34,8 +34,8 @@ module Semmy
34
34
 
35
35
  @changelog_path = 'CHANGELOG.md'
36
36
  @changelog_version_section_heading = '### Version %{version}'
37
- @changelog_unrelased_section_heading = '### Changes on `master`'
38
- @changelog_unrelased_section_blank_slate = 'None so far.'
37
+ @changelog_unreleased_section_heading = '### Unreleased Changes'
38
+ @changelog_unreleased_section_blank_slate = 'None so far.'
39
39
  @changelog_previous_changes_link = "See\n[%{branch} branch](%{url})\nfor previous changes."
40
40
 
41
41
  @source_files_with_docs_tags = '{app,lib}/**/*.{js,rb,scss}'
@@ -66,6 +66,16 @@ module Semmy
66
66
  task 'release' do
67
67
  Rake.application['release:after'].invoke
68
68
  end
69
+
70
+ task 'bump:patch' => [
71
+ 'semmy:versioning:bump_patch_level',
72
+ 'semmy:changelog:insert_unreleased_section'
73
+ ]
74
+
75
+ task 'bump:major' => [
76
+ 'semmy:changelog:replace_minor_stable_branch_with_major_stable_branch',
77
+ 'semmy:versioning:bump_major'
78
+ ]
69
79
  end
70
80
  end
71
81
  end
@@ -26,6 +26,23 @@ module Semmy
26
26
  version: Project.version,
27
27
  homepage: Gemspec.homepage))
28
28
  end
29
+
30
+ task 'replace_minor_stable_branch_with_major_stable_branch' do
31
+ Shell.info('Updating changelog ' \
32
+ "in #{config.changelog_path}.")
33
+
34
+ Files.rewrite(config.changelog_path,
35
+ Changelog::ReplaceMinorStableBranchWithMajorStableBranch
36
+ .new(config, version: Project.version))
37
+ end
38
+
39
+ task 'insert_unreleased_section' do
40
+ Shell.info('Inserting unreleased changes header ' \
41
+ "in #{config.changelog_path}.")
42
+
43
+ Files.rewrite(config.changelog_path,
44
+ Changelog::InsertUnreleasedSection.new(config))
45
+ end
29
46
  end
30
47
  end
31
48
  end
@@ -13,6 +13,15 @@ module Semmy
13
13
  rewrite_gemspec_version(new_version)
14
14
  end
15
15
 
16
+ task 'bump_major' do
17
+ new_version = VersionString
18
+ .bump_major(Project.version, config.development_version_suffix)
19
+
20
+ Shell.info("Bumping version to #{new_version}.")
21
+
22
+ rewrite_gemspec_version(new_version)
23
+ end
24
+
16
25
  task 'bump_minor' do
17
26
  new_version = VersionString
18
27
  .bump_minor(Project.version, config.development_version_suffix)
@@ -21,6 +30,15 @@ module Semmy
21
30
 
22
31
  rewrite_gemspec_version(new_version)
23
32
  end
33
+
34
+ task 'bump_patch_level' do
35
+ new_version = VersionString
36
+ .bump_patch_level(Project.version)
37
+
38
+ Shell.info("Bumping version to #{new_version}.")
39
+
40
+ rewrite_gemspec_version(new_version)
41
+ end
24
42
  end
25
43
  end
26
44
 
@@ -1,3 +1,3 @@
1
1
  module Semmy
2
- VERSION = '0.4.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -18,18 +18,16 @@ module Semmy
18
18
  new_version
19
19
  end
20
20
 
21
- def bump_minor(version, suffix)
22
- components = version.split('.')
23
-
24
- unless components.last =~ /^[0-9]+$/
25
- fail(UnexpectedSuffix, "Expected a version without suffix, found #{version}.")
26
- end
21
+ def bump_major(version, suffix)
22
+ [bump(0, version), suffix].join('.')
23
+ end
27
24
 
28
- components.map!(&:to_i)
29
- components[1] += 1
30
- components << suffix
25
+ def bump_minor(version, suffix)
26
+ [bump(1, version), suffix].join('.')
27
+ end
31
28
 
32
- components.join('.')
29
+ def bump_patch_level(version)
30
+ bump(2, version)
33
31
  end
34
32
 
35
33
  def minor_only(version)
@@ -70,17 +68,30 @@ module Semmy
70
68
 
71
69
  private
72
70
 
71
+ def bump(component_index, version)
72
+ components = version.split('.')[0..2].map!(&:to_i)
73
+
74
+ [
75
+ components[0...component_index],
76
+ components[component_index] + 1,
77
+ [0] * (2 - component_index)
78
+ ].flatten.join('.')
79
+ end
80
+
73
81
  def previous_minor_version_components(version)
74
82
  components = version.split('.').map(&:to_i)
75
83
 
76
84
  if components[1].zero?
77
- fail(NoPreviousMinor, "Cannot get previous minor version of #{version}.")
85
+ {
86
+ major: components[0] - 1,
87
+ minor: 'x'
88
+ }
89
+ else
90
+ {
91
+ major: components[0],
92
+ minor: components[1] - 1
93
+ }
78
94
  end
79
-
80
- {
81
- major: components[0],
82
- minor: components[1] - 1
83
- }
84
95
  end
85
96
  end
86
97
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semmy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Fischbach