sheep-a-changelog 0.1.4 → 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 +4 -4
- data/README.md +123 -0
- data/VERSION +1 -1
- data/lib/sheep-a-changelog.rb +5 -0
- data/lib/sheep-a-changelog/document.rb +63 -0
- data/lib/sheep-a-changelog/node.rb +27 -17
- data/lib/sheep-a-changelog/parser.rb +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97b4d535fc2e01b02db09270df9394f32fba28ae90dbb8afdee687484e2a5bc8
|
4
|
+
data.tar.gz: 790a3e1a6569d44473852c6e3f23eb53229c5d75e377474938e9745253599202
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54c466cde177deb6d832c62bf9be2481faa23b9e802bfb48415d41fa21bcd4bc769cbe1cdd00123bedc7468d79f52730de914e2ef8514beebc334eedd403a4b6
|
7
|
+
data.tar.gz: 362c51c13e2010ced70fd7524a17fd867b6cf4312b8a85c32c536bad070519661b8c828e58c3d7376dc7aeee1be767d731d7c1d222e95a24700648caf6e0142a
|
data/README.md
CHANGED
@@ -12,5 +12,128 @@
|
|
12
12
|
|
13
13
|
:sheep: Simple, particular, example driven parser of keep-a-changelog format.
|
14
14
|
|
15
|
+
## About
|
15
16
|
|
16
17
|
Parse a markdown changelog in [keep-a-changelog](https://keepachangelog.com) format to the optimal resolution depth to perform semantic tasks.
|
18
|
+
|
19
|
+
## Install
|
20
|
+
|
21
|
+
See [RubyGems](https://rubygems.org/gems/sheep-a-changelog) for installation instructions (simply add to your Gemfile).
|
22
|
+
|
23
|
+
Sheep-a-changelog requires at least ruby 2.2, and is [tested](https://travis-ci.com/grissius/sheep-a-changelog) on several minor versions up to 2.5.
|
24
|
+
|
25
|
+
## Getting started
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'sheep-a-changelog'
|
29
|
+
|
30
|
+
# Load keep-a-changelog markdown file as a string
|
31
|
+
contents = File.read('./path/to/CHANGELOG.md')
|
32
|
+
|
33
|
+
# Create an abstraction for it using the parser
|
34
|
+
# SheepAChangelog.parse: string -> SheepAChangelog.Node
|
35
|
+
doc = SheepAChangelog.parse(contents)
|
36
|
+
|
37
|
+
# TODO temper with the structure
|
38
|
+
# See features section
|
39
|
+
|
40
|
+
# Serialize back to string
|
41
|
+
updated = doc.to_s
|
42
|
+
|
43
|
+
# Save back
|
44
|
+
File.write('./path/to/CHANGELOG.md', updated)
|
45
|
+
```
|
46
|
+
|
47
|
+
## Features
|
48
|
+
|
49
|
+
### Release
|
50
|
+
This method performs the following actions:
|
51
|
+
- Rename current _unreleased_ version log to _new version_
|
52
|
+
- Add anchor for _new version_
|
53
|
+
- Add empty _unreleased_
|
54
|
+
- Update _unreleased_ anchor
|
55
|
+
|
56
|
+
It accepts arguments
|
57
|
+
1. `new_version` - semver format
|
58
|
+
2. `tag_prefix` - prefix for `new_version` for git tags (used for anchors). Defaults to `v`
|
59
|
+
3. `date` - date of the release, defaults to now
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
doc.release('2.0.0', 'v', Time.utc(2017, 6, 20))
|
63
|
+
```
|
64
|
+
|
65
|
+
|
66
|
+
### Inspect element
|
67
|
+
```ruby
|
68
|
+
node.build_tree
|
69
|
+
# :title - heading (string) or :empty for top-level node
|
70
|
+
# :lines - string[] of contents belonging to this node, without anchors and child nodes
|
71
|
+
# :anchors - { :v, :url } of anchor nodes
|
72
|
+
# :nodes - child nodes
|
73
|
+
```
|
74
|
+
```yaml
|
75
|
+
:title: :empty
|
76
|
+
:lines: []
|
77
|
+
:anchors:
|
78
|
+
- :v: Unreleased
|
79
|
+
:url: https://github.com/olivierlacan/keep-a-changelog/compare/v1.0.0...HEAD
|
80
|
+
- :v: 1.0.0
|
81
|
+
:url: https://github.com/olivierlacan/keep-a-changelog/compare/v0.3.0...v1.0.0
|
82
|
+
:nodes:
|
83
|
+
- :title: Changelog
|
84
|
+
:lines:
|
85
|
+
- All notable changes to this project will be documented in this file.
|
86
|
+
- ''
|
87
|
+
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
88
|
+
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
89
|
+
- ''
|
90
|
+
:anchors: []
|
91
|
+
:nodes:
|
92
|
+
- :title: "[1.0.0] - 2017-06-20"
|
93
|
+
:lines: []
|
94
|
+
:anchors: []
|
95
|
+
:nodes:
|
96
|
+
- :title: Added
|
97
|
+
:lines:
|
98
|
+
- '- "Frequently Asked Questions" section.'
|
99
|
+
- ''
|
100
|
+
:anchors: []
|
101
|
+
:nodes: []
|
102
|
+
```
|
103
|
+
|
104
|
+
### Latest version title
|
105
|
+
Returns the contents of the heading for the latest version.
|
106
|
+
```ruby
|
107
|
+
doc.latest_version_title
|
108
|
+
# --> "[1.0.0] - 2017-06-20"
|
109
|
+
```
|
110
|
+
|
111
|
+
### Diff prefix
|
112
|
+
Returns URL prefix for the anchors. If multiple used, return the most frequent.
|
113
|
+
```ruby
|
114
|
+
doc.diff_prefix
|
115
|
+
# --> "https://github.com/olivierlacan/keep-a-changelog/compare/"
|
116
|
+
```
|
117
|
+
|
118
|
+
### Rename version
|
119
|
+
Rename version. Looking for exact match. This only changes the title and keeps the contents (inlcuding all children intact.)
|
120
|
+
```ruby
|
121
|
+
doc.rename_version('[Unreleased]', new_version)
|
122
|
+
```
|
123
|
+
|
124
|
+
### Add anchor
|
125
|
+
```ruby
|
126
|
+
doc.add_anchor('LABEL', 'vFROM', 'vTO')
|
127
|
+
# adds "[LABEL]: {diff_prefix}/vFROM...vTO" as the topmost anchor
|
128
|
+
```
|
129
|
+
|
130
|
+
## Todo
|
131
|
+
|
132
|
+
- :heavy_check_mark: Ensure unreleased
|
133
|
+
- :heavy_check_mark: Release
|
134
|
+
- :construction: Initialize
|
135
|
+
- :construction: Sort type sections
|
136
|
+
- :construction: Fix typos in type sections
|
137
|
+
|
138
|
+
## License
|
139
|
+
Licensed under [MIT](./LICENSE)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/sheep-a-changelog.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'node'
|
2
|
+
|
3
|
+
module SheepAChangelog
|
4
|
+
class Document < Node
|
5
|
+
def initialize(lines)
|
6
|
+
super(lines, :empty, 0)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Return parent node to version nodes
|
10
|
+
def version_root
|
11
|
+
nodes.first
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return title of the latest version node
|
15
|
+
def latest_version_title(n = 0)
|
16
|
+
version_root.nodes[n].title
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return the latest version
|
20
|
+
def latest_version(n = 0)
|
21
|
+
latest_version_title(n).match(/^\[(\S+)\].*/).to_a[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_empty_version(name)
|
25
|
+
version_root.nodes.unshift(Node.new([''], name, 2))
|
26
|
+
end
|
27
|
+
|
28
|
+
def diff_prefix
|
29
|
+
anchors.map { |a| a[:url].match(%r{^(.*\/)(.*\.\.\..*)$}).to_a[1] }
|
30
|
+
.each_with_object(Hash.new(0)) { |word, counts| counts[word] += 1 }
|
31
|
+
.to_a
|
32
|
+
.min { |a, b| b[1] <=> a[1] }
|
33
|
+
.first
|
34
|
+
end
|
35
|
+
|
36
|
+
def rename_version(from, to)
|
37
|
+
parent = version_root
|
38
|
+
parent.nodes.map! do |node|
|
39
|
+
if node.title == from
|
40
|
+
Node.new(node.all_lines_wo_heading.first, to, 2)
|
41
|
+
else
|
42
|
+
node
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_anchor(name, from, to)
|
48
|
+
anchors.unshift(v: name, url: "#{diff_prefix}#{from}...#{to}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def remove_anchor_unreleased
|
52
|
+
anchors.reject! { |a| a[:v] == 'Unreleased' }
|
53
|
+
end
|
54
|
+
|
55
|
+
def release(version, tag_prefix, t = Time.now)
|
56
|
+
remove_anchor_unreleased
|
57
|
+
rename_version('[Unreleased]', "[#{version}] - #{t.strftime('%Y-%m-%d')}")
|
58
|
+
add_anchor(version, tag_prefix + latest_version(1), version)
|
59
|
+
add_empty_version('[Unreleased]')
|
60
|
+
add_anchor('Unreleased', tag_prefix + version, 'HEAD')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module SheepAChangelog
|
2
2
|
class Node
|
3
|
-
|
3
|
+
attr_reader :lines, :title, :anchors
|
4
|
+
attr_accessor :nodes
|
4
5
|
def self.parse(string)
|
5
6
|
new(string.split("\n"))
|
6
7
|
end
|
@@ -34,23 +35,26 @@ module SheepAChangelog
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def self.pick_lines(lines)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
anchor_lines << line
|
42
|
-
else
|
43
|
-
content_lines << line
|
44
|
-
end
|
38
|
+
# add matches for links
|
39
|
+
groups_lines = lines.inject([]) do |acc, line|
|
40
|
+
groups = line.match(/^\[(.*)\]\s*:\s*(\S+)\s*$/).to_a
|
41
|
+
acc + [[groups, line]]
|
45
42
|
end
|
46
|
-
|
43
|
+
# if no matches, it is content lines
|
44
|
+
content_lines = groups_lines
|
45
|
+
.select { |x| x.first.empty? }.map { |_, l| l }
|
46
|
+
# if matches, it is link
|
47
|
+
anchors = groups_lines
|
48
|
+
.reject { |x| x.first.empty? }
|
49
|
+
.map { |groups, _| { v: groups[1], url: groups[2] } }
|
50
|
+
[content_lines, anchors]
|
47
51
|
end
|
48
52
|
|
49
53
|
# Create node hierarchy from keep-a-changeloh markdown lines
|
50
|
-
def initialize(lines, title
|
51
|
-
content_lines,
|
54
|
+
def initialize(lines, title, level)
|
55
|
+
content_lines, anchors = Node.pick_lines(lines)
|
52
56
|
@title = title
|
53
|
-
@
|
57
|
+
@anchors = anchors
|
54
58
|
@nodes = build_nodes(content_lines, level + 1)
|
55
59
|
@level = level
|
56
60
|
end
|
@@ -67,9 +71,15 @@ module SheepAChangelog
|
|
67
71
|
def all_lines
|
68
72
|
res = []
|
69
73
|
res << format_heading if @title != :empty
|
70
|
-
res +=
|
71
|
-
res
|
72
|
-
|
74
|
+
res += all_lines_wo_heading
|
75
|
+
res
|
76
|
+
end
|
77
|
+
|
78
|
+
def all_lines_wo_heading
|
79
|
+
res = []
|
80
|
+
res += @lines
|
81
|
+
res += @nodes.map(&:all_lines)
|
82
|
+
res += @anchors.map { |a| "[#{a[:v]}]: #{a[:url]}" }
|
73
83
|
res
|
74
84
|
end
|
75
85
|
|
@@ -82,7 +92,7 @@ module SheepAChangelog
|
|
82
92
|
def build_tree
|
83
93
|
{ title: @title,
|
84
94
|
lines: @lines,
|
85
|
-
|
95
|
+
anchors: @anchors,
|
86
96
|
nodes: @nodes.map(&:build_tree) }
|
87
97
|
end
|
88
98
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sheep-a-changelog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jaroslav Šmolík
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coveralls
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- README.md
|
119
119
|
- VERSION
|
120
120
|
- lib/sheep-a-changelog.rb
|
121
|
+
- lib/sheep-a-changelog/document.rb
|
121
122
|
- lib/sheep-a-changelog/meta.rb
|
122
123
|
- lib/sheep-a-changelog/node.rb
|
123
124
|
- lib/sheep-a-changelog/parser.rb
|
@@ -141,8 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
142
|
- !ruby/object:Gem::Version
|
142
143
|
version: '0'
|
143
144
|
requirements: []
|
144
|
-
|
145
|
-
rubygems_version: 2.7.7
|
145
|
+
rubygems_version: 3.0.2
|
146
146
|
signing_key:
|
147
147
|
specification_version: 4
|
148
148
|
summary: Simple, particular, example driven parser of keep-a-changelog format.
|