renogen 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +112 -27
- 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 +22 -2
- data/lib/renogen/cli.rb +6 -4
- data/lib/renogen/config.rb +15 -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 +41 -0
- 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/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/spec_helper.rb +5 -0
- data/spec/support/renogen_helper.rb +9 -0
- metadata +15 -6
- 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
- data/spec/lib/renogen/change_log/writer_spec.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0d53b818e9ebb6f258fd39cfbe9c83acd9e9818fb49a288c11c86afe38e0f387
|
4
|
+
data.tar.gz: 1960bf0af875ef179e1f34826caf9ef56e7dec676c5bd7db44f9c05151448e53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 579845fd96294be9ef4a70ac58f7c9b6097951b8343013a7fa98f1ffc7ef42758ffa8ce7bd7b3adfb5eea23530f237032c792e887d0296f7a72e98fac2dc1203
|
7
|
+
data.tar.gz: aaa2da2cdaaa0c7ac48e3d7f8dcfbbdc82230d643c6d660a4d8453c5d8aa5eb03e84546afd7e1f154440dadabf588b14e9c9d17f1fff651f1a41cf2a047c78bf
|
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
|
11
|
+
|
12
|
+
- [Installation](#Installation)
|
13
|
+
- [Usage](#Usage)
|
14
|
+
- [Configuration](#Configuration)
|
15
|
+
- [Frequently Asked Questions](#FAQ)
|
16
|
+
- [License](#License)
|
10
17
|
|
11
|
-
|
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
|
+
```
|
26
|
+
|
27
|
+
or add the following to your Gemfile when using Bundler
|
28
|
+
|
29
|
+
```
|
30
|
+
gem 'renogen', require: false, group: :development
|
31
|
+
```
|
32
|
+
|
33
|
+
and run
|
34
|
+
|
35
|
+
```
|
36
|
+
bundle install
|
37
|
+
```
|
38
|
+
|
39
|
+
If you would prefer you can use a prebuild docker image.
|
16
40
|
|
17
|
-
|
41
|
+
Example:
|
18
42
|
|
19
|
-
|
43
|
+
```bash
|
44
|
+
$ docker run --rm -v `pwd`/.renogen:/.renogen:ro -v `pwd`/change_log:/change_log/ ddazza/renogen <CMD>
|
45
|
+
```
|
20
46
|
|
21
|
-
|
47
|
+
Now, you may initialize your repository with a `change_log` directory and a basic `.renogen` config file:
|
22
48
|
|
23
|
-
|
49
|
+
```
|
50
|
+
$ renogen init` # optional Creates directory for notes
|
51
|
+
```
|
24
52
|
|
25
|
-
|
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,77 @@ 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:
|
63
97
|
|
64
|
-
|
98
|
+
```
|
99
|
+
$ renogen new TICKET_NAME # creates ./change_log/next/TICKET_NAME.yml`
|
100
|
+
```
|
65
101
|
|
66
|
-
|
102
|
+
### Usage Examples
|
103
|
+
|
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:
|
75
131
|
|
76
|
-
|
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) | |
|
77
141
|
|
78
|
-
|
79
|
-
|
80
|
-
|
142
|
+
<a name="AllowedValues"></a>
|
143
|
+
## Allowed Values
|
144
|
+
|
145
|
+
Allowed values enables you to specify a range of allowed values for any default heading. This can be an array, string or
|
146
|
+
regular expression:
|
147
|
+
|
148
|
+
```yaml
|
149
|
+
default_headings:
|
150
|
+
- Products
|
151
|
+
- Countries
|
152
|
+
- User Facing
|
153
|
+
Products: !ruby/regexp '/\b(Foo|Bar)\b/'
|
154
|
+
Countries: [UK, AUS, FR]
|
155
|
+
User Facing: Yes
|
156
|
+
```
|
157
|
+
|
158
|
+
<a name="FAQ"></a>
|
159
|
+
## Frequently Asked Questions
|
81
160
|
|
82
161
|
### Custom formatter
|
83
162
|
|
84
163
|
You can use your own formatter quite easily.
|
85
164
|
|
86
165
|
For example, put this in `lib/my_project/renogen_formatter.rb`:
|
166
|
+
|
87
167
|
```ruby
|
88
168
|
require 'renogen/formatters'
|
89
169
|
|
@@ -114,23 +194,28 @@ end
|
|
114
194
|
|
115
195
|
You have to include that file when running renogen:
|
116
196
|
|
117
|
-
|
197
|
+
```
|
198
|
+
$ renogen -I. -Rlib/my_project/renogen_formatter 1.2.3
|
199
|
+
```
|
200
|
+
|
201
|
+
### Why does renogen not use renogen
|
118
202
|
|
119
|
-
### Why does renogen not use renogen?
|
120
203
|
The amount of activity and contributes for this project is small and so it is more practical to use a text file.
|
121
204
|
|
122
|
-
### How can I run from source
|
205
|
+
### How can I run from source
|
206
|
+
|
123
207
|
```
|
124
208
|
$ git clone git@github.com:DDAZZA/renogen.git
|
125
209
|
$ cd ./renogen/
|
126
210
|
$ bundle install
|
127
211
|
$ bundle exec ./bin/renogen test
|
128
212
|
```
|
129
|
-
|
213
|
+
|
214
|
+
## License
|
130
215
|
|
131
216
|
Renogen is a programming tool to generate a log of source code changes
|
132
217
|
|
133
|
-
Copyright (C) 2015 David Elliott
|
218
|
+
Copyright (C) 2015-2020 David Elliott
|
134
219
|
|
135
220
|
This program is free software; you can redistribute it and/or modify
|
136
221
|
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
|
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'"
|
@@ -68,6 +69,7 @@ module Renogen
|
|
68
69
|
# @param ticket_name [String]
|
69
70
|
def self.new_ticket(ticket_name)
|
70
71
|
raise 'You need to provide a ticket_name' if ticket_name.nil?
|
72
|
+
|
71
73
|
file_path = File.join(Config.instance.changelog_path, 'next', "#{ticket_name}.yml")
|
72
74
|
File.open(file_path, 'w') do |f|
|
73
75
|
Config.instance.default_headings.each do |h|
|
data/lib/renogen/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'singleton'
|
2
4
|
require 'yaml'
|
3
5
|
|
@@ -5,19 +7,20 @@ module Renogen
|
|
5
7
|
# Stores configuratin values to be used by the libary
|
6
8
|
class Config
|
7
9
|
include Singleton
|
8
|
-
attr_accessor :single_line_format, :input_source, :output_format, :supported_keys, :changelog_path,
|
10
|
+
attr_accessor :single_line_format, :input_source, :output_format, :supported_keys, :changelog_path,
|
11
|
+
:default_headings, :validations
|
9
12
|
|
10
13
|
def initialize
|
11
14
|
config_file = load_yaml_config
|
12
|
-
self.single_line_format = config_file['single_line_format'] || 'summary (see link)'
|
13
|
-
self.supported_keys = config_file['supported_keys'] ||
|
14
|
-
self.input_source = config_file['input_source'] || 'yaml'
|
15
|
-
self.output_format = config_file['output_format'] || 'markdown'
|
16
|
-
self.changelog_path = config_file['changelog_path'] || './change_log'
|
17
|
-
self.default_headings = config_file['default_headings'] || %w(Summary Detailed Tasks)
|
15
|
+
self.single_line_format = config_file['single_line_format'] || 'summary (see link)'
|
16
|
+
self.supported_keys = config_file['supported_keys'] || %w(identifier link summary)
|
17
|
+
self.input_source = config_file['input_source'] || 'yaml'
|
18
|
+
self.output_format = config_file['output_format'] || 'markdown'
|
19
|
+
self.changelog_path = config_file['changelog_path'] || './change_log'
|
20
|
+
self.default_headings = config_file['default_headings'] || %w(Summary Detailed Tasks)
|
21
|
+
self.validations = config_file['allowed_values']
|
18
22
|
end
|
19
23
|
|
20
|
-
|
21
24
|
# Renogen configuration extension
|
22
25
|
# a block can be provided to programatily setup configuration values
|
23
26
|
def self.configure
|
@@ -26,13 +29,10 @@ module Renogen
|
|
26
29
|
|
27
30
|
private
|
28
31
|
|
29
|
-
def load_yaml_config(config_file_path='.renogen')
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
{}
|
34
|
-
end
|
32
|
+
def load_yaml_config(config_file_path = '.renogen')
|
33
|
+
YAML.load_file(config_file_path)
|
34
|
+
rescue StandardError
|
35
|
+
{}
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
38
|
-
|