keepachangelog 0.1.0 → 0.2.0

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: 43670bf15155e781900c3e2ef0cc4867037d4814
4
- data.tar.gz: f4060bb3c0ab0ba82a24f73e53c283c47bc9e627
3
+ metadata.gz: beb911086da3260f5c4f06ff2f57b219ddb19a06
4
+ data.tar.gz: d08ff76239c9a49db9ee5f46f33d3f4df75498bd
5
5
  SHA512:
6
- metadata.gz: dba49f142c11099ef4eb18e8ee0b68abbc9b6f73b8436df90959e2fc286d0fb5e8bacb00c291651c434015e88b6753bace3e768726393ef3ea10dae18f81c410
7
- data.tar.gz: 14e98f3e890e8b5d8729660561951241c29e73eaf80f60cde9895ec55171368c563f333c74090445116f6055411044f9a4a688e42e67559f62a4d767ab3f9e77
6
+ metadata.gz: 5fb6c397a7f820740f5f86206f6e37211afbfc564afd4cf17c0f7de4907b6ff57faf50333abec10ccde44b4d18f04a72d0c1d096d148d0e9c54b7f033bc33fce
7
+ data.tar.gz: 0237365f64e45fd84ee99b74fd9c0b68f57621f063e0d2c7abf249525c7149f256ade2bb9ceb5b5c979d4ba05ff064f590f8d26377d147a65c8c75c263ea31a3
@@ -4,6 +4,9 @@ Style/Documentation:
4
4
  Style/ClassAndModuleChildren:
5
5
  Enabled: false
6
6
 
7
+ Style/AsciiComments:
8
+ Enabled: false
9
+
7
10
  Metrics/BlockLength:
8
11
  Exclude:
9
12
  - 'spec/**/*'
@@ -4,11 +4,16 @@ Alla ändringar till detta projekt dokumenteras i denna fil.
4
4
  Formatet är baserat på [Keep a Changelog](http://keepachangelog.com/)
5
5
  och detta projekt följer [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [0.2.0] - 2017-03-27
8
+ - Förmåga att läsa in Changelog i YAML-format.
9
+ - Förmåga att skriva till Markdown-format.
10
+
7
11
  ## [0.1.0] - 2017-03-27
8
12
  ### Nytt
9
13
  - Ruby gem som exponerar verktyget via Ruby och CLI.
10
14
  - Förmåga att konvertera Changelog till JSON.
11
15
  - Förmåga att konvertera Changelog till YAML.
12
16
 
13
- [Unreleased]: https://git.basalt.se/chbr/keepachangelog/compare/0.1.0...HEAD
17
+ [Unreleased]: https://git.basalt.se/chbr/keepachangelog/compare/0.2.0...HEAD
18
+ [0.2.0]: https://git.basalt.se/chbr/keepachangelog/compare/0.1.0...0.2.0
14
19
  [0.1.0]: https://git.basalt.se/chbr/keepachangelog/compare/77986bc...0.1.0
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keepachangelog (0.1.0)
4
+ keepachangelog (0.2.0)
5
5
  json (~> 2.0)
6
6
  thor (~> 0.19)
7
7
 
@@ -84,4 +84,4 @@ DEPENDENCIES
84
84
  simplecov (~> 0.14)
85
85
 
86
86
  BUNDLED WITH
87
- 1.14.3
87
+ 1.14.6
@@ -8,6 +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 parse`
12
- Then the output should contain "Options"
13
- And the output should contain "Usage"
11
+ When I successfully run `keepachangelog help markdown`
12
+ Then the output should contain "Usage"
@@ -10,10 +10,10 @@ Feature: List transformators
10
10
  ### New
11
11
  - Feature A
12
12
  """
13
- When I successfully run `keepachangelog parse`
13
+ When I successfully run `keepachangelog markdown`
14
14
  Then the output should contain:
15
15
  """
16
- [{"version":"Unreleased","url":null,"date":null,"changes":{"New":["Feature A"]}}]
16
+ {"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
17
17
  """
18
18
 
19
19
  Scenario: Running without command
@@ -26,7 +26,7 @@ Feature: List transformators
26
26
  When I successfully run `keepachangelog`
27
27
  Then the output should contain:
28
28
  """
29
- [{"version":"Unreleased","url":null,"date":null,"changes":{"New":["Feature A"]}}]
29
+ {"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
30
30
  """
31
31
 
32
32
  Scenario: Changelog has a non-default filename
@@ -39,5 +39,5 @@ Feature: List transformators
39
39
  When I successfully run `keepachangelog --path=HISTORY.md`
40
40
  Then the output should contain:
41
41
  """
42
- [{"version":"Unreleased","url":null,"date":null,"changes":{"New":["Feature A"]}}]
42
+ {"versions":{"Unreleased":{"url":null,"date":null,"changes":{"New":["Feature A"]}}}}
43
43
  """
@@ -0,0 +1,17 @@
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
+ """
@@ -18,22 +18,38 @@ module Keepachangelog
18
18
  shell.say Keepachangelog.version
19
19
  end
20
20
 
21
- desc '<options> parse', 'Parse a changelog'
21
+ desc 'markdown', 'Parse a changelog in markdown'
22
22
  option :format, type: :string,
23
23
  desc: 'The output format',
24
24
  default: 'json',
25
25
  banner: 'json|yaml',
26
26
  aliases: '-f'
27
27
  option :path, type: :string,
28
- desc: 'Path to the changelog file',
28
+ desc: 'Path to the Changelog file',
29
29
  default: 'CHANGELOG.md',
30
30
  aliases: '-p'
31
- def parse
32
- require 'keepachangelog/parser'
33
- p = Parser.load(options[:path])
31
+ def markdown
32
+ require 'keepachangelog/parser/markdown'
33
+ p = MarkdownParser.load(options[:path])
34
34
  shell.say p.send("to_#{options[:format]}")
35
35
  end
36
36
 
37
- default_task :parse
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',
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]}")
51
+ end
52
+
53
+ default_task :markdown
38
54
  end
39
55
  end
@@ -0,0 +1,90 @@
1
+ module Keepachangelog
2
+ class MarkdownPrinter
3
+ attr_accessor :options
4
+ attr_accessor :versions
5
+
6
+ def initialize(versions, options = {})
7
+ self.options = options
8
+ self.versions = versions
9
+ end
10
+
11
+ def to_s
12
+ [
13
+ "# #{options[:title] || default_title}",
14
+ clean_intro(options[:intro]) || default_intro,
15
+ '',
16
+ versions.reverse_each.map do |k, v|
17
+ version(k, v)
18
+ end,
19
+ anchors
20
+ ].flatten.join("\n")
21
+ end
22
+
23
+ private
24
+
25
+ def clean_intro(text)
26
+ text.to_s.strip.gsub("\n", "\n\n")
27
+ end
28
+
29
+ def version(header, content)
30
+ [
31
+ version_header(header),
32
+ content['changes'].map { |k, v| section(k, v) }
33
+ ]
34
+ end
35
+
36
+ def section(header, content)
37
+ [
38
+ "### #{header}",
39
+ content.map { |c| change(c) },
40
+ ''
41
+ ]
42
+ end
43
+
44
+ def anchors
45
+ v = versions.keys.sort.reverse
46
+ (0..v.length - 1).map { |i| anchor(v, i) }
47
+ end
48
+
49
+ def anchor(v, i)
50
+ from_v = i == v.length - 1 ? first_commit : v[i + 1]
51
+ to_v = v[i] == 'Unreleased' ? 'HEAD' : v[i]
52
+ "[#{v[i]}]: #{options[:url]}/compare/#{from_v}..#{to_v}"
53
+ end
54
+
55
+ def change(content)
56
+ "- #{content}"
57
+ end
58
+
59
+ def default_title
60
+ 'Change log'
61
+ end
62
+
63
+ def default_intro
64
+ "All notable changes to this project will be documented in this file.
65
+
66
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
67
+ and this project adheres to [Semantic Versioning](http://semver.org/)."
68
+ end
69
+
70
+ def first_commit
71
+ `git rev-parse --short $(git rev-list --max-parents=0 HEAD) 2>/dev/null`
72
+ .strip
73
+ end
74
+
75
+ def version_date(version)
76
+ date = `git log -1 --format=%aI #{version} 2>/dev/null`.strip
77
+ DateTime.parse(date).strftime('%Y-%m-%d')
78
+ rescue
79
+ nil
80
+ end
81
+
82
+ def version_header(version)
83
+ header = version
84
+ header = "[#{header}]" if options[:url]
85
+ date = version_date(version)
86
+ header += " - #{date}" if date
87
+ "## #{header}"
88
+ end
89
+ end
90
+ end
@@ -1,82 +1,54 @@
1
+ require 'keepachangelog/markdown_printer'
2
+
1
3
  module Keepachangelog
2
4
  class Parser
3
5
  attr_accessor :parsed_content
4
6
 
5
- def initialize(content = '')
6
- self.parsed_content = parse(content)
7
- end
8
-
9
- def self.load(filename = 'CHANGELOG.md')
10
- content = File.open(filename, &:read)
11
- new(content)
12
- end
13
-
14
- def self.parse(content)
15
- new(content)
7
+ def initialize
8
+ self.parsed_content = { 'versions' => {} }
16
9
  end
17
10
 
11
+ # Changelog in JSON format
12
+ #
13
+ # Example:
14
+ # ```json
15
+ # {"1.0.0": { "changes": { "New": ["Feature A"] } } }
16
+ # ```
18
17
  def to_json
19
18
  parsed_content.to_json
20
19
  end
21
20
 
21
+ # Changelog in YAML format
22
+ #
23
+ # Example:
24
+ # ```yaml
25
+ # ---
26
+ # 0.1.0:
27
+ # changes:
28
+ # New:
29
+ # - Feature A
30
+ # ```
22
31
  def to_yaml
23
32
  parsed_content.to_yaml
24
33
  end
25
34
 
35
+ # Changelog as a Ruby string
36
+ #
37
+ # Example:
38
+ # ```ruby
39
+ # {"0.1.0"=>{"changes"=>{"New"=>["Feature A"]}}
40
+ # ```
26
41
  def to_s
27
42
  parsed_content.to_s
28
43
  end
29
44
 
30
- private
31
-
32
- def parse(content)
33
- content = "\n" + clean(content).strip + "\n"
34
- anchors = extract_anchors! content
35
- versions = content.split(/\n\s*## /)[1..-1]
36
- versions.map { |v| parse_version v, anchors }
37
- end
38
-
39
- def clean(content)
40
- content.sub(/^.*?\n\s*## /, '## ')
41
- end
42
-
43
- def parse_version(content, anchors)
44
- header_pattern = /\[(?<name>.*)\]( - (?<date>\d\d\d\d-\d\d-\d\d))?/
45
- sections = content.split(/\n\s*### /)
46
- header = sections[0].match header_pattern
47
- {
48
- 'version' => header[:name],
49
- 'url' => get_url(header[:name], anchors),
50
- 'date' => header[:date],
51
- 'changes' => sections[1..-1].map { |s| parse_section s }.to_h
52
- }
53
- end
54
-
55
- def get_url(version, anchors)
56
- anchors.keys.include?(version) ? anchors[version] : nil
57
- end
58
-
59
- def parse_section(content)
60
- lines = content.split("\n")
61
- bullets = lines[1..-1]
62
- .select { |s| s.strip.start_with?('- ') }
63
- .map { |s| clean_bullet(s) }
64
- [lines[0], bullets]
65
- end
66
-
67
- def clean_bullet(string)
68
- string.strip.gsub(/^\s*- /, '').gsub(/\(.*#\d+\)\.?$/, '').strip
69
- end
70
-
71
- def extract_anchors!(content)
72
- anchor_pattern = /\n\s*\[(.*)\]: (.*)\s*\n/
73
- anchors = content.scan anchor_pattern
74
- cleaned_content = ''
75
- while cleaned_content.to_s != content.to_s
76
- cleaned_content = content.gsub anchor_pattern, "\n"
77
- content.replace(cleaned_content)
78
- end
79
- anchors.map { |x| [x[0], x[1]] }.to_h
45
+ # Changelog as Markdown
46
+ 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
80
52
  end
81
53
  end
82
54
  end
@@ -0,0 +1,68 @@
1
+ module Keepachangelog
2
+ # Parser for Markdown content
3
+ class MarkdownParser < Parser
4
+ # Parse raw markdown content
5
+ def self.parse(content = '')
6
+ new.parse(content)
7
+ end
8
+
9
+ # Parse a file with markdown content
10
+ def self.load(filename = 'CHANGELOG.md')
11
+ parse File.open(filename, &:read)
12
+ end
13
+
14
+ def parse(content)
15
+ content = "\n" + clean(content).strip + "\n"
16
+ anchors = extract_anchors! content
17
+ versions = content.split(/\n\s*## /)[1..-1]
18
+ {
19
+ 'versions' => versions.map { |v| parse_version v, anchors }.to_h
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def clean(content)
26
+ content.sub(/^.*?\n\s*## /, '## ')
27
+ end
28
+
29
+ def parse_version(content, anchors)
30
+ header_pattern = /\[(?<name>.*)\]( - (?<date>\d\d\d\d-\d\d-\d\d))?/
31
+ sections = content.split(/\n\s*### /)
32
+ header = sections[0].match header_pattern
33
+ [header[:name],
34
+ {
35
+ 'url' => get_url(header[:name], anchors),
36
+ 'date' => header[:date],
37
+ 'changes' => sections[1..-1].map { |s| parse_section s }.to_h
38
+ }]
39
+ end
40
+
41
+ def get_url(version, anchors)
42
+ anchors.keys.include?(version) ? anchors[version] : nil
43
+ end
44
+
45
+ def parse_section(content)
46
+ lines = content.split("\n")
47
+ bullets = lines[1..-1]
48
+ .select { |s| s.strip.start_with?('- ') }
49
+ .map { |s| clean_bullet(s) }
50
+ [lines[0], bullets]
51
+ end
52
+
53
+ def clean_bullet(string)
54
+ string.strip.gsub(/^\s*- /, '').gsub(/\(.*#\d+\)\.?$/, '').strip
55
+ end
56
+
57
+ def extract_anchors!(content)
58
+ anchor_pattern = /\n\s*\[(.*)\]: (.*)\s*\n/
59
+ anchors = content.scan anchor_pattern
60
+ cleaned_content = ''
61
+ while cleaned_content.to_s != content.to_s
62
+ cleaned_content = content.gsub anchor_pattern, "\n"
63
+ content.replace(cleaned_content)
64
+ end
65
+ anchors.map { |x| [x[0], x[1]] }.to_h
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,110 @@
1
+ module Keepachangelog
2
+ # Parser for YAML content
3
+ #
4
+ # The YAML files describing the Changelog are expected to be in a folder
5
+ # structure where each version is its own folder and each Merge Request
6
+ # or Pull Request is in its own YAML-file.
7
+ #
8
+ # ```
9
+ # changelog
10
+ # ├── 0.1.0
11
+ # │   └── 1-first-merge-request.yaml
12
+ # ├── 0.2.0
13
+ # │   └── 3-another-cool-mr.yaml
14
+ # ├── 0.3.0
15
+ # │   ├── 8-fixing-some-stuff.yaml
16
+ # │   └── 9-add-new-feature.yaml
17
+ # └── unreleased
18
+ #    └── 11-minor-patch.yaml
19
+ # ```
20
+ #
21
+ # Each YAML file is expected to be in the following format:
22
+ #
23
+ # ```yaml
24
+ # ---
25
+ # title: The ability to perform Foo while Bar is active
26
+ # merge_request: 11
27
+ # issue: 42
28
+ # author: @chbr
29
+ # type: New
30
+ # ```
31
+ #
32
+ # - `title` is a single sentence without punctiation that describes the
33
+ # change
34
+ # - `merge_request` is the ID of the MR or PR (optional)
35
+ # - `issue` is the ID of the issue (optional)
36
+ # - `author` is the username of the author (optional)
37
+ # - `type` is the type of change, for example *New*, *Changed*, *Fixed*,
38
+ # *Removed* or *Security*.
39
+ class YamlParser < Parser
40
+ # Parse raw yaml content of a single file
41
+ def self.parse(content, version = 'unreleased')
42
+ new.parse(content, version)
43
+ end
44
+
45
+ # Parse a folder with YAML files
46
+ def self.load(path = 'changelog')
47
+ p = new
48
+ p.load(path)
49
+ p
50
+ end
51
+
52
+ # Parse raw yaml content of a single file
53
+ def parse(content, version)
54
+ initialize_version version
55
+ yaml = YAML.safe_load content
56
+ return {} unless yaml
57
+ add_change yaml, version
58
+ end
59
+
60
+ # Parse a folder with YAML files
61
+ def load(path = 'changelog')
62
+ read_meta("#{path}/meta.yaml")
63
+ Dir.glob("#{path}/*").each { |f| parse_version(f) }
64
+ end
65
+
66
+ private
67
+
68
+ def read_meta(path)
69
+ return unless File.exist?(path)
70
+ content = File.open(path, &:read)
71
+ yaml = YAML.safe_load content
72
+ return unless yaml
73
+ parsed_content['title'] = yaml['title']
74
+ parsed_content['url'] = yaml['url']
75
+ parsed_content['intro'] = yaml['intro']
76
+ end
77
+
78
+ def add_change(yaml, version)
79
+ changes = parsed_content['versions'][version]['changes']
80
+ changes[yaml['type']] = (changes[yaml['type']] || []) +
81
+ [generate_line(yaml)]
82
+ parsed_content
83
+ end
84
+
85
+ def parse_version(folder)
86
+ version = File.basename(folder)
87
+ return if version == 'meta.yaml'
88
+ initialize_version version
89
+ files = Dir.glob("#{folder}/**/*.yaml") +
90
+ Dir.glob("#{folder}/**/*.yml")
91
+ files.sort.each { |f| parse_file(f, version) }
92
+ end
93
+
94
+ def parse_file(filename, version)
95
+ parse File.open(filename, &:read), version
96
+ end
97
+
98
+ def generate_line(yaml)
99
+ line = yaml['title']
100
+ line += " (!#{yaml['merge_request']})" if yaml['merge_request']
101
+ line += " (##{yaml['issue']})" if yaml['issue']
102
+ line += " (#{yaml['author']})" if yaml['author']
103
+ line
104
+ end
105
+
106
+ def initialize_version(version)
107
+ parsed_content['versions'][version] = { 'changes' => {} }
108
+ end
109
+ end
110
+ end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keepachangelog",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Parser for changelogs based on keepachangelog.com",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ module Keepachangelog
4
+ describe MarkdownParser do
5
+ describe '.parse' do
6
+ it 'should parse empty content' do
7
+ cl = MarkdownParser.parse('')
8
+ expect(cl).to eq('versions' => {})
9
+ end
10
+
11
+ it 'should parse single version' do
12
+ content = "
13
+ ## [1.2.3] - 2017-01-01
14
+ ### New
15
+ - Feature A
16
+ ### Fixed
17
+ - Feature B
18
+ [1.2.3]: http://test.io
19
+ "
20
+ cl = MarkdownParser.parse(content)
21
+ expect(cl).to eq(
22
+ 'versions' => {
23
+ '1.2.3' => {
24
+ 'url' => 'http://test.io',
25
+ 'date' => '2017-01-01',
26
+ 'changes' => {
27
+ 'New' => ['Feature A'],
28
+ 'Fixed' => ['Feature B']
29
+ }
30
+ }
31
+ }
32
+ )
33
+ end
34
+
35
+ it 'should parse multiple versions' do
36
+ content = "
37
+ ## [2.0.0] - 2017-01-01
38
+ ### New
39
+ - Feature A
40
+ ## [1.0.0]
41
+ ### Fixed
42
+ - Feature B
43
+ [1.0.0]: http://test.io
44
+ "
45
+ cl = MarkdownParser.parse(content)
46
+ expect(cl).to eq(
47
+ 'versions' => {
48
+ '2.0.0' => {
49
+ 'url' => nil,
50
+ 'date' => '2017-01-01',
51
+ 'changes' => { 'New' => ['Feature A'] }
52
+ },
53
+ '1.0.0' => {
54
+ 'url' => 'http://test.io',
55
+ 'date' => nil,
56
+ 'changes' => { 'Fixed' => ['Feature B'] }
57
+ }
58
+ }
59
+ )
60
+ end
61
+
62
+ it 'should parse version without sections' do
63
+ content = "
64
+ ## [3.0.0]
65
+ ## [2.0.0] - 2017-01-01
66
+ ### New
67
+ - Feature A
68
+ ## [1.0.0]
69
+ "
70
+ cl = MarkdownParser.parse(content)
71
+ expect(cl).to eq(
72
+ 'versions' => {
73
+ '3.0.0' => {
74
+ 'url' => nil, 'date' => nil, 'changes' => {}
75
+ },
76
+ '2.0.0' => {
77
+ 'url' => nil,
78
+ 'date' => '2017-01-01',
79
+ 'changes' => { 'New' => ['Feature A'] }
80
+ },
81
+ '1.0.0' => {
82
+ 'url' => nil, 'date' => nil, 'changes' => {}
83
+ }
84
+ }
85
+ )
86
+ end
87
+ end
88
+
89
+ describe '.load' do
90
+ it 'should parse content of file' do
91
+ content = 'test changelog'
92
+ allow(File).to receive(:open).and_call_original
93
+ expect(File).to receive(:open).with('test.md')
94
+ .and_yield(StringIO.new(content))
95
+ expect(MarkdownParser).to receive(:parse).with(content)
96
+ MarkdownParser.load('test.md')
97
+ end
98
+
99
+ it 'should throw on non-existent file' do
100
+ expect do
101
+ MarkdownParser.load('invalid-file')
102
+ end.to raise_exception(
103
+ Errno::ENOENT,
104
+ 'No such file or directory @ rb_sysopen - invalid-file'
105
+ )
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Keepachangelog
4
+ describe YamlParser do
5
+ describe '.parse' do
6
+ it 'should parse empty content' do
7
+ cl = YamlParser.parse('')
8
+ expect(cl).to eq({})
9
+ end
10
+
11
+ it 'should parse single version' do
12
+ content = "
13
+ ---
14
+ title: Feature A
15
+ type: New
16
+ "
17
+ cl = YamlParser.parse(content, '1.2.3')
18
+ expect(cl).to eq(
19
+ 'versions' => {
20
+ '1.2.3' => {
21
+ 'changes' => {
22
+ 'New' => ['Feature A']
23
+ }
24
+ }
25
+ }
26
+ )
27
+ end
28
+ end
29
+
30
+ describe '.load' do
31
+ it 'should parse content of folder' do
32
+ content = 'test changelog'
33
+ allow(File).to receive(:open).and_call_original
34
+ allow(File).to receive(:open).with('changelog/1.0.0/1.yml')
35
+ .and_yield(StringIO.new(content))
36
+ expect(Dir).to receive(:glob).with('changelog/*')
37
+ .and_return(['changelog/1.0.0'])
38
+ expect(Dir).to receive(:glob).with('changelog/1.0.0/**/*.yml')
39
+ .and_return(['changelog/1.0.0/1.yml'])
40
+ expect(Dir).to receive(:glob).with('changelog/1.0.0/**/*.yaml')
41
+ .and_return([])
42
+
43
+ expect_any_instance_of(YamlParser).to \
44
+ receive(:parse).with('test changelog', '1.0.0')
45
+
46
+ YamlParser.load
47
+ end
48
+ end
49
+ end
50
+ end
@@ -2,124 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Keepachangelog
4
4
  describe Parser do
5
- describe '#parse' do
6
- it 'should parse empty content' do
7
- content = ''
8
- p = Parser.new(content)
9
- expect(p.parsed_content).to eq([])
10
- end
11
-
12
- it 'should parse single version' do
13
- content = "
14
- ## [1.2.3] - 2017-01-01
15
- ### New
16
- - Feature A
17
- ### Fixed
18
- - Feature B
19
- [1.2.3]: http://test.io
20
- "
21
- p = Parser.new(content)
22
- expect(p.parsed_content).to eq(
23
- [
24
- {
25
- 'version' => '1.2.3',
26
- 'url' => 'http://test.io',
27
- 'date' => '2017-01-01',
28
- 'changes' => {
29
- 'New' => ['Feature A'],
30
- 'Fixed' => ['Feature B']
31
- }
32
- }
33
- ]
34
- )
35
- end
36
-
37
- it 'should parse multiple versions' do
38
- content = "
39
- ## [2.0.0] - 2017-01-01
40
- ### New
41
- - Feature A
42
- ## [1.0.0]
43
- ### Fixed
44
- - Feature B
45
- [1.0.0]: http://test.io
46
- "
47
- p = Parser.new(content)
48
- expect(p.parsed_content).to eq(
49
- [
50
- {
51
- 'version' => '2.0.0',
52
- 'url' => nil,
53
- 'date' => '2017-01-01',
54
- 'changes' => { 'New' => ['Feature A'] }
55
- },
56
- {
57
- 'version' => '1.0.0',
58
- 'url' => 'http://test.io',
59
- 'date' => nil,
60
- 'changes' => { 'Fixed' => ['Feature B'] }
61
- }
62
- ]
63
- )
64
- end
65
-
66
- it 'should parse version without sections' do
67
- content = "
68
- ## [3.0.0]
69
- ## [2.0.0] - 2017-01-01
70
- ### New
71
- - Feature A
72
- ## [1.0.0]
73
- "
74
- p = Parser.new(content)
75
- expect(p.parsed_content).to eq(
76
- [
77
- {
78
- 'version' => '3.0.0', 'url' => nil, 'date' => nil,
79
- 'changes' => {}
80
- },
81
- {
82
- 'version' => '2.0.0',
83
- 'url' => nil,
84
- 'date' => '2017-01-01',
85
- 'changes' => { 'New' => ['Feature A'] }
86
- },
87
- {
88
- 'version' => '1.0.0', 'url' => nil, 'date' => nil,
89
- 'changes' => {}
90
- }
91
- ]
92
- )
93
- end
94
- end
95
-
96
- describe '.load' do
97
- it 'should parse content of file' do
98
- content = 'test changelog'
99
- allow(File).to receive(:open).and_call_original
100
- expect(File).to receive(:open).with('test.md')
101
- .and_yield(StringIO.new(content))
102
- expect(Parser).to receive(:new).with(content)
103
- Parser.load('test.md')
104
- end
105
-
106
- it 'should throw on non-existent file' do
107
- expect do
108
- Parser.load('invalid-file')
109
- end.to raise_exception(
110
- Errno::ENOENT,
111
- 'No such file or directory @ rb_sysopen - invalid-file'
112
- )
113
- end
114
- end
115
-
116
- describe '.parse' do
117
- it 'should call on .new' do
118
- expect(Parser).to receive(:new).with('test')
119
- Parser.parse('test')
120
- end
121
- end
122
-
123
5
  describe '.to_json' do
124
6
  it 'should cast parsed content into json' do
125
7
  p = Parser.new
@@ -1,3 +1,5 @@
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keepachangelog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Basalt AB
@@ -144,15 +144,22 @@ files:
144
144
  - bin/setup
145
145
  - exe/keepachangelog
146
146
  - features/help.feature
147
- - features/parse.feature
147
+ - features/markdown.feature
148
148
  - features/support/aruba.rb
149
149
  - features/version.feature
150
+ - features/yaml.feature
150
151
  - keepachangelog.gemspec
151
152
  - lib/keepachangelog.rb
152
153
  - lib/keepachangelog/cli.rb
154
+ - lib/keepachangelog/markdown_printer.rb
153
155
  - lib/keepachangelog/parser.rb
156
+ - lib/keepachangelog/parser/markdown.rb
157
+ - lib/keepachangelog/parser/yaml.rb
154
158
  - lib/keepachangelog/version.rb
155
159
  - package.json
160
+ - spec/markdown_printer_spec.rb
161
+ - spec/parser/markdown_spec.rb
162
+ - spec/parser/yaml_spec.rb
156
163
  - spec/parser_spec.rb
157
164
  - spec/spec_helper.rb
158
165
  - spec/version_spec.rb