keepachangelog 0.3.1 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![build status](https://gitlab.com/ephracis/keepachangelog/badges/master/build.svg)](https://gitlab.com/ephracis/keepachangelog/commits/master)
|
2
|
+
[![coverage report](https://gitlab.com/ephracis/keepachangelog/badges/master/coverage.svg)](https://gitlab.com/ephracis/keepachangelog/commits/master)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/keepachangelog.svg)](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
|