renogen 1.2.0 → 1.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 +5 -5
- data/README.md +119 -26
- data/lib/renogen/change_log.rb +1 -0
- data/lib/renogen/change_log/item.rb +6 -4
- data/lib/renogen/change_log/model.rb +9 -0
- data/lib/renogen/change_log/validator.rb +61 -0
- data/lib/renogen/change_log/writer.rb +35 -3
- data/lib/renogen/cli.rb +7 -4
- data/lib/renogen/config.rb +16 -15
- data/lib/renogen/exceptions.rb +5 -0
- data/lib/renogen/exceptions/invalid_item_found.rb +32 -0
- data/lib/renogen/exceptions/yaml_file_blank.rb +21 -0
- data/lib/renogen/exceptions/yaml_file_invalid.rb +20 -0
- data/lib/renogen/extraction_stratagies.rb +0 -2
- data/lib/renogen/extraction_stratagies/yaml_file.rb +0 -1
- data/lib/renogen/extraction_stratagies/yaml_file/parser.rb +5 -4
- data/lib/renogen/extraction_stratagies/yaml_file/reader.rb +20 -11
- data/lib/renogen/formatters.rb +2 -0
- data/lib/renogen/formatters/base.rb +14 -4
- data/lib/renogen/formatters/csv.rb +42 -0
- data/lib/renogen/formatters/html.rb +1 -1
- data/lib/renogen/formatters/markdown.rb +2 -2
- data/lib/renogen/formatters/markdown_table.rb +58 -0
- data/lib/renogen/generator.rb +8 -1
- data/lib/renogen/version.rb +1 -1
- data/lib/renogen/writers/csv.rb +23 -0
- data/spec/lib/renogen/change_log/item_spec.rb +1 -1
- data/spec/lib/renogen/change_log/model_spec.rb +1 -1
- data/spec/lib/renogen/change_log/validator_spec.rb +38 -0
- data/spec/lib/renogen/change_log/writer_spec.rb +199 -2
- data/spec/lib/renogen/config_spec.rb +7 -2
- data/spec/lib/renogen/exceptions/invalid_item_found_spec.rb +35 -0
- data/spec/lib/renogen/exceptions/stratagy_not_found_spec.rb +2 -1
- data/spec/lib/renogen/{extraction_stratagies/yaml_file/exceptions → exceptions}/yaml_file_blank_spec.rb +1 -1
- data/spec/lib/renogen/exceptions/yaml_file_invalid_spec.rb +12 -0
- data/spec/lib/renogen/extraction_stratagies/yaml_file/parser_spec.rb +3 -3
- data/spec/lib/renogen/extraction_stratagies/yaml_file/reader_spec.rb +11 -5
- data/spec/lib/renogen/formatters/base_spec.rb +8 -8
- data/spec/lib/renogen/formatters/csv_spec.rb +49 -0
- data/spec/lib/renogen/formatters/html_spec.rb +1 -1
- data/spec/lib/renogen/formatters/markdown_spec.rb +2 -2
- data/spec/spec_helper.rb +5 -0
- data/spec/support/renogen_helper.rb +9 -0
- metadata +17 -8
- data/lib/renogen/extraction_stratagies/yaml_file/exceptions.rb +0 -12
- data/lib/renogen/extraction_stratagies/yaml_file/exceptions/yaml_file_blank.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f41746c67c1a940656716163553293ab5ddcdc6c3d763e577ac0117df9ec0d8c
|
4
|
+
data.tar.gz: 0bffdb719fb31fac03fc669a4acf5d17692390b9dd94122f4361faac1de4fc45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3d6be1ff1031affac80ea17f0701e5db0ffe7515e622b6101ce451bd1714450484423616dc160e6c20a8692928956b5edb47c662b6c5288f1e527d0a894cf05
|
7
|
+
data.tar.gz: f81ad8c1d96c818b9786c6d3fb4dae87d810e7db9a35c073b34b934157e08e6c84bf0e4625241dbf8e62adae477919ef5744483b70d118d23821615fc38ddd58
|
data/README.md
CHANGED
@@ -2,42 +2,76 @@
|
|
2
2
|
|
3
3
|
Renogen or Re(lease) No(tes) Gen(erator) is a development tool to separate feature notes from product versions.
|
4
4
|
|
5
|
-
|
6
5
|
This renogen can not do and will have to be reviewed manually
|
6
|
+
|
7
7
|
- Order the notes in the orrect order (e.g. if a task has to be run before/after something else)
|
8
8
|
- Remove Duplicate notes that might be added (e.g. 2 tickets might want to run the same task)
|
9
9
|
|
10
|
+
## Contents
|
10
11
|
|
11
|
-
|
12
|
+
- [Installation](#Installation)
|
13
|
+
- [Usage](#Usage)
|
14
|
+
- [Configuration](#Configuration)
|
15
|
+
- [Frequently Asked Questions](#FAQ)
|
16
|
+
- [License](#License)
|
17
|
+
|
18
|
+
<a name="Installation"></a>
|
19
|
+
## Installation
|
12
20
|
|
13
21
|
To install Renogen, use the following command:
|
14
22
|
|
15
|
-
|
23
|
+
```
|
24
|
+
$ gem install renogen
|
25
|
+
```
|
16
26
|
|
17
|
-
or add the following to your Gemfile
|
27
|
+
or add the following to your Gemfile when using Bundler
|
18
28
|
|
19
|
-
|
29
|
+
```
|
30
|
+
gem 'renogen', require: false, group: :development
|
31
|
+
```
|
20
32
|
|
21
|
-
|
33
|
+
and run
|
22
34
|
|
23
|
-
|
35
|
+
```
|
36
|
+
bundle install
|
37
|
+
```
|
38
|
+
|
39
|
+
If you would prefer you can use a prebuild docker image.
|
40
|
+
|
41
|
+
Example:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
$ docker run --rm -v `pwd`/.renogen:/.renogen:ro -v `pwd`/change_log:/change_log/ ddazza/renogen <CMD>
|
45
|
+
```
|
24
46
|
|
25
|
-
|
47
|
+
Now, you may initialize your repository with a `change_log` directory and a basic `.renogen` config file:
|
48
|
+
|
49
|
+
```
|
50
|
+
$ renogen init` # optional Creates directory for notes
|
51
|
+
```
|
52
|
+
|
53
|
+
<a name="Usage"></a>
|
54
|
+
## Usage
|
26
55
|
|
27
56
|
To generate your notes run the following command
|
28
57
|
|
29
|
-
|
58
|
+
```
|
59
|
+
$ renogen <VERSION> # e.g v1.2.1
|
60
|
+
```
|
30
61
|
|
31
62
|
Unfortunatly renogen cant write documentation for your change.
|
32
63
|
By default renogen uses the yaml file stratagy to extract your notes
|
33
64
|
|
34
|
-
|
65
|
+
```
|
66
|
+
$ renogen --help # list available command options
|
67
|
+
```
|
68
|
+
|
69
|
+
### Adding YAML feature notes
|
35
70
|
|
36
|
-
|
71
|
+
You can create a new file within the 'next' version folder (default: `change_log/next/`) manually:
|
37
72
|
|
38
|
-
|
73
|
+
Example feature note:
|
39
74
|
|
40
|
-
Example feature note
|
41
75
|
```yaml
|
42
76
|
# change_log/next/example.yml
|
43
77
|
my_formatted_single_line:
|
@@ -59,31 +93,78 @@ my_list:
|
|
59
93
|
- e.g. run this as well
|
60
94
|
```
|
61
95
|
|
62
|
-
|
96
|
+
You can also use the `new` command to create a feature note YAML file in the 'next' version folder:
|
97
|
+
|
98
|
+
```
|
99
|
+
$ renogen new TICKET_NAME # creates ./change_log/next/TICKET_NAME.yml`
|
100
|
+
```
|
63
101
|
|
64
|
-
|
102
|
+
### Usage Examples
|
65
103
|
|
66
|
-
|
104
|
+
Prepend your notes to a changelog file (TODO make command simple)
|
105
|
+
|
106
|
+
```
|
107
|
+
$ renogen --format markdown v1.2.1 > CHANGELOG.md | cat - CHANGELOG > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG
|
108
|
+
```
|
67
109
|
|
68
110
|
Writes notes to html file
|
69
111
|
|
70
|
-
|
112
|
+
```
|
113
|
+
$ renogen --format html v1.2.1 > v1_2_1.html
|
114
|
+
```
|
115
|
+
|
116
|
+
Writes note to csv file
|
117
|
+
|
118
|
+
`$ renogen --format csv v1.2.1 > v1_2_1.csv`
|
71
119
|
|
72
120
|
Print all notes since v1.0.0 as text
|
73
121
|
|
74
|
-
|
122
|
+
```
|
123
|
+
$ renogen --format text -l v1.0.0 v1.2.1
|
124
|
+
```
|
125
|
+
|
126
|
+
<a name="Configuration"></a>
|
127
|
+
## Configuration
|
128
|
+
|
129
|
+
Renogen tries to read the file `.renogen` in the working directory to load its configuration. The file is in YAML format
|
130
|
+
with the following keys:
|
131
|
+
|
132
|
+
| key | meaning | default value | configuration example |
|
133
|
+
|----------------------|----------|---------------|-----------------------|
|
134
|
+
| `single_line_format` | A template for generating a single line of text from a YAML dictionary in a feature note file. Each dictionary key in the template gets replaced by the value for that key. | `summary (see link)` | `[#ticket](https://github.com/renogen/issue/ticket): summary` |
|
135
|
+
| `supported_keys` | YAML dictionary keys allowed in dictionary feature notes. Ignored for dictionaries where rules apply. | `%w[identifier summary link]` | |
|
136
|
+
| `input_source` | The format of the feature note files. Currently, only `yaml` is supported. | `yaml` | |
|
137
|
+
| `output_format` | The default output format when generating release notes. | `markdown` | `html` |
|
138
|
+
| `changelog_path` | The directory where the feature note files are stored. | `./change_log` | `./doc/src/changes` |
|
139
|
+
| `default_headings` | The headings/group names that will be printed into a feature note file created by the `new` command. Ignored when there is a rule defined for the given file name. | `%w[Summary Detailed Tasks]` | `%w[Title Description Deployment]` |
|
140
|
+
| `allowed_values` | Allowed values for default headings. See [Allowed Values](#AllowedValues). | `{}` (none) | |
|
141
|
+
| `remove_duplicates` | Remove duplicate items from output release notes. Not applicable when using table formats (e.g`csv` or `markdown_table`). | `false` | |
|
75
142
|
|
76
|
-
|
143
|
+
<a name="AllowedValues"></a>
|
144
|
+
## Allowed Values
|
77
145
|
|
78
|
-
|
79
|
-
|
80
|
-
|
146
|
+
Allowed values enables you to specify a range of allowed values for any default heading. This can be an array, string or
|
147
|
+
regular expression:
|
148
|
+
|
149
|
+
```yaml
|
150
|
+
default_headings:
|
151
|
+
- Products
|
152
|
+
- Countries
|
153
|
+
- User Facing
|
154
|
+
Products: !ruby/regexp '/\b(Foo|Bar)\b/'
|
155
|
+
Countries: [UK, AUS, FR]
|
156
|
+
User Facing: Yes
|
157
|
+
```
|
158
|
+
|
159
|
+
<a name="FAQ"></a>
|
160
|
+
## Frequently Asked Questions
|
81
161
|
|
82
162
|
### Custom formatter
|
83
163
|
|
84
164
|
You can use your own formatter quite easily.
|
85
165
|
|
86
166
|
For example, put this in `lib/my_project/renogen_formatter.rb`:
|
167
|
+
|
87
168
|
```ruby
|
88
169
|
require 'renogen/formatters'
|
89
170
|
|
@@ -114,16 +195,28 @@ end
|
|
114
195
|
|
115
196
|
You have to include that file when running renogen:
|
116
197
|
|
117
|
-
|
198
|
+
```
|
199
|
+
$ renogen -I. -Rlib/my_project/renogen_formatter 1.2.3
|
200
|
+
```
|
201
|
+
|
202
|
+
### Why does renogen not use renogen
|
118
203
|
|
119
|
-
### Why does renogen not use renogen?
|
120
204
|
The amount of activity and contributes for this project is small and so it is more practical to use a text file.
|
121
205
|
|
122
|
-
###
|
206
|
+
### How can I run from source
|
207
|
+
|
208
|
+
```
|
209
|
+
$ git clone git@github.com:DDAZZA/renogen.git
|
210
|
+
$ cd ./renogen/
|
211
|
+
$ bundle install
|
212
|
+
$ bundle exec ./bin/renogen test
|
213
|
+
```
|
214
|
+
|
215
|
+
## License
|
123
216
|
|
124
217
|
Renogen is a programming tool to generate a log of source code changes
|
125
218
|
|
126
|
-
Copyright (C) 2015 David Elliott
|
219
|
+
Copyright (C) 2015-2020 David Elliott
|
127
220
|
|
128
221
|
This program is free software; you can redistribute it and/or modify
|
129
222
|
it under the terms of the GNU General Public License as published by
|
data/lib/renogen/change_log.rb
CHANGED
@@ -3,9 +3,10 @@ module Renogen
|
|
3
3
|
# Object to represent single change item
|
4
4
|
class Item
|
5
5
|
attr_accessor :change
|
6
|
-
attr_reader :group_name
|
6
|
+
attr_reader :group_name, :ticket_id
|
7
7
|
|
8
|
-
def initialize(group_name, change, options={})
|
8
|
+
def initialize(ticket_id, group_name, change, options={})
|
9
|
+
@ticket_id = ticket_id
|
9
10
|
@group_name = group_name
|
10
11
|
@change = change
|
11
12
|
end
|
@@ -15,6 +16,7 @@ module Renogen
|
|
15
16
|
# @return [String]
|
16
17
|
def to_s
|
17
18
|
return '' unless change
|
19
|
+
|
18
20
|
case change.class.to_s
|
19
21
|
when 'String'
|
20
22
|
format_multiline(change)
|
@@ -46,12 +48,12 @@ module Renogen
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def format_array(change)
|
49
|
-
# TODO should return a string
|
51
|
+
# TODO: should return a string
|
50
52
|
change
|
51
53
|
end
|
52
54
|
|
53
55
|
def format_oneline(change)
|
54
|
-
# TODO Refactor
|
56
|
+
# TODO: Refactor
|
55
57
|
string = config.single_line_format.downcase.gsub('\n', '\n ')
|
56
58
|
config.supported_keys.each do |key|
|
57
59
|
string = string.gsub(key, '#{change[\'' + key + '\']}')
|
@@ -22,6 +22,15 @@ module Renogen
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# @return [Hash<ticket id: string>]
|
26
|
+
def tickets
|
27
|
+
items.inject({}) do |hash, change|
|
28
|
+
hash[change.ticket_id] ||= {}
|
29
|
+
hash[change.ticket_id][change.group_name] = change.to_s
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
25
34
|
# Adds a change to the changelog
|
26
35
|
#
|
27
36
|
# @param change [Renogen::ChangeLog::Item]
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renogen
|
4
|
+
module ChangeLog
|
5
|
+
# Validates the change log
|
6
|
+
class Validator
|
7
|
+
def initialize(formatter)
|
8
|
+
@formatter = formatter
|
9
|
+
@validations = formatter.options['allowed_values']
|
10
|
+
end
|
11
|
+
|
12
|
+
# Validates the change log
|
13
|
+
#
|
14
|
+
# @param changelog [ChangeLog::Model]
|
15
|
+
def validate!(changelog)
|
16
|
+
validate_headings(changelog)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
attr_reader :formatter, :validations
|
22
|
+
|
23
|
+
def validate_headings(changelog)
|
24
|
+
return if validations.nil?
|
25
|
+
return if changelog.items.none? { |item| validations.key?(item.group_name) }
|
26
|
+
|
27
|
+
validate_properties(changelog)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def validate_properties(changelog)
|
33
|
+
invalid_items = []
|
34
|
+
validations.each do |heading, values|
|
35
|
+
items_to_select = changelog.items.select { |log| log.group_name == heading }
|
36
|
+
invalid_values = items_to_select.map do |i|
|
37
|
+
changes = changes_to_validate(i.change)
|
38
|
+
next changes - values if values.is_a?(Array)
|
39
|
+
next unless values.is_a?(Regexp)
|
40
|
+
|
41
|
+
changes.detect { |c| c !~ values } # return anything that does not match the regexp.
|
42
|
+
end
|
43
|
+
|
44
|
+
invalid_values = invalid_values.flatten.compact.uniq # remove duplicates and nils
|
45
|
+
next if invalid_values.empty?
|
46
|
+
|
47
|
+
invalid_items << { invalid_value: invalid_values, valid_values: values, group_name: heading }
|
48
|
+
end
|
49
|
+
|
50
|
+
invalid_items = invalid_items.flatten
|
51
|
+
raise(Renogen::Exceptions::InvalidItemFound, invalid_items) unless invalid_items.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
def changes_to_validate(change)
|
55
|
+
return [change] if change.is_a? String
|
56
|
+
|
57
|
+
change
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -10,9 +10,29 @@ module Renogen
|
|
10
10
|
#
|
11
11
|
# @param changelog [ChangeLog::Model]
|
12
12
|
def write!(changelog)
|
13
|
-
puts formatter.write_header(formatter.header(changelog))
|
13
|
+
puts formatter.write_header(formatter.header(changelog)) unless formatter.write_header(formatter.header(changelog)).nil?
|
14
|
+
if formatter.table_formatter?
|
15
|
+
write_by_table!(changelog)
|
16
|
+
else
|
17
|
+
write_by_group!(changelog)
|
18
|
+
end
|
19
|
+
puts formatter.write_footer(changelog) unless formatter.write_footer(changelog).nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Writes out the change log by group
|
23
|
+
#
|
24
|
+
# @param changelog [ChangeLog::Model]
|
25
|
+
def write_by_group!(changelog)
|
14
26
|
output_groups(changelog.groups)
|
15
|
-
|
27
|
+
end
|
28
|
+
|
29
|
+
# Writes out the change log by item
|
30
|
+
#
|
31
|
+
# @param changelog [ChangeLog::Model]
|
32
|
+
def write_by_table!(changelog)
|
33
|
+
changelog.tickets.each do |_, ticket|
|
34
|
+
puts formatter.write_change(ticket)
|
35
|
+
end
|
16
36
|
end
|
17
37
|
|
18
38
|
protected
|
@@ -30,10 +50,22 @@ module Renogen
|
|
30
50
|
def output_groups(groups)
|
31
51
|
groups.each do |group, changes|
|
32
52
|
puts formatter.write_group(group)
|
33
|
-
changes.each { |change| output_change(change) }
|
53
|
+
deduped_changes(changes).each { |change| output_change(change) }
|
34
54
|
puts formatter.write_group_end
|
35
55
|
end
|
36
56
|
end
|
57
|
+
|
58
|
+
def deduped_changes(changes)
|
59
|
+
return changes unless config.remove_duplicates
|
60
|
+
|
61
|
+
changes.uniq { |c| c.to_s }
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def config
|
67
|
+
Config.instance
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
39
71
|
end
|
data/lib/renogen/cli.rb
CHANGED
@@ -21,26 +21,27 @@ module Renogen
|
|
21
21
|
options['changelog_path'] ||= config_instance.changelog_path
|
22
22
|
options['old_version'] ||= config_instance.changelog_path
|
23
23
|
options['release_date'] ||= Date.today
|
24
|
+
options['allowed_values'] ||= config_instance.validations
|
24
25
|
|
25
26
|
begin
|
26
27
|
generator = Renogen::Generator.new(version, source, format, options)
|
27
28
|
generator.generate!
|
28
29
|
rescue Renogen::Exceptions::Base => e
|
29
30
|
puts e.message
|
30
|
-
exit
|
31
|
+
exit 1
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
35
|
# Initialize the current working directory with an example change
|
35
36
|
def self.init
|
36
|
-
# TODO Refactor to use Config.instance.changelog_path
|
37
|
+
# TODO: Refactor to use Config.instance.changelog_path
|
37
38
|
Dir.mkdir('./change_log')
|
38
39
|
puts "Created './change_log/'"
|
39
40
|
|
40
41
|
Dir.mkdir('./change_log/next')
|
41
42
|
puts "Created './change_log/next/'"
|
42
43
|
|
43
|
-
File.open(
|
44
|
+
File.open('./change_log/next/added_renogen_gem.yml', 'w') do |f|
|
44
45
|
f.write("Summary:\n")
|
45
46
|
f.write(" identifier: renogen\n")
|
46
47
|
f.write(" link: https://github.com/DDAZZA/renogen\n")
|
@@ -57,7 +58,7 @@ module Renogen
|
|
57
58
|
|
58
59
|
puts "Created './change_log/next/added_renogen_gem.yml'"
|
59
60
|
|
60
|
-
File.open(
|
61
|
+
File.open('.renogen', 'w') do |f|
|
61
62
|
f.write("changelog_path: './change_log/'\n")
|
62
63
|
end
|
63
64
|
puts "Created '.renogen'"
|
@@ -67,6 +68,8 @@ module Renogen
|
|
67
68
|
#
|
68
69
|
# @param ticket_name [String]
|
69
70
|
def self.new_ticket(ticket_name)
|
71
|
+
raise 'You need to provide a ticket_name' if ticket_name.nil?
|
72
|
+
|
70
73
|
file_path = File.join(Config.instance.changelog_path, 'next', "#{ticket_name}.yml")
|
71
74
|
File.open(file_path, 'w') do |f|
|
72
75
|
Config.instance.default_headings.each do |h|
|