keepachangelog_manager 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 77a5bbc658a38412711067bc833cbd9d46b2bef2
4
+ data.tar.gz: c4ab817a80b97bb93938e1b20f53ea5cc4a5870c
5
+ SHA512:
6
+ metadata.gz: 60d59c8034fa8ae6e546575859bfcd625a40977839eb9c71aa18f9c7e576a6ac83e9a1e45de7ae95ff092d108c35e796ba9ba47ed39c54f1d8a8c20d0c1d1c15
7
+ data.tar.gz: 04e47a37894d997698388616629f05640e01f2da4e5a1575f2523eb060d2c9e4d8de628ab4f555f635c04e7da0ecc9a8225e5cd4cbeda164e651c95a7bb5373d
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ lib/keepachangelog.rb lib/**/*.rb
data/README.md ADDED
@@ -0,0 +1,96 @@
1
+
2
+ # `keepachangelog_manager` Ruby gem for your CHANGELOG.md
3
+ [![Gem Version](https://badge.fury.io/rb/keepachangelog_manager.svg)](https://rubygems.org/gems/keepachangelog_manager)
4
+ [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/keepachangelog_manager/0.0.1)
5
+ [![Build Status](http://badges.herokuapp.com/travis/ianfixes/keepachangelog_manager_gem?label=build&branch=master)](https://travis-ci.org/ianfixes/keepachangelog_manager_gem)
6
+
7
+ If you follow the [Keep A Changelog](http://keepachangelog.com) `CHANGELOG.md` style, this gem automates the process of updating the file for a release.
8
+
9
+ Before:
10
+ ```markdown
11
+ # Change Log
12
+ All notable changes to this project will be documented in this file.
13
+
14
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
15
+ and this project adheres to [Semantic Versioning](http://semver.org/).
16
+
17
+ ## [Unreleased]
18
+ ### Added
19
+
20
+ ### Changed
21
+ * Everything
22
+
23
+ ### Deprecated
24
+
25
+ ### Removed
26
+
27
+ ### Fixed
28
+
29
+ ### Security
30
+
31
+
32
+ ## [0.0.1] - 2018-12-19
33
+ ### Added
34
+ * Initial stuff
35
+
36
+
37
+ [Unreleased]: https://github.com/ianfixes/keepachangelog_manager_gem/compare/v0.0.1...HEAD
38
+ [0.0.1]: https://github.com/ianfixes/keepachangelog_manager_gem/compare/v0.0.0...v0.0.1
39
+ ```
40
+
41
+ After running `bundle exec keepachangelog_release.md --increment-minor`:
42
+
43
+ ```markdown
44
+ # Change Log
45
+ All notable changes to this project will be documented in this file.
46
+
47
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
48
+ and this project adheres to [Semantic Versioning](http://semver.org/).
49
+
50
+ ## [Unreleased]
51
+ ### Added
52
+
53
+ ### Changed
54
+
55
+ ### Deprecated
56
+
57
+ ### Removed
58
+
59
+ ### Fixed
60
+
61
+ ### Security
62
+
63
+
64
+ ## [0.1.0] - 2019-01-23
65
+ ### Changed
66
+ * Everything
67
+
68
+
69
+ ## [0.0.1] - 2018-12-19
70
+ ### Added
71
+ * Initial stuff
72
+
73
+
74
+ [Unreleased]: https://github.com/ianfixes/keepachangelog_manager_gem/compare/v0.1.0...HEAD
75
+ [0.1.0]: https://github.com/ianfixes/keepachangelog_manager_gem/compare/v0.0.1...v0.1.0
76
+ [0.0.1]: https://github.com/ianfixes/keepachangelog_manager_gem/compare/v0.0.0...v0.0.1
77
+ ```
78
+
79
+
80
+ ## Installation In Your GitHub Project
81
+
82
+ Add the following to your `Gemfile`:
83
+
84
+ ```ruby
85
+ source 'https://rubygems.org'
86
+ gem 'keepachangelog'
87
+ ```
88
+
89
+ ## Author
90
+
91
+ This gem was written by Ian Katz (ianfixes@gmail.com) in 2019. It's released under the Apache 2.0 license.
92
+
93
+
94
+ ## See Also
95
+
96
+ * [Contributing](CONTRIBUTING.md)
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ require 'keepachangelog_manager'
3
+ require 'optparse'
4
+
5
+ # Use some basic parsing to allow command-line overrides of config
6
+ class Parser
7
+ def self.parse(options)
8
+ parsed_config = {}
9
+
10
+ opt_parser = OptionParser.new do |opts|
11
+ opts.banner = "Usage: #{File.basename(__FILE__)} <ONLY ONE of the following options>"
12
+
13
+ opts.on("--major=VERSION", "Upgrade major version to VERSION") do |p|
14
+ parsed_config[:abs_major] = p
15
+ end
16
+
17
+ opts.on("--minor=VERSION", "Upgrade minor version to VERSION") do |p|
18
+ parsed_config[:abs_minor] = p
19
+ end
20
+
21
+ opts.on("--patch=VERSION", "Upgrade patch version to VERSION") do |p|
22
+ parsed_config[:abs_patch] = p
23
+ end
24
+
25
+ opts.on("--increment-major", "Increment major version") do |v|
26
+ parsed_config[:inc_major] = v
27
+ end
28
+
29
+ opts.on("--increment-minor", "Increment minor version") do |v|
30
+ parsed_config[:inc_minor] = v
31
+ end
32
+
33
+ opts.on("--increment-patch", "Increment patch version") do |v|
34
+ parsed_config[:inc_patch] = v
35
+ end
36
+
37
+ opts.on("-h", "--help", "Prints this help") do
38
+ puts opts
39
+ exit
40
+ end
41
+ end
42
+
43
+ opt_parser.parse!(options)
44
+ parsed_config
45
+ end
46
+ end
47
+
48
+ # Read in command line options and make them read-only
49
+ @cli_options = (Parser.parse ARGV).freeze
50
+ Parser.parse %w[--help] if @cli_options.empty?
51
+
52
+ repo = KeepAChangelogManager::Repo.new(`git rev-parse --show-toplevel`.strip)
53
+ new_version = repo.changelog.update(@cli_options)
54
+ puts new_version
@@ -0,0 +1,9 @@
1
+ require "keepachangelog_manager/version"
2
+ require "keepachangelog_manager/repo"
3
+ require "keepachangelog_manager/exceptions"
4
+
5
+ # KeepAChangelogManager updates the sections of CHANGELOG.md according to keepachangelog.org rules
6
+ # @author Ian Katz <ianfixes@gmail.com>
7
+ module KeepAChangelogManager
8
+
9
+ end
@@ -0,0 +1,352 @@
1
+ require 'semver'
2
+ require 'git/remote/parser'
3
+ require 'date'
4
+
5
+ UNRELEASED = "Unreleased".freeze
6
+ DEFAULT_VERSION = "0.0.0".freeze
7
+ SECTION_ORDER = [:added, :changed, :deprecated, :removed, :fixed, :security].freeze
8
+ SECTION_NAME = {
9
+ added: "Added",
10
+ changed: "Changed",
11
+ deprecated: "Deprecated",
12
+ removed: "Removed",
13
+ fixed: "Fixed",
14
+ security: "Security",
15
+ }.freeze
16
+
17
+ module KeepAChangelogManager
18
+
19
+ # Handles all things related to a CHANGELOG.md
20
+ class Changelog
21
+
22
+ # Data Structure of a Changelog document:
23
+ # * Header (array of lines -- just the text, the title is predefined)
24
+ # * Release hash: key = semver (or :unreleased)
25
+ # * Date string (optional)
26
+ # * Section hash (order = )
27
+ # * array of lines
28
+ class ChangeData
29
+ # @return Array<String>
30
+ attr_accessor :header
31
+
32
+ # @return Hash
33
+ attr_accessor :releases
34
+
35
+ def initialize(header, releases)
36
+ @header = header
37
+ @releases = releases
38
+ end
39
+
40
+ # validate an attempted change to a version -- make sure no versions decrease
41
+ #
42
+ # @param version SemVer
43
+ # @param dimension Symbol
44
+ # @param newval Int
45
+ def validate(version, dimension, newval)
46
+ oldval = version.send(dimension)
47
+ raise ArgumentError, "Tried to set #{dimension} to #{newval}, which isn't greater than #{oldval}" unless newval > oldval
48
+ end
49
+
50
+ # Default "unreleased" structure
51
+ #
52
+ # @return Hash
53
+ def self.bare_unreleased_data
54
+ {
55
+ sections: Hash[SECTION_ORDER.map { |i| [i, []] }]
56
+ }
57
+ end
58
+
59
+ # content of a fresh (empty) changelog
60
+ #
61
+ # @return String
62
+ def self.bare
63
+ header_lines = [
64
+ "All notable changes to this project will be documented in this file.",
65
+ "",
66
+ "The format is based on [Keep a Changelog](http://keepachangelog.com/)",
67
+ "and this project adheres to [Semantic Versioning](http://semver.org/).",
68
+ ]
69
+ ChangeData.new(header_lines, UNRELEASED => self.bare_unreleased_data)
70
+ end
71
+
72
+ # Update a changelog by transforming Unreleased into a release
73
+ #
74
+ # Only one argument at a time should be supplied, all others nil
75
+ #
76
+ # @param inc_patch boolean whether to increment the patch version
77
+ # @param abs_patch int an absolute value for the patch version
78
+ # @param inc_minor boolean whether to increment the minor version
79
+ # @param abs_minor int an absolute value for the minor version
80
+ # @param inc_major boolean whether to increment the major version
81
+ # @param abs_major int an absolute value for the major version
82
+ # @return String the new version
83
+ def update(inc_patch: nil, abs_patch: nil,
84
+ inc_minor: nil, abs_minor: nil,
85
+ inc_major: nil, abs_major: nil)
86
+ num_args_supplied = binding.local_variables.count { |p| !binding.local_variable_get(p).nil? }
87
+ raise ArgumentError, "Only one update option should be specified" unless 1 == num_args_supplied
88
+
89
+ version = @releases.keys.reject { |k| k == UNRELEASED }.map { |k| SemVer.parse(k) }.max
90
+ version = SemVer.parse("0.0.0") if version.nil?
91
+
92
+ if !inc_patch.nil?
93
+ version.patch += 1
94
+ elsif !abs_patch.nil?
95
+ validate(version, :patch, abs_patch)
96
+ version.patch = abs_patch
97
+ elsif !inc_minor.nil?
98
+ version.minor += 1
99
+ version.patch = 0
100
+ elsif !abs_minor.nil?
101
+ validate(version, :minor, abs_minor)
102
+ version.minor = abs_minor
103
+ version.patch = 0
104
+ elsif !inc_major.nil?
105
+ version.major += 1
106
+ version.minor = 0
107
+ version.patch = 0
108
+ elsif !abs_major.nil?
109
+ validate(version, :major, abs_major)
110
+ version.major = abs_major
111
+ version.minor = 0
112
+ version.patch = 0
113
+ end
114
+
115
+ new_version = version.format("%M.%m.%p")
116
+ @releases[new_version] = @releases[UNRELEASED]
117
+ @releases[new_version][:date] = Date.today.strftime("%Y-%m-%d")
118
+ @releases[UNRELEASED] = self.class.bare_unreleased_data
119
+
120
+ new_version
121
+ end
122
+ end
123
+
124
+ # @return KeepAChangelog::Repo the repository
125
+ attr_accessor :repo
126
+
127
+ # @param path String path to CHANGELOG.md (or where it should be)
128
+ def initialize(repo)
129
+ @repo = repo
130
+ end
131
+
132
+ # Removes empty entries from the end of an array
133
+ #
134
+ # Works very much like string chomp
135
+ #
136
+ # @param lines Array<String>
137
+ # @return Array<String>
138
+ def array_chomp(lines)
139
+ return [] if lines.empty?
140
+ return [] if lines.all?(&:empty?)
141
+
142
+ last_entry = lines.rindex { |l| !l.strip.empty? }
143
+ lines[0..last_entry]
144
+ end
145
+
146
+ # whether the changelog exists in its supposed path
147
+ #
148
+ # @return boolean
149
+ def exist?
150
+ File.exist? @repo.changelog_path
151
+ end
152
+
153
+ # Create an empty CHANGELOG.md for this repo
154
+ #
155
+ # keepachangelog.com CHANGELOG.md syntax assumes git _and_ github.com
156
+ # so use that to our advantage: assume git repo exists.
157
+ #
158
+ # @return String
159
+ def create(force = false)
160
+ return if File.exist(@repo.changelog_path) && !force
161
+
162
+ File.open(@repo.changelog_path, 'w') { |file| file.write(bare_changelog) }
163
+ end
164
+
165
+ # Update a changelog in-place by transforming Unreleased into a release
166
+ #
167
+ # @see ChangeData.update
168
+ # @return String the new version
169
+ def update(**kwargs)
170
+ content = File.open(@repo.changelog_path, "r").read
171
+ data = parse(content)
172
+ new_version = data.update(**kwargs)
173
+ File.open(@repo.changelog_path, 'w') { |file| file.write(render(data)) }
174
+ new_version
175
+ end
176
+
177
+ # content of a fresh (empty) changelog
178
+ #
179
+ # @return String
180
+ def bare
181
+ render(ChangeData.bare)
182
+ end
183
+
184
+ # Sort section versions into a reverse-chronological array, unreleased first
185
+ #
186
+ # @param sections Hash the input
187
+ # @return Array<String> the sorted version strings
188
+ def version_order(releases)
189
+ # order sections in reverse chronological, unreleased on top
190
+ releases.keys.sort do |a, b|
191
+ next 0 if a == b
192
+ next -1 if a == UNRELEASED
193
+ next 1 if b == UNRELEASED
194
+
195
+ SemVer.parse(b) <=> SemVer.parse(a)
196
+ end
197
+ end
198
+
199
+ # Render the data structure to text
200
+ #
201
+ # @param data ChangeData
202
+ # @return String
203
+ def render(data)
204
+ render_lines(data).join("\n") + "\n"
205
+ end
206
+
207
+ # Render the data structure to an array of strings
208
+ #
209
+ # Output Structure of a Changelog document:
210
+ # * Header ("Change Log" and the text under it, up to the first '## ')
211
+ # * Release versions, reverse chronological, starting with 'unreleased'
212
+ # * Version (or unreleased) as a link to the diff
213
+ # * Date (optional)
214
+ # * Sections
215
+ # * Added
216
+ # * Changed
217
+ # * Deprecated
218
+ # * Removed
219
+ # * Fixed
220
+ # * Security
221
+ # * Diff URLs
222
+ #
223
+ # Assumes the "Unreleased" section is fleshed out, even if blank
224
+ #
225
+ # @param data ChangeData
226
+ # @return Array<String>
227
+ def render_lines(data)
228
+ # header
229
+ out_lines = ["# Change Log"] + data.header
230
+ out_lines << ""
231
+ out_lines << ""
232
+
233
+ # releases
234
+ versions = version_order(data.releases)
235
+ versions.each do |v|
236
+ release = data.releases[v]
237
+ out_lines << "## [#{v}]" + (v == UNRELEASED || release[:date].nil? ? "" : " - #{release[:date]}")
238
+
239
+ SECTION_ORDER.each do |s|
240
+ next unless release[:sections].key? s
241
+ next if release[:sections][s].empty? && v != UNRELEASED
242
+
243
+ section = release[:sections][s]
244
+ out_lines << "### #{SECTION_NAME[s]}"
245
+ out_lines += section
246
+ out_lines << ""
247
+ end
248
+ out_lines << ""
249
+ end
250
+
251
+ # links. unreleased will come first and may be the only one
252
+ versions.each_with_index do |v, i|
253
+ next_index = i + 1
254
+ this_version = v == UNRELEASED ? "HEAD" : "v#{v}"
255
+ prev_version = next_index < versions.length ? versions[next_index] : DEFAULT_VERSION
256
+ out_lines << "[#{v}]: https://github.com/#{@repo.owner}/#{@repo.name}/compare/v#{prev_version}...#{this_version}"
257
+ end
258
+
259
+ out_lines
260
+ end
261
+
262
+ # Parse an existing changelog (by path)
263
+ #
264
+ # @param changelog_text String path
265
+ # @return ChangeData
266
+ def parse_file(path)
267
+ parse(File.open(path, "r").read)
268
+ end
269
+
270
+ # Parse an existing changelog (delivered as a string)
271
+ #
272
+ # @param changelog_text String input
273
+ # @return ChangeData
274
+ def parse(changelog_text)
275
+ # allowable transitions
276
+ next_states = {
277
+ initial: [:header],
278
+ header: [:header, :release],
279
+ release: [:section],
280
+ section: [:section, :section_body, :release, :links],
281
+ section_body: [:section_body, :release, :links]
282
+ }
283
+ state = :initial
284
+
285
+ # signals for transitions, plus capture groups for params
286
+ transitions = {
287
+ header: /^# Change/,
288
+ release: /^## \[([^\]]+)\]( - (.*))?/,
289
+ section: /^### ([A-Z][a-z]+)/,
290
+ links: /^\[Unreleased\]: https:\/\/github\.com\//,
291
+ }
292
+
293
+ # parser state data
294
+ header_lines = []
295
+ releases = {}
296
+ last_version = nil
297
+ last_section = nil
298
+
299
+ changelog_text.lines.each do |l|
300
+ # find the regex that matches, no transition if no match
301
+ want_state, regex = transitions.find(proc { [nil, nil] }) { |_s, re| re.match(l) }
302
+ good_transition = want_state.nil? || next_states[state].include?(want_state)
303
+ raise ChangelogParseFail, "Changing to #{want_state} from #{state}" unless good_transition
304
+
305
+ want_param = regex.match(l) unless regex.nil?
306
+
307
+ # do any pre-transition bookkeeping
308
+ case want_state
309
+ when :initial
310
+ raise ChangelogParseFail, "Tried to transition back to initial state"
311
+ when :header
312
+ # nothing to do
313
+ when :release
314
+ version = want_param[1]
315
+ date = want_param[3]
316
+ releases[version] = { sections: {}, date: date }
317
+ last_version = version
318
+ last_section = nil
319
+ when :section
320
+ section_name = want_param[1]
321
+ section = SECTION_NAME.key(section_name)
322
+ raise ChangelogParseFail, "Unknown section name: '#{section_name}'" if section.nil?
323
+
324
+ releases[last_version][:sections][section] = []
325
+ last_section = section
326
+ when :links
327
+ break
328
+ else
329
+ # line is just a normal line. decide where we are and start appending
330
+
331
+ case state
332
+ when :header
333
+ header_lines << l.chomp
334
+ when :section
335
+ releases[last_version][:sections][last_section] << l.chomp
336
+ end
337
+ end
338
+ state = want_state unless want_state.nil?
339
+ end
340
+
341
+ releases.each do |version, release|
342
+ release[:sections].each do |section, lines|
343
+ releases[version][:sections][section] = array_chomp(lines)
344
+ end
345
+ end
346
+
347
+ ChangeData.new(array_chomp(header_lines), releases)
348
+ end
349
+
350
+ end # class
351
+
352
+ end # module
@@ -0,0 +1,10 @@
1
+ module KeepAChangelogManager
2
+ # If the code in question is not actually a git repository
3
+ class NoGitRepo < RuntimeError; end
4
+
5
+ # If the remote doesn't seem sane
6
+ class BadGitRepoUrl < RuntimeError; end
7
+
8
+ # If an existing changelog doesn't seem sane
9
+ class ChangelogParseFail < RuntimeError; end
10
+ end
@@ -0,0 +1,75 @@
1
+ require "keepachangelog_manager/exceptions"
2
+ require 'keepachangelog_manager/changelog'
3
+
4
+ module KeepAChangelogManager
5
+
6
+ # Handles all things related to a repository and its filesystem
7
+ class Repo
8
+
9
+ # @return String the repository root
10
+ attr_accessor :root
11
+
12
+ # Create a new Repo representing git repository, given its path
13
+ #
14
+ # @param root String path to root directory of repository
15
+ def initialize(root)
16
+ @root = root
17
+ end
18
+
19
+ # Get the repository name. It is assumed to be the name of the repo root directory
20
+ #
21
+ # keepachangelog.com CHANGELOG.md syntax assumes git _and_ github.com
22
+ # so use that to our advantage: assume git repo exists.
23
+ #
24
+ # @return String
25
+ def name
26
+ File.basename(@root)
27
+ end
28
+
29
+ # The git remote origin url
30
+ #
31
+ # @return String
32
+ def origin_url
33
+ `git remote get-url origin`
34
+ end
35
+
36
+ # Extract the owner from a git URL
37
+ #
38
+ # @param url String the URL (git:// or https://)
39
+ # @return String
40
+ def _owner_from_git_url(url)
41
+ parsed = Git::Remote::Parser.new.parse(url)
42
+ raise BadGitRepoUrl, "Could not parse '#{url}' as a git url" if parsed.nil?
43
+
44
+ parsed.owner
45
+ end
46
+
47
+ # Get the repo owner
48
+ #
49
+ # Assumes an "origin" url!
50
+ #
51
+ # @return String
52
+ def owner
53
+ Dir.chdir(@root) do
54
+ url = origin_url
55
+ raise NoGitRepo, "Could not find a git repo in '#{@root}'" if url.empty?
56
+
57
+ _owner_from_git_url(url)
58
+ end
59
+ end
60
+
61
+ # the path to the CHANGELOG.md file
62
+ #
63
+ # @return String
64
+ def changelog_path
65
+ File.join(@root, "CHANGELOG.md")
66
+ end
67
+
68
+ # A changelog object
69
+ #
70
+ # @return KeepAChangelog::Changelog
71
+ def changelog
72
+ Changelog.new(self)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module KeepAChangelogManager
2
+ VERSION = "0.0.1".freeze
3
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keepachangelog_manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ian Katz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: git-remote-parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: semver2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.15'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.15'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fakefs
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.18.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.18.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.59.2
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.59.2
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.9.11
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.9.11
111
+ description: ''
112
+ email:
113
+ - ianfixes@gmail.com
114
+ executables:
115
+ - keepachangelog_manager.rb
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".yardopts"
120
+ - README.md
121
+ - bin/keepachangelog_manager.rb
122
+ - lib/keepachangelog_manager.rb
123
+ - lib/keepachangelog_manager/changelog.rb
124
+ - lib/keepachangelog_manager/exceptions.rb
125
+ - lib/keepachangelog_manager/repo.rb
126
+ - lib/keepachangelog_manager/version.rb
127
+ homepage: http://github.com/ianfixes/keepachangelog_manager_gem
128
+ licenses:
129
+ - Apache-2.0
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.5.2.3
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: CHANGELOG.md (keepachangelog.com style) section updater for automated releasing
151
+ test_files: []