release-notes 0.1.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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/.yardopts +6 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +179 -0
- data/Rakefile +9 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/generators/release/notes/install/install_generator.rb +20 -0
- data/lib/generators/release/notes/install/templates/README +11 -0
- data/lib/generators/release/notes/install/templates/release_notes.rb +20 -0
- data/lib/release/notes.rb +40 -0
- data/lib/release/notes/configuration.rb +210 -0
- data/lib/release/notes/date_format.rb +22 -0
- data/lib/release/notes/git.rb +33 -0
- data/lib/release/notes/link.rb +44 -0
- data/lib/release/notes/log.rb +99 -0
- data/lib/release/notes/pretty_print.rb +24 -0
- data/lib/release/notes/railtie.rb +15 -0
- data/lib/release/notes/system.rb +31 -0
- data/lib/release/notes/version.rb +7 -0
- data/lib/release/notes/with_configuration.rb +18 -0
- data/lib/release/notes/write.rb +72 -0
- data/lib/tasks/update_release_notes.rake +7 -0
- data/release-notes.gemspec +25 -0
- metadata +115 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 691d3c472f9792ce0e682085a84f2207f6a4fdda
|
|
4
|
+
data.tar.gz: bb273e2057859b3a70ffcf692ed6f442152df7d9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e056b89f89730bb42537f613e7dcb23363ee4ff25c74aecb54711882935cd2f29912b0a86ef4e3a4af7ea11d5012c55c371033f661b0248ec224b2bd0fb9601b
|
|
7
|
+
data.tar.gz: ed86f0d78b8f71c11e8f39766a3e92f403da70c6711e933b375d1c84c061bfffc903c325ea9b494395b817eff227bf5a36933256cf5bab09538c78ebe44a91c1
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.4.0
|
data/.travis.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
sudo: false
|
|
2
|
+
language: ruby
|
|
3
|
+
rvm:
|
|
4
|
+
- 2.4.0
|
|
5
|
+
before_install: gem install bundler -v 1.12.5
|
|
6
|
+
env:
|
|
7
|
+
global:
|
|
8
|
+
secure: ovawk+NnGZGW+hOeC3iPMZ9jKY5FvaxfHLj6XX4Vfe12cq0cdGYirW6pk2uKdJZdE0pC5q4sFv1ZTgcNSTySuNpQ9Gkp4xjcGEVr5JSdmVse8DuxttwkeSPt94DemyMK3f0A3dWN8OJF7/NQbacPeUuXryxmusCqJMlWccVYGeSQQNJ21mFfl2pCf6Z9qls4Q3rzXc4hsVQ5G1B/j9YcMjax0EwXI4cEq/6JadK4OmXrGkCw6M/wvBEqNyhLz+R/gcYiJZqYUETdncRuNiH8N6JKiaCnZUFkGY4bggpOvz29lj3JEQV9jY+3UBeqxuYj3glT7buEuf6//ARedY7IDlupkiDNuSpIKJhzIKAgitc/g+cnUflQV8PiImAEseO0OpoAJ7Bsa688EgyvMgo/kYwjHqZetvlUksQI+XyZ+o7/88LF2Qz4pbuBtdFC4DaKaeqQN5afIHSPtxhYwFA/n+GmY4jymj5ZWod9zZasVdlDgCQzgH5M1W7nEGun8mRW93wf8+3wAx+fXVbB67aDbqJFBJfH6zm/aBCN16kGkHUibRxUyb0F52woBQLUcOIr9Kbujp02D7IK3Z7PFz+DtHfA8aYRXxRDIHxx0tw91UxQzBinsq27kH8EWDmEKMHJeZlMRR4X4ijd6+KFoKUobXFblCeVeO0HCIBxpfTc39w=
|
|
9
|
+
after_success:
|
|
10
|
+
- bundle exec codeclimate-test-reporter
|
data/.yardopts
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Contributor Code of Conduct
|
|
2
|
+
|
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
|
7
|
+
|
|
8
|
+
We are committed to making participation in this project a harassment-free
|
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
|
12
|
+
|
|
13
|
+
Examples of unacceptable behavior by participants include:
|
|
14
|
+
|
|
15
|
+
* The use of sexualized language or imagery
|
|
16
|
+
* Personal attacks
|
|
17
|
+
* Trolling or insulting/derogatory comments
|
|
18
|
+
* Public or private harassment
|
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
|
20
|
+
addresses, without explicit permission
|
|
21
|
+
* Other unethical or unprofessional conduct
|
|
22
|
+
|
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
27
|
+
threatening, offensive, or harmful.
|
|
28
|
+
|
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
|
32
|
+
Conduct may be permanently removed from the project team.
|
|
33
|
+
|
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
|
35
|
+
when an individual is representing the project or its community.
|
|
36
|
+
|
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
38
|
+
reported by contacting a project maintainer at dvmonroe6@gmail.com. All
|
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
|
42
|
+
incident.
|
|
43
|
+
|
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
45
|
+
version 1.3.0, available at
|
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
|
47
|
+
|
|
48
|
+
[homepage]: http://contributor-covenant.org
|
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Specify your gem's dependencies in release-notes.gemspec
|
|
4
|
+
gemspec
|
|
5
|
+
|
|
6
|
+
group :test do
|
|
7
|
+
gem 'aruba', '~> 0.14.2'
|
|
8
|
+
gem 'codeclimate-test-reporter', require: false
|
|
9
|
+
gem 'pry-byebug', '~> 3.4.2'
|
|
10
|
+
gem 'rspec', '~> 3.6.0'
|
|
11
|
+
gem 'simplecov', require: false
|
|
12
|
+
end
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 Drew Monroe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Release::Notes
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/dvmonroe/release-notes)
|
|
4
|
+
[](https://codeclimate.com/github/dvmonroe/release-notes)
|
|
5
|
+
[](https://codeclimate.com/github/dvmonroe/release-notes/coverage)
|
|
6
|
+
[](http://inch-ci.org/github/dvmonroe/release-notes)
|
|
7
|
+
|
|
8
|
+
Release notes for the stakeholders.
|
|
9
|
+
|
|
10
|
+
Release::Notes is a small wrapper around your project's git log. The gem is
|
|
11
|
+
intended to help increase visability to all team members and stakeholders with
|
|
12
|
+
automated documentation of important changes made to your code base for a given production
|
|
13
|
+
deployment based on tags and labels in your commit messages.
|
|
14
|
+
|
|
15
|
+
Release::Notes is different than a changelog. It's meant for situations where other
|
|
16
|
+
team members (non-devs) in your organization need to know about key changes
|
|
17
|
+
to the production software. If your looking for a comprehnsive changelog that
|
|
18
|
+
reflects resolved github issues or logging all merges to your project, I would
|
|
19
|
+
suggest you look at something else like
|
|
20
|
+
[github-changelog-generator](https://github.com/skywinder/github-changelog-generator).
|
|
21
|
+
|
|
22
|
+
Not looking for a tested gem or prefer the rawness of a bash script? Checkout the similar
|
|
23
|
+
[bash implementation](https://gist.github.com/dvmonroe/300226a1ed4435fb38d72e72e1bbc5a0)
|
|
24
|
+
|
|
25
|
+
## Getting Started
|
|
26
|
+
|
|
27
|
+
Add this line to your application's Gemfile:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
gem 'release-notes'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
And then execute:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
$ bundle
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or install it yourself as:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
$ gem install release-notes
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
After you install Release::Notes, if you're using with rails, you can run the generator:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
$ rails generate release:notes:install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This Release::Notes generator creates an initializer file to allow further configuration.
|
|
52
|
+
|
|
53
|
+
If you're not in a rails project you can create the file yourself.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
## Configure
|
|
57
|
+
|
|
58
|
+
Override any of these defaults in `config/initializers/release_notes.rb`:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
Release::Notes.configure do |config|
|
|
62
|
+
config.output_file = './RELEASE_NOTES.md'
|
|
63
|
+
config.temp_file = './release-notes.tmp.md'
|
|
64
|
+
config.include_merges = false
|
|
65
|
+
config.ignore_case = true
|
|
66
|
+
config.log_format = '- %s'
|
|
67
|
+
config.extended_regex = true
|
|
68
|
+
config.bug_labels = %w[Fix Update]
|
|
69
|
+
config.feature_labels = %w[Add Create]
|
|
70
|
+
config.misc_labels = %w[Refactor]
|
|
71
|
+
config.bug_title = '**Fixed bugs:**'
|
|
72
|
+
config.feature_title = '**Implemented enhancements:**'
|
|
73
|
+
config.misc_title = '**Miscellaneous:**'
|
|
74
|
+
config.link_to_labels = %w[]
|
|
75
|
+
config.link_to_humanize = %w[]
|
|
76
|
+
config.link_to_sites = %w[]
|
|
77
|
+
config.timezone = 'America/New_York'
|
|
78
|
+
end
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For more information about each individual setting checkout Release::Notes's
|
|
82
|
+
[config docs](http://www.rubydoc.info/github/dvmonroe/release-notes/master/Release/Notes/Configuration).
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
### TL;DR
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
bundle exec update_release_notes:run
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Git Worklow
|
|
93
|
+
|
|
94
|
+
Release::Notes works best with a rebase workflow and requires tagging. General rebase benefits include:
|
|
95
|
+
|
|
96
|
+
* One clear commit per feature, bug or miscellaneous addition to the codebase
|
|
97
|
+
* Commits in logical time manner
|
|
98
|
+
|
|
99
|
+
By default configuration, Release::Notes ignores merges. Along with rebasing, by deafult,
|
|
100
|
+
Release::Notes relies mainly on the subject of a commit. Therefore, it's important to craft concise and
|
|
101
|
+
meaningful commit subjects with longer bodies as needed for larger feature additions or bug fixes.
|
|
102
|
+
|
|
103
|
+
For more information about a rebase workflow or crafting solid commit messages
|
|
104
|
+
check out the following links
|
|
105
|
+
|
|
106
|
+
* [Commit Messages](http://chris.beams.io/posts/git-commit/)
|
|
107
|
+
* [Git Rebase Workflow](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
|
|
108
|
+
|
|
109
|
+
### Deploying with Capistrano
|
|
110
|
+
|
|
111
|
+
If using Rails, a rake task is included and would be best utilized within your deploy script.
|
|
112
|
+
|
|
113
|
+
If not on rails, but using rake, you can easily craft your own rake task. At the very least calling
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
Release::Notes::Update.new.run
|
|
117
|
+
```
|
|
118
|
+
is the only instance that needs to be instantiated and invoked.
|
|
119
|
+
|
|
120
|
+
A sample capistrano production file might look something like this:
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
# config/deploy/production.rb
|
|
124
|
+
server 'the_name_for_my_server', user: 'deploy', roles: %w{app web}
|
|
125
|
+
|
|
126
|
+
set :application, 'my_app'
|
|
127
|
+
set :deploy_to, '/var/www/my_app'
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
namespace :deploy do
|
|
131
|
+
before :starting, :update_release_notes
|
|
132
|
+
|
|
133
|
+
task :update_release_notes do
|
|
134
|
+
sh 'RAILS_ENV=development bin/rake "update_release_notes:run"'
|
|
135
|
+
# run a second task that generates an auto commit
|
|
136
|
+
# this would be created by you
|
|
137
|
+
sh 'RAILS_ENV=development bin/rake "release_notes:commit"'
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Useful information can be found here regarding the
|
|
143
|
+
[capistrano flow](http://capistranorb.com/documentation/getting-started/flow/).
|
|
144
|
+
|
|
145
|
+
As you can see above, it's suggested that after generating your release notes you would
|
|
146
|
+
run an automated commit with a rake task like:
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
# lib/tasks/commit.rake
|
|
150
|
+
`git commit -am "Release to production #{Time.zone.now}"`
|
|
151
|
+
`git push origin master`
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
From there, make sure you tag your release after the deploy script runs so that your tag
|
|
155
|
+
includes this last commit.
|
|
156
|
+
|
|
157
|
+
## Note
|
|
158
|
+
|
|
159
|
+
* Your project must tag releases(release-notes uses the tag date to output the changes)
|
|
160
|
+
(PR's to make this more flexible are welcome)
|
|
161
|
+
* Linking is opinionated and will link to a URI structure of `#{site-url}/#{issue_number}`. It
|
|
162
|
+
will ouput something like: `[HONEYBADGER #33150353](https://app.honeybadger.io/projects/9999/faults/33150353)`.
|
|
163
|
+
This also means that your link_to_labels have to be something like `['HB #']` (PR's to make this more flexible are welcome)
|
|
164
|
+
|
|
165
|
+
## Development
|
|
166
|
+
|
|
167
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
168
|
+
|
|
169
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
170
|
+
|
|
171
|
+
## Contributing
|
|
172
|
+
|
|
173
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/dvmonroe/release-notes. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
179
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'release/notes'
|
|
6
|
+
require 'pry-byebug'
|
|
7
|
+
|
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
10
|
+
|
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
12
|
+
# require "pry"
|
|
13
|
+
# Pry.start
|
|
14
|
+
|
|
15
|
+
require 'irb'
|
|
16
|
+
IRB.start
|
data/bin/setup
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module Release
|
|
5
|
+
module Notes
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
9
|
+
|
|
10
|
+
def create_release_notes_initializer
|
|
11
|
+
copy_file 'release_notes.rb', 'config/initializers/release_notes.rb'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def display_readme
|
|
15
|
+
readme 'README'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
*******************************************************************************
|
|
2
|
+
|
|
3
|
+
Next step:
|
|
4
|
+
|
|
5
|
+
1. Configure release and tag options :
|
|
6
|
+
|
|
7
|
+
# config/initializers/release_notes.rb
|
|
8
|
+
config.by_tag_date = false
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
*******************************************************************************
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Release::Notes.configure do |config|
|
|
4
|
+
# config.output_file = './RELEASE_NOTES.md'
|
|
5
|
+
# config.temp_file = './release-notes.tmp.md'
|
|
6
|
+
# config.include_merges = false
|
|
7
|
+
# config.ignore_case = true
|
|
8
|
+
# config.log_format = '- %s'
|
|
9
|
+
# config.extended_regex = true
|
|
10
|
+
# config.bug_labels = %w[Fix Update]
|
|
11
|
+
# config.feature_labels = %w[Add Create]
|
|
12
|
+
# config.misc_labels = %w[Refactor]
|
|
13
|
+
# config.bug_title = '**Fixed bugs:**'
|
|
14
|
+
# config.feature_title = '**Implemented enhancements:**'
|
|
15
|
+
# config.misc_title = '**Miscellaneous:**'
|
|
16
|
+
# config.link_to_labels = %w[]
|
|
17
|
+
# config.link_to_humanize = %w[]
|
|
18
|
+
# config.link_to_sites = %w[]
|
|
19
|
+
# config.timezone = 'America/New_York'
|
|
20
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/core_ext/time'
|
|
5
|
+
|
|
6
|
+
require 'release/notes/date_format'
|
|
7
|
+
require 'release/notes/link'
|
|
8
|
+
require 'release/notes/pretty_print'
|
|
9
|
+
|
|
10
|
+
require 'release/notes/version'
|
|
11
|
+
require 'release/notes/configuration'
|
|
12
|
+
require 'release/notes/git'
|
|
13
|
+
require 'release/notes/system'
|
|
14
|
+
require 'release/notes/with_configuration'
|
|
15
|
+
|
|
16
|
+
require 'release/notes/write'
|
|
17
|
+
require 'release/notes/log'
|
|
18
|
+
|
|
19
|
+
require 'release/notes/railtie' if defined?(Rails)
|
|
20
|
+
|
|
21
|
+
module Release
|
|
22
|
+
module Notes
|
|
23
|
+
class Update
|
|
24
|
+
attr_reader :logger
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
@options = Release::Notes.configuration
|
|
28
|
+
@logger = Release::Notes::Log.new @options
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
logger.perform
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.root
|
|
37
|
+
File.expand_path('../..', __FILE__)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
class Configuration
|
|
6
|
+
# The absolute path of your generated log.
|
|
7
|
+
# Defaults to `./RELEASE_NOTES.md`.
|
|
8
|
+
# @return [String]
|
|
9
|
+
attr_accessor :output_file
|
|
10
|
+
|
|
11
|
+
# The absolute path of the temporary generated log.
|
|
12
|
+
# Defaults to `./release-notes.tmp.md`.
|
|
13
|
+
# @return [String]
|
|
14
|
+
attr_accessor :temp_file
|
|
15
|
+
|
|
16
|
+
# Determines whether to print commits with more than one parent.
|
|
17
|
+
# Defaults to `false`. For more, see
|
|
18
|
+
# [Git Log Docs](https://git-scm.com/docs/git-log)
|
|
19
|
+
# @return [Boolean]
|
|
20
|
+
attr_accessor :include_merges
|
|
21
|
+
|
|
22
|
+
# Match the regular expression limiting patterns without regard to letter case
|
|
23
|
+
# when printing your git log.
|
|
24
|
+
# Defaults to `true`. For more, see
|
|
25
|
+
# [Git Log Docs](https://git-scm.com/docs/git-log)
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
attr_accessor :ignore_case
|
|
28
|
+
|
|
29
|
+
# Consider the limiting patterns to be extended regular expressions patterns
|
|
30
|
+
# when printing your git log.
|
|
31
|
+
# Defaults to `true`. For more, see
|
|
32
|
+
# [Git Log Docs](https://git-scm.com/docs/git-log)
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
attr_accessor :extended_regex
|
|
35
|
+
|
|
36
|
+
# Allows you to specify what information you want to print from your git log
|
|
37
|
+
# Defaults to `%s` for subject. For more, see
|
|
38
|
+
# [Git Log Docs](https://git-scm.com/docs/git-log)
|
|
39
|
+
# @return [String]
|
|
40
|
+
attr_accessor :log_format
|
|
41
|
+
|
|
42
|
+
# Controls the labels grepped for in your commit subjects that will
|
|
43
|
+
# be add under you bug title
|
|
44
|
+
# Defaults to `%w(Fix Update)`.
|
|
45
|
+
# @return [Array]
|
|
46
|
+
attr_accessor :bug_labels
|
|
47
|
+
|
|
48
|
+
# Controls the labels grepped for in your commit subjects that will
|
|
49
|
+
# be add under you feature title
|
|
50
|
+
# Defaults to `%w(Add Create)`.
|
|
51
|
+
# @return [Array]
|
|
52
|
+
attr_accessor :feature_labels
|
|
53
|
+
|
|
54
|
+
# Controls the labels grepped for in your commit subjects that will
|
|
55
|
+
# be add under you miscellaneous title
|
|
56
|
+
# Defaults to `%w(Refactor)`.
|
|
57
|
+
# @return [Array]
|
|
58
|
+
attr_accessor :misc_labels
|
|
59
|
+
|
|
60
|
+
# Controls the title used in your generated log for all bugs listed
|
|
61
|
+
# Defaults to `**Fixed bugs:**`.
|
|
62
|
+
# @return [String]
|
|
63
|
+
attr_accessor :bug_title
|
|
64
|
+
|
|
65
|
+
# Controls the title used in your generated log for all features listed
|
|
66
|
+
# Defaults to `**Implemented enhancements:**`.
|
|
67
|
+
# @return [String]
|
|
68
|
+
attr_accessor :feature_title
|
|
69
|
+
|
|
70
|
+
# Controls the title used in your generated log for all misc commits listed
|
|
71
|
+
# Defaults to `**Miscellaneous:**`.
|
|
72
|
+
# @return [String]
|
|
73
|
+
attr_accessor :misc_title
|
|
74
|
+
|
|
75
|
+
# The labels grepped for in your commit subject that you want to linkify.
|
|
76
|
+
# The index within the array must match the index for the site
|
|
77
|
+
# in `:link_to_humanize` and `:link_to_sites`.
|
|
78
|
+
# Defaults to `[]`.
|
|
79
|
+
# @return [Array]
|
|
80
|
+
attr_accessor :link_to_labels
|
|
81
|
+
|
|
82
|
+
# The humanized output that you'd like to represent the associated `:link_to_label`
|
|
83
|
+
# The index within the array must match the index for the site
|
|
84
|
+
# in `:link_to_label` and `:link_to_sites`.
|
|
85
|
+
# Defaults to `[]`.
|
|
86
|
+
# @return [Array]
|
|
87
|
+
attr_accessor :link_to_humanize
|
|
88
|
+
|
|
89
|
+
# The url for the site that you'd like to represent the associated `:link_to_label`
|
|
90
|
+
# The index within the array must match the index for the site
|
|
91
|
+
# in `:link_to_label` and `:link_to_humanize`.
|
|
92
|
+
# Defaults to `[]`.
|
|
93
|
+
# @return [Array]
|
|
94
|
+
attr_accessor :link_to_sites
|
|
95
|
+
|
|
96
|
+
# Sets the timezone that should be used for setting the date.
|
|
97
|
+
# Defaults to `America/New_York`. For more, see
|
|
98
|
+
# [ActiveSupport Time Zones](http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html)
|
|
99
|
+
# @return [String]
|
|
100
|
+
attr_accessor :timezone
|
|
101
|
+
|
|
102
|
+
# Controls whether your commit subject labels should be removed from the final
|
|
103
|
+
# ouput of your message on the generated log.
|
|
104
|
+
# Defaults to `true`.
|
|
105
|
+
# @return [Boolean]
|
|
106
|
+
attr_accessor :prettify_messages
|
|
107
|
+
|
|
108
|
+
def initialize
|
|
109
|
+
@output_file = './RELEASE_NOTES.md'
|
|
110
|
+
@temp_file = './release-notes.tmp.md'
|
|
111
|
+
@include_merges = false
|
|
112
|
+
@ignore_case = true
|
|
113
|
+
@extended_regex = true
|
|
114
|
+
@log_format = '- %s'
|
|
115
|
+
@bug_labels = %w[Fix Update]
|
|
116
|
+
@feature_labels = %w[Add Create]
|
|
117
|
+
@misc_labels = %w[Refactor]
|
|
118
|
+
@bug_title = '**Fixed bugs:**'
|
|
119
|
+
@feature_title = '**Implemented enhancements:**'
|
|
120
|
+
@misc_title = '**Miscellaneous:**'
|
|
121
|
+
@link_to_labels = %w[]
|
|
122
|
+
@link_to_humanize = %w[]
|
|
123
|
+
@link_to_sites = %w[]
|
|
124
|
+
@timezone = 'America/New_York'
|
|
125
|
+
@prettify_messages = true
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# @return [String]
|
|
129
|
+
def include_merges?
|
|
130
|
+
@include_merges ? '' : '--no-merges'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# @return [String]
|
|
134
|
+
def regex_type
|
|
135
|
+
@extended_regex ? '-E' : ''
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# @return [String]
|
|
139
|
+
def grep_insensitive?
|
|
140
|
+
@ignore_case ? '-i' : ''
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @return [String]
|
|
144
|
+
def bugs
|
|
145
|
+
@bugs ||= generate_regex(@bug_labels)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# @return [String]
|
|
149
|
+
def features
|
|
150
|
+
@features ||= generate_regex(@feature_labels)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# @return [String]
|
|
154
|
+
def misc
|
|
155
|
+
@misc ||= generate_regex(@misc_labels)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# @return [String]
|
|
159
|
+
def all_labels
|
|
160
|
+
@all_labels ||= generate_regex(@bug_labels + @feature_labels + @misc_labels)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# @return [Boolean]
|
|
164
|
+
def release_notes_exist?
|
|
165
|
+
File.exist? output_file
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# @return [Boolean]
|
|
169
|
+
def link_commits?
|
|
170
|
+
link_to_labels.present? && link_to_humanize.present? &&
|
|
171
|
+
link_to_sites.present?
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @return [Boolean]
|
|
175
|
+
def prettify_messages?
|
|
176
|
+
@prettify_messages
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
private
|
|
180
|
+
|
|
181
|
+
# @api private
|
|
182
|
+
# Using over Regexp.union
|
|
183
|
+
def generate_regex(arr)
|
|
184
|
+
arr.join('|').insert(0, '(').insert(-1, ')')
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @return [Release::Notes::Configuration] Release::Notes's current configuration
|
|
189
|
+
def self.configuration
|
|
190
|
+
@configuration ||= Configuration.new
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Set Release::Notes's configuration
|
|
194
|
+
# @param config [Release::Notes::Configuration]
|
|
195
|
+
def self.configuration=(config)
|
|
196
|
+
@configuration = config
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Modify Release::Notes's current configuration
|
|
200
|
+
# @yieldparam [Release::Notes] config current Release::Notes config
|
|
201
|
+
# ```
|
|
202
|
+
# Release::Notes.configure do |config|
|
|
203
|
+
# config.routes = false
|
|
204
|
+
# end
|
|
205
|
+
# ```
|
|
206
|
+
def self.configure
|
|
207
|
+
yield configuration
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
class DateFormat
|
|
6
|
+
attr_reader :config, :time_now
|
|
7
|
+
delegate :timezone, to: :config
|
|
8
|
+
|
|
9
|
+
def initialize(config)
|
|
10
|
+
@config = config
|
|
11
|
+
Time.zone = timezone
|
|
12
|
+
|
|
13
|
+
@time_now = Time.zone.now
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def date_humanized(date: nil)
|
|
17
|
+
date = date.present? ? Time.zone.parse(date) : time_now
|
|
18
|
+
date.strftime('%B %d, %Y %r %Z')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
module Git
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
delegate :log_format, :grep_insensitive?, :regex_type, :include_merges?, to: :config
|
|
12
|
+
|
|
13
|
+
def log(**opts)
|
|
14
|
+
"git log '#{opts[:tag_from]}'..'#{opts[:tag_to]}' --grep='#{opts[:label]}'" \
|
|
15
|
+
" #{regex_type} #{grep_insensitive?}" \
|
|
16
|
+
" #{include_merges?} --format='#{log_format}'"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def last_tag
|
|
21
|
+
'git describe --abbrev=0 --tags'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def tag_date(tag)
|
|
25
|
+
"git log -1 --format=%ai #{tag}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def read_all_tags
|
|
29
|
+
'git tags | sort -u -r'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
module Link
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
delegate :link_to_labels, :link_to_sites, :link_to_humanize, to: :config
|
|
10
|
+
|
|
11
|
+
def link_lines(lines:)
|
|
12
|
+
new_lines = ''
|
|
13
|
+
lines.split("\n").each do |line|
|
|
14
|
+
unless link_to_labels.any? { |la| line.include? la }
|
|
15
|
+
new_lines += "#{line}\n"
|
|
16
|
+
next
|
|
17
|
+
end
|
|
18
|
+
link_to_labels.each_with_index do |label, i|
|
|
19
|
+
next unless line.include? label
|
|
20
|
+
words = line.split(/\s/)
|
|
21
|
+
words.each do |word|
|
|
22
|
+
next unless (word =~ /^#.*/)&.zero?
|
|
23
|
+
new_lines += "#{replace(line, word, label, i)}\n"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
new_lines
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# @api private
|
|
33
|
+
def replace(line, issue_number, label, index)
|
|
34
|
+
identifier = "#{label.split(/\s/)[0]} #{issue_number}"
|
|
35
|
+
humanized = "#{link_to_humanize[index]} #{issue_number}"
|
|
36
|
+
linked = "[#{humanized}](#{link_to_sites[index]})"
|
|
37
|
+
|
|
38
|
+
line.gsub! identifier, linked
|
|
39
|
+
line
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
class Log
|
|
6
|
+
include System
|
|
7
|
+
include WithConfiguration
|
|
8
|
+
|
|
9
|
+
attr_reader :config, :writer, :date_formatter
|
|
10
|
+
attr_reader :all_tags
|
|
11
|
+
|
|
12
|
+
delegate :all_labels, :features, :bugs, :misc, :feature_title,
|
|
13
|
+
:bug_title, :misc_title, :release_notes_exist?, to: :config
|
|
14
|
+
|
|
15
|
+
delegate :date_humanized, :format_tag_date, to: :date_formatter
|
|
16
|
+
delegate :digest, to: :writer
|
|
17
|
+
|
|
18
|
+
def initialize(config)
|
|
19
|
+
@config = config
|
|
20
|
+
|
|
21
|
+
setup_writer
|
|
22
|
+
setup_date_formatter
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def perform
|
|
26
|
+
if release_notes_exist?
|
|
27
|
+
# Find the last tag and group all commits
|
|
28
|
+
# under a date header at the time this is run
|
|
29
|
+
find_last_tag_and_log
|
|
30
|
+
else
|
|
31
|
+
# Find all tags and get the logs between each tag
|
|
32
|
+
# run this the first time if nothing exists
|
|
33
|
+
find_all_tags_and_log_all
|
|
34
|
+
end
|
|
35
|
+
writer.write_new_file
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def all_tags
|
|
41
|
+
@all_tags ||= System.all_tags.split("\n")
|
|
42
|
+
# return Error.new(msg: :missing_tags) unless all_tags.present?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @api private
|
|
46
|
+
def copy_single_tag_of_activity(tag_from:, tag_to: nil)
|
|
47
|
+
tag_to ||= 'HEAD'
|
|
48
|
+
[features, bugs, misc].each_with_index do |regex, i|
|
|
49
|
+
log = system_call(tag_from: tag_from, tag_to: tag_to, label: regex)
|
|
50
|
+
digest(date: nil, title: titles[i], log_message: log) if log.present?
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @api private
|
|
55
|
+
def find_last_tag_and_log
|
|
56
|
+
last_tag = system_last_tag.delete!("\n")
|
|
57
|
+
return false unless system_call(tag_from: last_tag, label: all_labels).present?
|
|
58
|
+
|
|
59
|
+
# output the date right now
|
|
60
|
+
digest date: date_humanized
|
|
61
|
+
copy_single_tag_of_activity(tag_from: last_tag)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @api private
|
|
65
|
+
def setup_writer
|
|
66
|
+
@writer = Release::Notes::Write.new config
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @api private
|
|
70
|
+
def setup_date_formatter
|
|
71
|
+
@date_formatter = Release::Notes::DateFormat.new config
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @api private
|
|
75
|
+
def find_all_tags_and_log_all
|
|
76
|
+
all_tags.each_with_index do |ta, i|
|
|
77
|
+
previous_tag = all_tags[i + 1]
|
|
78
|
+
next unless previous_tag.present? &&
|
|
79
|
+
system_call(tag_from: previous_tag, tag_to: ta, label: all_labels).present?
|
|
80
|
+
|
|
81
|
+
digest date: date_humanized(date: System.tag_date(tag: ta))
|
|
82
|
+
copy_single_tag_of_activity(tag_from: previous_tag, tag_to: ta)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @api private
|
|
87
|
+
def system_call(**opts)
|
|
88
|
+
with_config(config: config) do
|
|
89
|
+
system_log(opts)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @api private
|
|
94
|
+
def titles
|
|
95
|
+
[feature_title, bug_title, misc_title]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
module PrettyPrint
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
delegate :all_labels, to: :config
|
|
10
|
+
|
|
11
|
+
def prettify(line:)
|
|
12
|
+
line.gsub(labels_regex, '').strip
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# @api private
|
|
19
|
+
def labels_regex
|
|
20
|
+
Regexp.new all_labels, Regexp::IGNORECASE
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
class Railtie < Rails::Railtie
|
|
6
|
+
rake_tasks do
|
|
7
|
+
load 'tasks/update_release_notes.rake'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
generators do
|
|
11
|
+
require 'generators/release/notes/install/install_generator.rb'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
module System
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
include Git
|
|
10
|
+
|
|
11
|
+
included do
|
|
12
|
+
def system_log(**opts)
|
|
13
|
+
`#{log(opts)}`
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def all_tags
|
|
18
|
+
`#{Git.read_all_tags}`
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def system_last_tag
|
|
22
|
+
`#{Git.last_tag}`
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def tag_date(tag: nil)
|
|
26
|
+
tag ||= system_last_tag
|
|
27
|
+
`#{Git.tag_date(tag)}`
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
module WithConfiguration
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
attr_reader :config, :date_formatter
|
|
10
|
+
|
|
11
|
+
def with_config(**opts, &_block)
|
|
12
|
+
@confg = opts.fetch(:config, {})
|
|
13
|
+
yield
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Release
|
|
4
|
+
module Notes
|
|
5
|
+
class Write
|
|
6
|
+
include Link
|
|
7
|
+
include PrettyPrint
|
|
8
|
+
include WithConfiguration
|
|
9
|
+
|
|
10
|
+
attr_accessor :config
|
|
11
|
+
|
|
12
|
+
delegate :output_file, :temp_file, :link_commits?, :all_labels,
|
|
13
|
+
:prettify_messages?, :release_notes_exist?, to: :config
|
|
14
|
+
|
|
15
|
+
def initialize(config)
|
|
16
|
+
@config = config
|
|
17
|
+
# create a new temp file regardless if it exists
|
|
18
|
+
new_temp_file_template
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def digest(date: nil, title: nil, log_message: nil)
|
|
22
|
+
File.open(temp_file, 'a') do |fi|
|
|
23
|
+
fi << "\n\n## #{date}\n" if date
|
|
24
|
+
fi << "\n#{title}\n\n" if title && !date
|
|
25
|
+
fi << "#{title}\n\n" if title && date
|
|
26
|
+
|
|
27
|
+
break unless log_message
|
|
28
|
+
# link messages if needed
|
|
29
|
+
msg = link_message log_message
|
|
30
|
+
# remove tags if needed
|
|
31
|
+
msg = with_config(config: config) { prettify(line: msg) } if prettify_messages?
|
|
32
|
+
fi << "#{msg}\n"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# append old file to new temp file
|
|
37
|
+
# overwrite output file with tmp file
|
|
38
|
+
def write_new_file
|
|
39
|
+
copy_over_notes if release_notes_exist?
|
|
40
|
+
|
|
41
|
+
FileUtils.cp(temp_file, output_file)
|
|
42
|
+
FileUtils.rm temp_file
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# @api private
|
|
48
|
+
def copy_over_notes
|
|
49
|
+
File.open(temp_file, 'a') do |f|
|
|
50
|
+
f << "\n"
|
|
51
|
+
IO.readlines(output_file)[2..-1].each { |line| f << line }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @api private
|
|
56
|
+
def link_message(log_message)
|
|
57
|
+
return log_message unless link_commits?
|
|
58
|
+
with_config(config: config) do
|
|
59
|
+
link_lines(lines: log_message)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @api private
|
|
64
|
+
def new_temp_file_template
|
|
65
|
+
File.new(temp_file, 'w')
|
|
66
|
+
File.open(temp_file, 'a') do |fi|
|
|
67
|
+
fi << "# Release Notes\n----------------------"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'release/notes/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "release-notes"
|
|
8
|
+
spec.version = Release::Notes::VERSION
|
|
9
|
+
spec.authors = ["Drew Monroe"]
|
|
10
|
+
spec.email = ["dvmonroe6@gmail.com"]
|
|
11
|
+
|
|
12
|
+
spec.summary = "Release notes for stakeholders"
|
|
13
|
+
spec.description = spec.summary
|
|
14
|
+
spec.homepage = "http://github.com/dvmonroe/release-notes"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
+
spec.bindir = "exe"
|
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_dependency 'activesupport'
|
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: release-notes
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Drew Monroe
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-05-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.12'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.12'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '10.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '10.0'
|
|
55
|
+
description: Release notes for stakeholders
|
|
56
|
+
email:
|
|
57
|
+
- dvmonroe6@gmail.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- ".gitignore"
|
|
63
|
+
- ".rspec"
|
|
64
|
+
- ".ruby-version"
|
|
65
|
+
- ".travis.yml"
|
|
66
|
+
- ".yardopts"
|
|
67
|
+
- CODE_OF_CONDUCT.md
|
|
68
|
+
- Gemfile
|
|
69
|
+
- LICENSE.txt
|
|
70
|
+
- README.md
|
|
71
|
+
- Rakefile
|
|
72
|
+
- bin/console
|
|
73
|
+
- bin/setup
|
|
74
|
+
- lib/generators/release/notes/install/install_generator.rb
|
|
75
|
+
- lib/generators/release/notes/install/templates/README
|
|
76
|
+
- lib/generators/release/notes/install/templates/release_notes.rb
|
|
77
|
+
- lib/release/notes.rb
|
|
78
|
+
- lib/release/notes/configuration.rb
|
|
79
|
+
- lib/release/notes/date_format.rb
|
|
80
|
+
- lib/release/notes/git.rb
|
|
81
|
+
- lib/release/notes/link.rb
|
|
82
|
+
- lib/release/notes/log.rb
|
|
83
|
+
- lib/release/notes/pretty_print.rb
|
|
84
|
+
- lib/release/notes/railtie.rb
|
|
85
|
+
- lib/release/notes/system.rb
|
|
86
|
+
- lib/release/notes/version.rb
|
|
87
|
+
- lib/release/notes/with_configuration.rb
|
|
88
|
+
- lib/release/notes/write.rb
|
|
89
|
+
- lib/tasks/update_release_notes.rake
|
|
90
|
+
- release-notes.gemspec
|
|
91
|
+
homepage: http://github.com/dvmonroe/release-notes
|
|
92
|
+
licenses:
|
|
93
|
+
- MIT
|
|
94
|
+
metadata: {}
|
|
95
|
+
post_install_message:
|
|
96
|
+
rdoc_options: []
|
|
97
|
+
require_paths:
|
|
98
|
+
- lib
|
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - ">="
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0'
|
|
109
|
+
requirements: []
|
|
110
|
+
rubyforge_project:
|
|
111
|
+
rubygems_version: 2.6.10
|
|
112
|
+
signing_key:
|
|
113
|
+
specification_version: 4
|
|
114
|
+
summary: Release notes for stakeholders
|
|
115
|
+
test_files: []
|