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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d54eca6140fcc5088df9a25e92f0fe50b7df1a82
4
- data.tar.gz: cd1981c05340bc9ec4fb1309d9e422c9cfb008a7
3
+ metadata.gz: 6e63e90c5940db3033ddb2f4e58e77437af51e43
4
+ data.tar.gz: 8f30352f336656f66229df3eba5abbb4e2924149
5
5
  SHA512:
6
- metadata.gz: 721125e2778898619487ef091c5d2783bf7d01d6017721e83220547a794b32a9e13d57ae3d75852adb02c3a371d4ca37fe3ec0e8fca75326b18d768234a777a6
7
- data.tar.gz: 065e781135ea1d0d1ab7dfe01666b118755b7b81aaa3db4b12746b5f1887e2982cdd4e5a4140fb6b4bc293ed941c548b1d3e129daeecf2245861994b70738c37
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
- download.basalt.se:
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
@@ -7,6 +7,9 @@ Style/ClassAndModuleChildren:
7
7
  Style/AsciiComments:
8
8
  Enabled: false
9
9
 
10
+ Metrics/MethodLength:
11
+ Max: 15
12
+
10
13
  Metrics/BlockLength:
11
14
  Exclude:
12
15
  - 'spec/**/*'
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.3.1]: https://git.basalt.se/chbr/keepachangelog/compare/0.3.0...0.3.1
35
- [0.3.0]: https://git.basalt.se/chbr/keepachangelog/compare/0.2.1...0.3.0
36
- [0.2.1]: https://git.basalt.se/chbr/keepachangelog/compare/0.2.0...0.2.1
37
- [0.2.0]: https://git.basalt.se/chbr/keepachangelog/compare/0.1.0...0.2.0
38
- [0.1.0]: https://git.basalt.se/chbr/keepachangelog/compare/77986bc...0.1.0
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
- Se [metodanvisning utveckling](http://doc.basalt.se/docs/beans-metodanvisning-testdriven-utveckling/sv/stable/)
2
- för detaljer hur man utvecklar i detta projekt.
1
+ You can help out in several ways:
2
+ - File or discuss issues
3
+ - Send merge requests
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keepachangelog (0.3.1)
4
+ keepachangelog (0.4.1)
5
5
  json (~> 2.0)
6
6
  thor (~> 0.19)
7
7
 
data/LICENSE.md CHANGED
@@ -1,3 +1,19 @@
1
- Copyright © 2016 Basalt
1
+ Copyright © 2017 Basalt
2
2
 
3
- All rights reserved - Do Not Redistribute
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-files.
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 --path CHANGELOG.md --format json
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 without punctiation that describes the change
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 `keepachangelog yaml -f md`
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:
@@ -0,0 +1,4 @@
1
+ ---
2
+ title: Ability to output changelog to yaml file structure
3
+ merge_request: 9
4
+ type: New
@@ -0,0 +1,4 @@
1
+ ---
2
+ title: Sort versions in reverse numerical order in Markdown output
3
+ issue: 7
4
+ type: Fixed
@@ -0,0 +1,3 @@
1
+ ---
2
+ title: The code is pushed into a public repo at gitlab.com
3
+ type: New
@@ -0,0 +1,4 @@
1
+ ---
2
+ title: Deploy job in CI will no longer be skipped even though it should run
3
+ issue: 8
4
+ type: Fixed
data/changelog/meta.yaml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- url: https://git.basalt.se/chbr/keepachangelog
2
+ url: https://gitlab.com/ephracis/keepachangelog
@@ -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 markdown`
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
+ """
@@ -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 = ['Nonstandard']
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 = 'http://www.basalt.se'
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) }
@@ -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'
@@ -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 'markdown', 'Parse a changelog in markdown'
22
- option :format, type: :string,
23
- desc: 'The output format',
24
- default: 'json',
25
- banner: 'json|yaml',
26
- aliases: '-f'
27
- option :path, type: :string,
28
- desc: 'Path to the Changelog file',
29
- default: 'CHANGELOG.md',
30
- aliases: '-p'
31
- def markdown
32
- require 'keepachangelog/parser/markdown'
33
- p = MarkdownParser.load(options[:path])
34
- shell.say p.send("to_#{options[:format]}")
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
- desc 'yaml', 'Parse a folder of YAML files'
38
- option :format, type: :string,
39
- desc: 'The output format',
40
- default: 'json',
41
- banner: 'json|yaml|md',
42
- aliases: '-f'
43
- option :path, type: :string,
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
- default_task :markdown
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
- parsed_content.to_yaml
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
- md = MarkdownPrinter.new(parsed_content['versions'],
48
- title: parsed_content['title'],
49
- intro: parsed_content['intro'],
50
- url: parsed_content['url'])
51
- md.to_s
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 = 'CHANGELOG.md')
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" + clean(content).strip + "\n"
18
+ content = "\n" + content.strip + "\n"
18
19
  anchors = extract_anchors! content
19
- versions = content.split(/\n\s*## /)[1..-1]
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 clean(content)
29
- content.sub(/^.*?\n\s*## /, '## ')
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>.*)\]( - (?<date>\d\d\d\d-\d\d-\d\d))?/
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' => get_url(header[:name], anchors),
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 get_url(version, anchors)
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*- /, '').gsub(/\(.*#\d+\)\.?$/, '').strip
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 = 'changelog')
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 = 'changelog')
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']
@@ -0,0 +1,4 @@
1
+ module Keepachangelog
2
+ class Printer
3
+ end
4
+ end
@@ -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.reverse_each.map do |k, v|
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.gsub("\n", "\n\n")
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.1",
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@git.basalt.se:chbr/keepachangelog.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
- expect(p.parsed_content).to receive(:to_yaml)
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
@@ -1,5 +1,3 @@
1
1
  require 'simplecov'
2
2
  SimpleCov.start
3
3
  require 'keepachangelog'
4
- require 'keepachangelog/parser/markdown'
5
- require 'keepachangelog/parser/yaml'
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.3.1
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-27 00:00:00.000000000 Z
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/markdown.feature
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: http://www.basalt.se
183
+ homepage: https://gitlab.com/ephracis/keepachangelog
178
184
  licenses:
179
- - Nonstandard
185
+ - MIT
180
186
  metadata: {}
181
187
  post_install_message:
182
188
  rdoc_options: []
@@ -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
- """
@@ -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