keepachangelog 0.3.1 → 0.4.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 +4 -4
- data/.gitlab-ci.yml +11 -1
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +19 -5
- data/CONTRIBUTING.md +3 -2
- data/Gemfile.lock +1 -1
- data/LICENSE.md +18 -2
- data/README.md +20 -6
- data/changelog/0.4.0/5-yaml-files.yaml +4 -0
- data/changelog/0.4.0/7-numeric-order.yaml +4 -0
- data/changelog/0.4.0/share-with-public.yaml +3 -0
- data/changelog/0.4.1/8-fix-deploy.yaml +4 -0
- data/changelog/meta.yaml +1 -1
- data/features/help.feature +1 -1
- data/features/parser.feature +57 -0
- data/keepachangelog.gemspec +2 -2
- data/lib/keepachangelog.rb +5 -2
- data/lib/keepachangelog/cli.rb +54 -30
- data/lib/keepachangelog/parser.rb +11 -9
- data/lib/keepachangelog/parser/markdown.rb +31 -10
- data/lib/keepachangelog/parser/yaml.rb +6 -3
- data/lib/keepachangelog/printer.rb +4 -0
- data/lib/keepachangelog/{markdown_printer.rb → printer/markdown.rb} +16 -5
- data/lib/keepachangelog/printer/yaml.rb +79 -0
- data/package.json +2 -2
- data/spec/parser/markdown_spec.rb +20 -2
- data/spec/parser_spec.rb +2 -2
- data/spec/printer/markdown_spec.rb +36 -0
- data/spec/printer/yaml_spec.rb +81 -0
- data/spec/spec_helper.rb +0 -2
- metadata +14 -8
- data/features/markdown.feature +0 -43
- data/features/yaml.feature +0 -17
- data/spec/markdown_printer_spec.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e63e90c5940db3033ddb2f4e58e77437af51e43
|
4
|
+
data.tar.gz: 8f30352f336656f66229df3eba5abbb4e2924149
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d332fc8dc0d944376a22d7419a8e31aff436e89b18c533d5e3f1c26d8639b8c9cbb3b6a57ee5083120869d82e5628b8f2e841dedcac29c5324bf15c10fd4a20
|
7
|
+
data.tar.gz: 2bf95c69b9f25c988c53f193735ef3fa254a2d81dd6be3e663c77cf2e7bd3c5909cc981a06f9828572384462a0efa5fd1c508082245a5eff661e0a81c16cf3cb
|
data/.gitlab-ci.yml
CHANGED
@@ -40,10 +40,15 @@ integration:
|
|
40
40
|
script:
|
41
41
|
- "grunt test:integration"
|
42
42
|
|
43
|
-
|
43
|
+
fileshare:
|
44
44
|
stage: deploy
|
45
45
|
environment: production
|
46
46
|
script:
|
47
|
+
- |
|
48
|
+
if [[ "$SSH_KEY" == "" || "$SSH_USER" == "" || "$TARGET_HOST" == "" || "$TARGET_PATH" == "" ]]; then
|
49
|
+
echo "Skipping deploy due to missing credentials"
|
50
|
+
exit 0
|
51
|
+
fi
|
47
52
|
- grunt publish
|
48
53
|
only:
|
49
54
|
- tags
|
@@ -52,6 +57,11 @@ rubygems.org:
|
|
52
57
|
stage: deploy
|
53
58
|
environment: production
|
54
59
|
script:
|
60
|
+
- |
|
61
|
+
if [[ "$RUBYGEMS_API_KEY" == "" ]]; then
|
62
|
+
echo "Skipping deploy due to missing credentials"
|
63
|
+
exit 0
|
64
|
+
fi
|
55
65
|
- mkdir -p ~/.gem
|
56
66
|
- "echo \":rubygems_api_key: $RUBYGEMS_API_KEY\" > ~/.gem/credentials"
|
57
67
|
- chmod 0600 /root/.gem/credentials
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.4.1]
|
8
|
+
### Fixed
|
9
|
+
- Deploy job in CI will no longer be skipped even though it should run. (#8)
|
10
|
+
|
11
|
+
## [0.4.0] - 2017-03-30
|
12
|
+
### New
|
13
|
+
- Ability to output changelog to yaml file structure. (!9)
|
14
|
+
- The code is pushed into a public repo at gitlab.com.
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
- Sort versions in reverse numerical order in Markdown output. (#7)
|
18
|
+
|
7
19
|
## [0.3.1] - 2017-03-27
|
8
20
|
### Fixed
|
9
21
|
- Remove duplicates in Changelog for this project. (#6)
|
@@ -31,8 +43,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
31
43
|
- Tool for reading Changelog in Markdown format.
|
32
44
|
- Ability to convert Changelog to YAML.
|
33
45
|
|
34
|
-
[0.
|
35
|
-
[0.
|
36
|
-
[0.
|
37
|
-
[0.
|
38
|
-
[0.1
|
46
|
+
[0.4.1]: https://gitlab.com/ephracis/keepachangelog/compare/0.4.0...0.4.1
|
47
|
+
[0.4.0]: https://gitlab.com/ephracis/keepachangelog/compare/0.3.1...0.4.0
|
48
|
+
[0.3.1]: https://gitlab.com/ephracis/keepachangelog/compare/0.3.0...0.3.1
|
49
|
+
[0.3.0]: https://gitlab.com/ephracis/keepachangelog/compare/0.2.1...0.3.0
|
50
|
+
[0.2.1]: https://gitlab.com/ephracis/keepachangelog/compare/0.2.0...0.2.1
|
51
|
+
[0.2.0]: https://gitlab.com/ephracis/keepachangelog/compare/0.1.0...0.2.0
|
52
|
+
[0.1.0]: https://gitlab.com/ephracis/keepachangelog/compare/77986bc...0.1.0
|
data/CONTRIBUTING.md
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
You can help out in several ways:
|
2
|
+
- File or discuss issues
|
3
|
+
- Send merge requests
|
data/Gemfile.lock
CHANGED
data/LICENSE.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
-
Copyright ©
|
1
|
+
Copyright © 2017 Basalt
|
2
2
|
|
3
|
-
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
+
[](https://gitlab.com/ephracis/keepachangelog/commits/master)
|
2
|
+
[](https://gitlab.com/ephracis/keepachangelog/commits/master)
|
3
|
+
[](https://badge.fury.io/rb/keepachangelog)
|
4
|
+
|
1
5
|
# Changelog parser and transformer
|
2
6
|
|
3
7
|
Ruby gem for parsing Changelogs based on the format described at
|
4
8
|
[keepachangelog.com](http://keepachangelog.com).
|
5
9
|
|
6
10
|
The parser can read either a Markdown file or a folder structure with
|
7
|
-
YAML
|
11
|
+
YAML files.
|
8
12
|
|
9
|
-
The output can be Markdown, YAML or JSON.
|
13
|
+
The output can be Markdown, YAML files or JSON.
|
10
14
|
|
11
15
|
## Installation
|
12
16
|
|
@@ -28,17 +32,26 @@ Or install it yourself as:
|
|
28
32
|
|
29
33
|
### Command line
|
30
34
|
|
35
|
+
When using the parser there are four important options to pay attention to:
|
36
|
+
- `from` - The input format
|
37
|
+
- `to` - The output format
|
38
|
+
- `in` - The input file or folder
|
39
|
+
- `out` - The output folder (only used when output format is `yaml`)
|
40
|
+
|
41
|
+
See `keepachangelog help parse` for more information.
|
42
|
+
|
31
43
|
#### Markdown input
|
32
44
|
To dump a Changelog to JSON run the following command:
|
33
45
|
|
34
|
-
keepachangelog --
|
46
|
+
keepachangelog --in CHANGELOG.md --from md --to json
|
35
47
|
|
36
48
|
#### YAML input
|
37
49
|
You can also express your changelog in YAML files inside a folder structure
|
38
50
|
where each version is its own folder containing each change in a YAML-file.
|
39
51
|
|
40
52
|
Here's an example of a folder structure:
|
41
|
-
|
53
|
+
|
54
|
+
```shell
|
42
55
|
changelog
|
43
56
|
├── 0.1.0
|
44
57
|
│ └── 1-first-merge-request.yaml
|
@@ -63,14 +76,15 @@ type: New
|
|
63
76
|
```
|
64
77
|
|
65
78
|
|
66
|
-
- `title`: A single sentence
|
79
|
+
- `title`: A single sentence that describes the change
|
67
80
|
- `merge_request`: The ID of the MR or PR (optional)
|
68
81
|
- `issue`: The ID of the issue (optional)
|
69
82
|
- `author`: The author of the change (optional)
|
70
83
|
- `type`: The type of change, for example *New*, *Changed*, *Fixed*,
|
71
84
|
*Removed* or *Security*.
|
72
85
|
|
73
|
-
To turn this into a Markdown document, simply run
|
86
|
+
To turn this into a Markdown document, simply run
|
87
|
+
`keepachangelog --in ./changelog --from yaml --to md`
|
74
88
|
|
75
89
|
You can add meta data to your changelog in the file `meta.yaml`, placed inside
|
76
90
|
the changelog folder, like so:
|
data/changelog/meta.yaml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
url: https://
|
2
|
+
url: https://gitlab.com/ephracis/keepachangelog
|
data/features/help.feature
CHANGED
@@ -8,5 +8,5 @@ Feature: Show help
|
|
8
8
|
Then the output should contain "Keepachangelog commands"
|
9
9
|
|
10
10
|
Scenario: Getting help about a command
|
11
|
-
When I successfully run `keepachangelog help
|
11
|
+
When I successfully run `keepachangelog help parse`
|
12
12
|
Then the output should contain "Usage"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Feature: Parse changelogs
|
2
|
+
|
3
|
+
Parse a changelog by running `keepachangelog parse` or just simply
|
4
|
+
`keepachangelog`.
|
5
|
+
|
6
|
+
Scenario: Convert from Markdown to JSON
|
7
|
+
Given a file "CHANGELOG.md" with:
|
8
|
+
"""
|
9
|
+
# My Changes
|
10
|
+
Some intro goes here.
|
11
|
+
## [Unreleased]
|
12
|
+
### New
|
13
|
+
- Feature A
|
14
|
+
"""
|
15
|
+
When I successfully run `keepachangelog --from md --to json --in CHANGELOG.md`
|
16
|
+
Then the output should contain:
|
17
|
+
"""
|
18
|
+
{"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}},"intro":"Some intro goes here.","title":"My Changes"}
|
19
|
+
"""
|
20
|
+
|
21
|
+
Scenario: Convert from YAML files to Markdown
|
22
|
+
Given a file "changelog/1.0.0/1.yml" with:
|
23
|
+
"""
|
24
|
+
---
|
25
|
+
title: Feature A
|
26
|
+
type: New
|
27
|
+
"""
|
28
|
+
When I successfully run `keepachangelog --from yaml --to md`
|
29
|
+
Then the output should contain:
|
30
|
+
"""
|
31
|
+
# Change log
|
32
|
+
All notable changes to this project will be documented in this file.
|
33
|
+
|
34
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
35
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
36
|
+
|
37
|
+
## 1.0.0
|
38
|
+
### New
|
39
|
+
- Feature A.
|
40
|
+
"""
|
41
|
+
|
42
|
+
Scenario: Convert from Markdown to YAML files
|
43
|
+
Given a file "CHANGELOG.md" with:
|
44
|
+
"""
|
45
|
+
# My Changes
|
46
|
+
Some intro goes here.
|
47
|
+
## [Unreleased]
|
48
|
+
### New
|
49
|
+
- Feature A
|
50
|
+
"""
|
51
|
+
When I successfully run `keepachangelog --from md --to yaml --in CHANGELOG.md --out test`
|
52
|
+
Then the file "test/Unreleased/feature-a.yaml" should contain:
|
53
|
+
"""
|
54
|
+
---
|
55
|
+
title: Feature A
|
56
|
+
type: New
|
57
|
+
"""
|
data/keepachangelog.gemspec
CHANGED
@@ -14,12 +14,12 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.version = Keepachangelog.version
|
15
15
|
spec.authors = ['Basalt AB']
|
16
16
|
spec.email = %w(christoffer.brodd-reijer@basalt.se)
|
17
|
-
spec.licenses = ['
|
17
|
+
spec.licenses = ['MIT']
|
18
18
|
spec.summary = 'Parser for changelogs based on keepachangelog.com'
|
19
19
|
spec.description = 'Tool for parsing changelogs that are based on the '\
|
20
20
|
'keepachangelog.com standard. Changelogs can be dumped '\
|
21
21
|
'to JSON or YAML.'
|
22
|
-
spec.homepage = '
|
22
|
+
spec.homepage = 'https://gitlab.com/ephracis/keepachangelog'
|
23
23
|
spec.files = gem_files
|
24
24
|
spec.bindir = 'exe'
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
data/lib/keepachangelog.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
# require 'active_support'
|
2
|
-
# require 'active_support/core_ext'
|
3
1
|
require 'keepachangelog/version'
|
4
2
|
require 'keepachangelog/parser'
|
3
|
+
require 'keepachangelog/parser/markdown'
|
4
|
+
require 'keepachangelog/parser/yaml'
|
5
|
+
require 'keepachangelog/printer'
|
6
|
+
require 'keepachangelog/printer/markdown'
|
7
|
+
require 'keepachangelog/printer/yaml'
|
5
8
|
require 'json'
|
6
9
|
require 'yaml'
|
data/lib/keepachangelog/cli.rb
CHANGED
@@ -14,42 +14,66 @@ module Keepachangelog
|
|
14
14
|
desc 'version', 'Show current version'
|
15
15
|
long_desc 'Show the version of the tool'
|
16
16
|
def version
|
17
|
-
require 'keepachangelog/version'
|
18
17
|
shell.say Keepachangelog.version
|
19
18
|
end
|
20
19
|
|
21
|
-
desc '
|
22
|
-
option :
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
option :
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
20
|
+
desc 'parse', 'Parse a changelog'
|
21
|
+
option :from, type: :string,
|
22
|
+
desc: 'The input format',
|
23
|
+
default: 'md',
|
24
|
+
banner: 'yaml|md',
|
25
|
+
aliases: '-f'
|
26
|
+
option :to, type: :string,
|
27
|
+
desc: 'The output format',
|
28
|
+
default: 'json',
|
29
|
+
banner: 'json|yaml|md',
|
30
|
+
aliases: '-t'
|
31
|
+
option :in, type: :string,
|
32
|
+
desc: 'Path to the input file/folder',
|
33
|
+
aliases: '-i'
|
34
|
+
option :out, type: :string,
|
35
|
+
desc: 'Path to the output file/folder',
|
36
|
+
aliases: '-o'
|
37
|
+
def parse
|
38
|
+
case options[:from].to_sym
|
39
|
+
when :md then parse_markdown
|
40
|
+
when :yaml then parse_yaml
|
41
|
+
else
|
42
|
+
shell.error "Unknown input format #{options[:from]}"
|
43
|
+
exit 1
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
desc: 'Path to the yaml folder',
|
45
|
-
default: 'changelog',
|
46
|
-
aliases: '-p'
|
47
|
-
def yaml
|
48
|
-
require 'keepachangelog/parser/yaml'
|
49
|
-
p = YamlParser.load(options[:path])
|
50
|
-
shell.say p.send("to_#{options[:format]}")
|
47
|
+
default_task :parse
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def parse_markdown
|
52
|
+
parser = MarkdownParser.load(options[:in])
|
53
|
+
print parser
|
51
54
|
end
|
52
55
|
|
53
|
-
|
56
|
+
def parse_yaml
|
57
|
+
parser = YamlParser.load(options[:in])
|
58
|
+
print parser
|
59
|
+
end
|
60
|
+
|
61
|
+
# rubocop:disable Metrics/AbcSize
|
62
|
+
def print(parser)
|
63
|
+
case options[:to].to_sym
|
64
|
+
when :json
|
65
|
+
shell.say parser.to_json
|
66
|
+
when :s, :string
|
67
|
+
shell.say parser.to_s
|
68
|
+
when :md, :markdown
|
69
|
+
shell.say parser.to_md
|
70
|
+
when :yaml, :yml
|
71
|
+
parser.to_yaml(options[:out])
|
72
|
+
shell.say "Finished writing changelog to '#{options[:out]}'"
|
73
|
+
else
|
74
|
+
shell.error "Unknown output format #{options[:to]}"
|
75
|
+
exit 2
|
76
|
+
end
|
77
|
+
end
|
54
78
|
end
|
55
79
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'keepachangelog/markdown_printer'
|
2
|
-
|
3
1
|
module Keepachangelog
|
4
2
|
class Parser
|
5
3
|
attr_accessor :parsed_content
|
@@ -28,8 +26,11 @@ module Keepachangelog
|
|
28
26
|
# New:
|
29
27
|
# - Feature A
|
30
28
|
# ```
|
31
|
-
def to_yaml
|
32
|
-
|
29
|
+
def to_yaml(path = nil)
|
30
|
+
path ||= 'changelog'
|
31
|
+
require 'keepachangelog/printer/yaml'
|
32
|
+
p = YamlPrinter.new(parsed_content)
|
33
|
+
p.write(path)
|
33
34
|
end
|
34
35
|
|
35
36
|
# Changelog as a Ruby string
|
@@ -44,11 +45,12 @@ module Keepachangelog
|
|
44
45
|
|
45
46
|
# Changelog as Markdown
|
46
47
|
def to_md
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
require 'keepachangelog/printer/markdown'
|
49
|
+
p = MarkdownPrinter.new(parsed_content['versions'],
|
50
|
+
title: parsed_content['title'],
|
51
|
+
intro: parsed_content['intro'],
|
52
|
+
url: parsed_content['url'])
|
53
|
+
p.to_s
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
@@ -7,16 +7,19 @@ module Keepachangelog
|
|
7
7
|
end
|
8
8
|
|
9
9
|
# Parse a file with markdown content
|
10
|
-
def self.load(filename =
|
10
|
+
def self.load(filename = nil)
|
11
|
+
filename ||= 'CHANGELOG.md'
|
11
12
|
p = new
|
12
13
|
p.parse File.open(filename, &:read)
|
13
14
|
p
|
14
15
|
end
|
15
16
|
|
16
17
|
def parse(content)
|
17
|
-
content = "\n" +
|
18
|
+
content = "\n" + content.strip + "\n"
|
18
19
|
anchors = extract_anchors! content
|
19
|
-
|
20
|
+
sections = content.split(/\n\s*## /)
|
21
|
+
parse_meta anchors, sections[0]
|
22
|
+
versions = sections[1..-1]
|
20
23
|
parsed_content['versions'] = versions.map do |v|
|
21
24
|
parse_version v, anchors
|
22
25
|
end.to_h
|
@@ -25,26 +28,44 @@ module Keepachangelog
|
|
25
28
|
|
26
29
|
private
|
27
30
|
|
28
|
-
def
|
29
|
-
|
31
|
+
def parse_meta(anchors, header)
|
32
|
+
url = get_repo_url(anchors)
|
33
|
+
title = extract_title!(header)
|
34
|
+
intro = header.strip
|
35
|
+
parsed_content['url'] = url if url
|
36
|
+
parsed_content['intro'] = intro unless intro.to_s.empty?
|
37
|
+
parsed_content['title'] = title if title
|
38
|
+
end
|
39
|
+
|
40
|
+
def extract_title!(text)
|
41
|
+
title_pattern = /# (?<title>.*)/
|
42
|
+
match = text.match(title_pattern)
|
43
|
+
return nil unless match && match[:title]
|
44
|
+
text.gsub!(title_pattern, '').strip!
|
45
|
+
match[:title]
|
30
46
|
end
|
31
47
|
|
32
48
|
def parse_version(content, anchors)
|
33
|
-
header_pattern = /\[(?<name
|
49
|
+
header_pattern = /\[?(?<name>[^\]]*)\]?( - (?<date>\d\d\d\d-\d\d-\d\d))?/
|
34
50
|
sections = content.split(/\n\s*### /)
|
35
51
|
header = sections[0].match header_pattern
|
36
|
-
[header[:name],
|
52
|
+
[header[:name].strip,
|
37
53
|
{
|
38
|
-
'url' =>
|
54
|
+
'url' => get_version_url(header[:name], anchors),
|
39
55
|
'date' => header[:date],
|
40
56
|
'changes' => sections[1..-1].map { |s| parse_section s }.to_h
|
41
57
|
}]
|
42
58
|
end
|
43
59
|
|
44
|
-
def
|
60
|
+
def get_version_url(version, anchors)
|
45
61
|
anchors.keys.include?(version) ? anchors[version] : nil
|
46
62
|
end
|
47
63
|
|
64
|
+
def get_repo_url(anchors)
|
65
|
+
return nil unless anchors && anchors.values && anchors.values.first
|
66
|
+
anchors.values.first.gsub(%r{/compare/.*}, '')
|
67
|
+
end
|
68
|
+
|
48
69
|
def parse_section(content)
|
49
70
|
lines = content.split("\n")
|
50
71
|
bullets = lines[1..-1]
|
@@ -54,7 +75,7 @@ module Keepachangelog
|
|
54
75
|
end
|
55
76
|
|
56
77
|
def clean_bullet(string)
|
57
|
-
string.strip.gsub(/^\s*- /, '').
|
78
|
+
string.strip.gsub(/^\s*- /, '').strip
|
58
79
|
end
|
59
80
|
|
60
81
|
def extract_anchors!(content)
|
@@ -39,7 +39,8 @@ module Keepachangelog
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Parse a folder with YAML files
|
42
|
-
def self.load(path =
|
42
|
+
def self.load(path = nil)
|
43
|
+
path ||= 'changelog'
|
43
44
|
p = new
|
44
45
|
p.load(path)
|
45
46
|
p
|
@@ -54,7 +55,8 @@ module Keepachangelog
|
|
54
55
|
end
|
55
56
|
|
56
57
|
# Parse a folder with YAML files
|
57
|
-
def load(path =
|
58
|
+
def load(path = nil)
|
59
|
+
path ||= 'changelog'
|
58
60
|
read_meta("#{path}/meta.yaml")
|
59
61
|
Dir.glob("#{path}/*").each { |f| parse_version(f) }
|
60
62
|
end
|
@@ -92,7 +94,8 @@ module Keepachangelog
|
|
92
94
|
end
|
93
95
|
|
94
96
|
def generate_line(yaml)
|
95
|
-
line = yaml['title']
|
97
|
+
line = yaml['title']
|
98
|
+
line += + '.' unless line =~ /[[:punct:]]$/
|
96
99
|
line += " (!#{yaml['merge_request']})" if yaml['merge_request']
|
97
100
|
line += " (##{yaml['issue']})" if yaml['issue']
|
98
101
|
line += " (#{yaml['author']})" if yaml['author']
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Keepachangelog
|
2
|
-
class MarkdownPrinter
|
2
|
+
class MarkdownPrinter < Printer
|
3
3
|
attr_accessor :options
|
4
4
|
attr_accessor :versions
|
5
5
|
|
@@ -13,18 +13,29 @@ module Keepachangelog
|
|
13
13
|
"# #{options[:title] || default_title}",
|
14
14
|
clean_intro(options[:intro]) || default_intro,
|
15
15
|
'',
|
16
|
-
versions
|
17
|
-
version(k, v)
|
18
|
-
end,
|
16
|
+
parse_versions(versions),
|
19
17
|
anchors
|
20
18
|
].flatten.join("\n")
|
21
19
|
end
|
22
20
|
|
23
21
|
private
|
24
22
|
|
23
|
+
def parse_versions(versions)
|
24
|
+
versions.sort { |a, b| compare_versions(a[0], b[0]) }
|
25
|
+
.reverse_each.map { |k, v| version(k, v) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def compare_versions(a, b)
|
29
|
+
a = Gem::Version.new(a) if Gem::Version.correct?(a)
|
30
|
+
b = Gem::Version.new(b) if Gem::Version.correct?(b)
|
31
|
+
return -1 if b == 'Unreleased'
|
32
|
+
return 1 if a == 'Unreleased'
|
33
|
+
a <=> b
|
34
|
+
end
|
35
|
+
|
25
36
|
def clean_intro(text)
|
26
37
|
return nil unless text
|
27
|
-
text.to_s.strip
|
38
|
+
text.to_s.strip
|
28
39
|
end
|
29
40
|
|
30
41
|
def version(header, content)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Keepachangelog
|
4
|
+
class YamlPrinter < Printer
|
5
|
+
attr_accessor :changelog
|
6
|
+
|
7
|
+
def initialize(changelog)
|
8
|
+
self.changelog = changelog
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(path)
|
12
|
+
FileUtils.mkdir_p(path)
|
13
|
+
write_meta File.join(path, 'meta.yaml')
|
14
|
+
write_versions path, changelog['versions']
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def write_meta(path)
|
20
|
+
meta = {}
|
21
|
+
%w(url title intro).each do |key|
|
22
|
+
meta[key] = changelog[key] unless changelog[key].to_s.empty?
|
23
|
+
end
|
24
|
+
File.write(path, meta.to_yaml)
|
25
|
+
end
|
26
|
+
|
27
|
+
def write_versions(path, versions)
|
28
|
+
versions.each do |version, data|
|
29
|
+
folder = File.join(path, version)
|
30
|
+
FileUtils.mkdir_p folder
|
31
|
+
write_changes folder, data['changes']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_changes(path, changes)
|
36
|
+
changes.each do |section, lines|
|
37
|
+
lines.each do |line|
|
38
|
+
change = parse_line(line)
|
39
|
+
change['type'] = section
|
40
|
+
write_change path, change
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def write_change(folder, change)
|
46
|
+
fname = change['title'].gsub(/\W/, ' ').strip.tr(' ', '-').downcase
|
47
|
+
fname = "#{change['issue']}-#{fname}" if change['issue']
|
48
|
+
fname = "#{change['merge_request']}-#{fname}" if change['merge_request']
|
49
|
+
path = create_unique_file(folder, fname + '.yaml')
|
50
|
+
File.write(path, change.to_yaml)
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_line(line)
|
54
|
+
issue = extract_field! line, /\s*\(#(?<issue>\d+)\)\s*/, :issue
|
55
|
+
mr = extract_field! line, /\s*\(!(?<mr>\d+)\)\s*/, :mr
|
56
|
+
author = extract_field! line, /\s*\((?<author>.*@.*)\)\s*/, :author
|
57
|
+
data = { 'title' => line }
|
58
|
+
data['author'] = author if author
|
59
|
+
data['merge_request'] = mr.to_i if mr
|
60
|
+
data['issue'] = issue.to_i if issue
|
61
|
+
data
|
62
|
+
end
|
63
|
+
|
64
|
+
def extract_field!(line, pattern, name)
|
65
|
+
match = line.match(pattern)
|
66
|
+
return nil unless match && match[name]
|
67
|
+
line.gsub!(pattern, '').strip
|
68
|
+
match[name]
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_unique_file(folder, filename)
|
72
|
+
if File.exist? File.join(folder, filename)
|
73
|
+
randstr = SecureRandom.hex(3)
|
74
|
+
filename = "#{randstr}-#{filename}"
|
75
|
+
end
|
76
|
+
File.join(folder, filename)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "keepachangelog",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.1",
|
4
4
|
"description": "Parser for changelogs based on keepachangelog.com",
|
5
5
|
"main": "index.js",
|
6
6
|
"scripts": {
|
@@ -8,7 +8,7 @@
|
|
8
8
|
},
|
9
9
|
"repository": {
|
10
10
|
"type": "git",
|
11
|
-
"url": "git@
|
11
|
+
"url": "git@gitlab.com:ephracis/keepachangelog.git"
|
12
12
|
},
|
13
13
|
"author": "Christoffer Reijer",
|
14
14
|
"license": "ISC",
|
@@ -28,7 +28,8 @@ module Keepachangelog
|
|
28
28
|
'Fixed' => ['Feature B']
|
29
29
|
}
|
30
30
|
}
|
31
|
-
}
|
31
|
+
},
|
32
|
+
'url' => 'http://test.io'
|
32
33
|
)
|
33
34
|
end
|
34
35
|
|
@@ -55,7 +56,8 @@ module Keepachangelog
|
|
55
56
|
'date' => nil,
|
56
57
|
'changes' => { 'Fixed' => ['Feature B'] }
|
57
58
|
}
|
58
|
-
}
|
59
|
+
},
|
60
|
+
'url' => 'http://test.io'
|
59
61
|
)
|
60
62
|
end
|
61
63
|
|
@@ -84,6 +86,22 @@ module Keepachangelog
|
|
84
86
|
}
|
85
87
|
)
|
86
88
|
end
|
89
|
+
|
90
|
+
it 'should parse title and intro' do
|
91
|
+
content = "
|
92
|
+
# My Title
|
93
|
+
My test intro.
|
94
|
+
## 1.0.0
|
95
|
+
"
|
96
|
+
cl = MarkdownParser.parse(content)
|
97
|
+
expect(cl).to eq(
|
98
|
+
'versions' => {
|
99
|
+
'1.0.0' => { 'url' => nil, 'date' => nil, 'changes' => {} }
|
100
|
+
},
|
101
|
+
'title' => 'My Title',
|
102
|
+
'intro' => 'My test intro.'
|
103
|
+
)
|
104
|
+
end
|
87
105
|
end
|
88
106
|
|
89
107
|
describe '.load' do
|
data/spec/parser_spec.rb
CHANGED
@@ -11,9 +11,9 @@ module Keepachangelog
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe '.to_yaml' do
|
14
|
-
it 'should cast parsed content into yaml' do
|
14
|
+
it 'should cast parsed content into a yaml files' do
|
15
15
|
p = Parser.new
|
16
|
-
|
16
|
+
expect_any_instance_of(YamlPrinter).to receive(:write)
|
17
17
|
p.to_yaml
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Keepachangelog
|
4
|
+
describe MarkdownPrinter do
|
5
|
+
describe '.to_s' do
|
6
|
+
it 'should print markdown document' do
|
7
|
+
versions = {
|
8
|
+
'1.0.0' => {
|
9
|
+
'changes' => { 'New' => ['Feature A'] }
|
10
|
+
}
|
11
|
+
}
|
12
|
+
p = MarkdownPrinter.new(versions, title: 'My Title')
|
13
|
+
md = p.to_s
|
14
|
+
expect(md).to match('# My Title')
|
15
|
+
expect(md).to match('## 1.0.0')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should order versions numerically' do
|
19
|
+
versions = {
|
20
|
+
'0.1.0' => {
|
21
|
+
'changes' => { 'New' => ['Feature A'] }
|
22
|
+
},
|
23
|
+
'0.10.0' => {
|
24
|
+
'changes' => { 'New' => ['Feature B'] }
|
25
|
+
},
|
26
|
+
'0.2.0' => {
|
27
|
+
'changes' => { 'New' => ['Feature C'] }
|
28
|
+
}
|
29
|
+
}
|
30
|
+
p = MarkdownPrinter.new(versions)
|
31
|
+
md = p.to_s.delete("\n")
|
32
|
+
expect(md).to match(/.*0\.10\.0.*0\.2\.0.*0\.1\.0.*/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Keepachangelog
|
4
|
+
describe YamlPrinter do
|
5
|
+
let(:changelog) do
|
6
|
+
{
|
7
|
+
'versions' => {
|
8
|
+
'1.0.0' => {
|
9
|
+
'changes' => {
|
10
|
+
'New' => [
|
11
|
+
'Feature A',
|
12
|
+
'Feature B'
|
13
|
+
],
|
14
|
+
'Fixed' => ['Bug A']
|
15
|
+
}
|
16
|
+
},
|
17
|
+
'1.0.1' => {
|
18
|
+
'changes' => { 'Fixed' => ['Bug B'] }
|
19
|
+
}
|
20
|
+
},
|
21
|
+
'url' => 'https://git.example.com/foo/bar',
|
22
|
+
'title' => 'Change log',
|
23
|
+
'intro' => 'This is my intro'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
let(:p) { YamlPrinter.new(changelog) }
|
27
|
+
|
28
|
+
describe '.write' do
|
29
|
+
before do
|
30
|
+
allow(FileUtils).to receive(:mkdir_p).with('test')
|
31
|
+
allow(FileUtils).to receive(:mkdir_p).with('test/1.0.0')
|
32
|
+
allow(FileUtils).to receive(:mkdir_p).with('test/1.0.1')
|
33
|
+
allow(File).to receive(:write).with('test/**/*.yaml', any_args)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should create destination folder' do
|
37
|
+
allow(p).to receive(:write_meta)
|
38
|
+
allow(p).to receive(:write_versions)
|
39
|
+
expect(FileUtils).to receive(:mkdir_p).with('test')
|
40
|
+
p.write('test')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should create meta file' do
|
44
|
+
meta_content = "---\nurl: https://git.example.com/foo/bar\ntitle: "\
|
45
|
+
"Change log\nintro: This is my intro\n"
|
46
|
+
allow(p).to receive(:write_versions)
|
47
|
+
expect(File).to receive(:write).with('test/meta.yaml', meta_content)
|
48
|
+
p.write('test')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should create version folders' do
|
52
|
+
allow(p).to receive(:write_meta)
|
53
|
+
allow(p).to receive(:write_changes)
|
54
|
+
expect(FileUtils).to receive(:mkdir_p).with('test/1.0.0')
|
55
|
+
expect(FileUtils).to receive(:mkdir_p).with('test/1.0.1')
|
56
|
+
p.write('test')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should write change file' do
|
60
|
+
allow(p).to receive(:write_meta)
|
61
|
+
expect(File).to receive(:write).with(
|
62
|
+
'test/1.0.0/feature-a.yaml',
|
63
|
+
"---\ntitle: Feature A\ntype: New\n"
|
64
|
+
)
|
65
|
+
expect(File).to receive(:write).with(
|
66
|
+
'test/1.0.0/feature-b.yaml',
|
67
|
+
"---\ntitle: Feature B\ntype: New\n"
|
68
|
+
)
|
69
|
+
expect(File).to receive(:write).with(
|
70
|
+
'test/1.0.0/bug-a.yaml',
|
71
|
+
"---\ntitle: Bug A\ntype: Fixed\n"
|
72
|
+
)
|
73
|
+
expect(File).to receive(:write).with(
|
74
|
+
'test/1.0.1/bug-b.yaml',
|
75
|
+
"---\ntitle: Bug B\ntype: Fixed\n"
|
76
|
+
)
|
77
|
+
p.write('test')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keepachangelog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Basalt AB
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -152,31 +152,37 @@ files:
|
|
152
152
|
- changelog/0.3.0/3-anchors-without-url.yaml
|
153
153
|
- changelog/0.3.0/4-document-meta.yaml
|
154
154
|
- changelog/0.3.1/6-clean-changelog.yaml
|
155
|
+
- changelog/0.4.0/5-yaml-files.yaml
|
156
|
+
- changelog/0.4.0/7-numeric-order.yaml
|
157
|
+
- changelog/0.4.0/share-with-public.yaml
|
158
|
+
- changelog/0.4.1/8-fix-deploy.yaml
|
155
159
|
- changelog/meta.yaml
|
156
160
|
- exe/keepachangelog
|
157
161
|
- features/help.feature
|
158
|
-
- features/
|
162
|
+
- features/parser.feature
|
159
163
|
- features/support/aruba.rb
|
160
164
|
- features/version.feature
|
161
|
-
- features/yaml.feature
|
162
165
|
- keepachangelog.gemspec
|
163
166
|
- lib/keepachangelog.rb
|
164
167
|
- lib/keepachangelog/cli.rb
|
165
|
-
- lib/keepachangelog/markdown_printer.rb
|
166
168
|
- lib/keepachangelog/parser.rb
|
167
169
|
- lib/keepachangelog/parser/markdown.rb
|
168
170
|
- lib/keepachangelog/parser/yaml.rb
|
171
|
+
- lib/keepachangelog/printer.rb
|
172
|
+
- lib/keepachangelog/printer/markdown.rb
|
173
|
+
- lib/keepachangelog/printer/yaml.rb
|
169
174
|
- lib/keepachangelog/version.rb
|
170
175
|
- package.json
|
171
|
-
- spec/markdown_printer_spec.rb
|
172
176
|
- spec/parser/markdown_spec.rb
|
173
177
|
- spec/parser/yaml_spec.rb
|
174
178
|
- spec/parser_spec.rb
|
179
|
+
- spec/printer/markdown_spec.rb
|
180
|
+
- spec/printer/yaml_spec.rb
|
175
181
|
- spec/spec_helper.rb
|
176
182
|
- spec/version_spec.rb
|
177
|
-
homepage:
|
183
|
+
homepage: https://gitlab.com/ephracis/keepachangelog
|
178
184
|
licenses:
|
179
|
-
-
|
185
|
+
- MIT
|
180
186
|
metadata: {}
|
181
187
|
post_install_message:
|
182
188
|
rdoc_options: []
|
data/features/markdown.feature
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
Feature: List transformators
|
2
|
-
|
3
|
-
Parse a changelog by running `keepachangelog parse` or just simply
|
4
|
-
`keepachangelog`.
|
5
|
-
|
6
|
-
Scenario: Running with command
|
7
|
-
Given a file "CHANGELOG.md" with:
|
8
|
-
"""
|
9
|
-
## [Unreleased]
|
10
|
-
### New
|
11
|
-
- Feature A
|
12
|
-
"""
|
13
|
-
When I successfully run `keepachangelog markdown`
|
14
|
-
Then the output should contain:
|
15
|
-
"""
|
16
|
-
{"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
|
17
|
-
"""
|
18
|
-
|
19
|
-
Scenario: Running without command
|
20
|
-
Given a file "CHANGELOG.md" with:
|
21
|
-
"""
|
22
|
-
## [Unreleased]
|
23
|
-
### New
|
24
|
-
- Feature A
|
25
|
-
"""
|
26
|
-
When I successfully run `keepachangelog`
|
27
|
-
Then the output should contain:
|
28
|
-
"""
|
29
|
-
{"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
|
30
|
-
"""
|
31
|
-
|
32
|
-
Scenario: Changelog has a non-default filename
|
33
|
-
Given a file "HISTORY.md" with:
|
34
|
-
"""
|
35
|
-
## [Unreleased]
|
36
|
-
### New
|
37
|
-
- Feature A
|
38
|
-
"""
|
39
|
-
When I successfully run `keepachangelog --path=HISTORY.md`
|
40
|
-
Then the output should contain:
|
41
|
-
"""
|
42
|
-
{"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
|
43
|
-
"""
|
data/features/yaml.feature
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
Feature: List transformators
|
2
|
-
|
3
|
-
Parse a changelog by running `keepachangelog parse` or just simply
|
4
|
-
`keepachangelog`.
|
5
|
-
|
6
|
-
Scenario: Running with command
|
7
|
-
Given a file "changelog/1.0.0/1.yml" with:
|
8
|
-
"""
|
9
|
-
---
|
10
|
-
title: Feature A
|
11
|
-
type: New
|
12
|
-
"""
|
13
|
-
When I successfully run `keepachangelog yaml`
|
14
|
-
Then the output should contain:
|
15
|
-
"""
|
16
|
-
{"versions":{"1.0.0":{"changes":{"New":["Feature A."]}}}}
|
17
|
-
"""
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Keepachangelog
|
4
|
-
describe MarkdownPrinter do
|
5
|
-
describe '.to_s' do
|
6
|
-
it 'should print markdown document' do
|
7
|
-
versions = {
|
8
|
-
'1.0.0' => {
|
9
|
-
'changes' => { 'New' => ['Feature A'] }
|
10
|
-
}
|
11
|
-
}
|
12
|
-
p = MarkdownPrinter.new(versions, title: 'My Title')
|
13
|
-
md = p.to_s
|
14
|
-
expect(md).to match('# My Title')
|
15
|
-
expect(md).to match('## 1.0.0')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|