keepachangelog_manager 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []