renogen 1.0.0 → 1.3.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 +5 -5
- data/README.md +162 -23
- data/lib/renogen/change_log.rb +1 -0
- data/lib/renogen/change_log/item.rb +10 -7
- data/lib/renogen/change_log/model.rb +11 -8
- data/lib/renogen/change_log/validator.rb +61 -0
- data/lib/renogen/change_log/writer.rb +23 -3
- data/lib/renogen/cli.rb +28 -7
- data/lib/renogen/cli/param_parser.rb +19 -3
- data/lib/renogen/config.rb +15 -14
- 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 +32 -7
- data/lib/renogen/formatters/csv.rb +41 -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 +9 -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 +8 -1
- data/spec/lib/renogen/change_log/model_spec.rb +22 -8
- 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 +14 -4
- 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
- data/spec/lib/renogen/change_log/writer_spec.rb +0 -8
@@ -17,10 +17,14 @@ module Renogen
|
|
17
17
|
args = Hash.new
|
18
18
|
|
19
19
|
opt_parser = OptionParser.new do |opts|
|
20
|
-
opts.banner =
|
20
|
+
opts.banner = "Usage:"
|
21
|
+
opts.separator " renogen [options] VERSION"
|
22
|
+
opts.separator " renogen new TICKET_NAME"
|
23
|
+
opts.separator " renogen init"
|
21
24
|
opts.separator ""
|
22
25
|
opts.separator "Required:"
|
23
|
-
opts.separator " VERSION
|
26
|
+
opts.separator " VERSION this is the version that is currently being required:"
|
27
|
+
opts.separator " TICKET_NAME this is the name of the new ticket to be created:"
|
24
28
|
opts.separator ""
|
25
29
|
opts.separator "Options:"
|
26
30
|
|
@@ -40,6 +44,18 @@ module Renogen
|
|
40
44
|
args['legacy_version'] = n
|
41
45
|
end
|
42
46
|
|
47
|
+
opts.on("-rDATE", "--release-date=DATE", "Release date") do |n|
|
48
|
+
args['release_date'] = n
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on("-IPATH", "--include=PATH", "Add a path to the load path") do |n|
|
52
|
+
$LOAD_PATH << n
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("-RFILE", "--require=FILE", "Require a file from the load path") do |n|
|
56
|
+
require n
|
57
|
+
end
|
58
|
+
|
43
59
|
opts.on_tail("-h", "--help", "Show this message") do
|
44
60
|
puts opts
|
45
61
|
exit
|
@@ -55,7 +71,7 @@ module Renogen
|
|
55
71
|
|
56
72
|
new_version = options.shift
|
57
73
|
if new_version.nil?
|
58
|
-
puts "Error: Missing argument
|
74
|
+
puts "Error: Missing argument"
|
59
75
|
puts
|
60
76
|
puts opt_parser
|
61
77
|
exit 1
|
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,18 +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']
|
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']
|
17
22
|
end
|
18
23
|
|
19
|
-
|
20
24
|
# Renogen configuration extension
|
21
25
|
# a block can be provided to programatily setup configuration values
|
22
26
|
def self.configure
|
@@ -25,13 +29,10 @@ module Renogen
|
|
25
29
|
|
26
30
|
private
|
27
31
|
|
28
|
-
def load_yaml_config(config_file_path='.renogen')
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
{}
|
33
|
-
end
|
32
|
+
def load_yaml_config(config_file_path = '.renogen')
|
33
|
+
YAML.load_file(config_file_path)
|
34
|
+
rescue StandardError
|
35
|
+
{}
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
37
|
-
|
data/lib/renogen/exceptions.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Renogen
|
2
4
|
# Custom exceptions throw by the libary
|
3
5
|
module Exceptions
|
4
6
|
require_relative 'exceptions/base'
|
5
7
|
require_relative 'exceptions/stratagy_not_found'
|
8
|
+
require_relative 'exceptions/invalid_item_found'
|
9
|
+
require_relative 'exceptions/yaml_file_blank'
|
10
|
+
require_relative 'exceptions/yaml_file_invalid'
|
6
11
|
end
|
7
12
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renogen
|
4
|
+
module Exceptions
|
5
|
+
# Raised when change log contains invalid items.
|
6
|
+
class InvalidItemFound < Base
|
7
|
+
attr_reader :invalid_items
|
8
|
+
|
9
|
+
def initialize(invalid_items)
|
10
|
+
@invalid_items = invalid_items
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
# Friendly error message
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
def message
|
18
|
+
messages = ['Invalid items:']
|
19
|
+
invalid_items.each do |item|
|
20
|
+
invalid_value = item[:invalid_value]
|
21
|
+
|
22
|
+
messages << if item[:valid_values].is_a?(Regexp)
|
23
|
+
"Group: #{item[:group_name]}, Content: #{invalid_value}, Pattern: #{item[:valid_values].inspect}"
|
24
|
+
else
|
25
|
+
"Group: #{item[:group_name]}, Content: #{invalid_value}, Valid Values: #{item[:valid_values]}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
messages.join("\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Renogen
|
2
|
+
module Exceptions
|
3
|
+
# This is raised when a yaml file change is found but has not contents
|
4
|
+
class YamlFileBlank < Renogen::Exceptions::Base
|
5
|
+
attr_reader :file_path
|
6
|
+
|
7
|
+
def initialize(file_path)
|
8
|
+
@file_path = file_path
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
# Friendly error message
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
def message
|
16
|
+
"Error: File contents blank '#{file_path}'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Renogen
|
2
|
+
module Exceptions
|
3
|
+
# This is raised when a yaml file change is found but has invalid contents
|
4
|
+
class YamlFileInvalid < Renogen::Exceptions::Base
|
5
|
+
attr_reader :file_path
|
6
|
+
|
7
|
+
def initialize(file_path)
|
8
|
+
@file_path = file_path
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
# Friendly error message
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
def message
|
16
|
+
"Error: File contents invalid '#{file_path}'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -13,8 +13,8 @@ module Renogen
|
|
13
13
|
|
14
14
|
# @return [ChangeLog::Model]
|
15
15
|
def parse!
|
16
|
-
yaml_file_reader.each_yaml_file do |file|
|
17
|
-
parse_file(file)
|
16
|
+
yaml_file_reader.each_yaml_file do |file, index|
|
17
|
+
parse_file(index, file)
|
18
18
|
end
|
19
19
|
changelog
|
20
20
|
end
|
@@ -23,9 +23,10 @@ module Renogen
|
|
23
23
|
|
24
24
|
attr_reader :yaml_file_reader
|
25
25
|
|
26
|
-
|
26
|
+
# @param [Hash] data
|
27
|
+
def parse_file(id, file)
|
27
28
|
file.each do |group_name, content|
|
28
|
-
changelog.add_change(ChangeLog::Item.new(group_name, content))
|
29
|
+
changelog.add_change(ChangeLog::Item.new(id, group_name, content))
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
|
3
5
|
module Renogen
|
@@ -7,23 +9,28 @@ module Renogen
|
|
7
9
|
class Reader
|
8
10
|
attr_accessor :directory_path, :legacy_version
|
9
11
|
|
10
|
-
def initialize(directory_path, options={})
|
12
|
+
def initialize(directory_path, options = {})
|
11
13
|
@legacy_version = options['legacy_version']
|
12
14
|
@directory_path = directory_path
|
13
15
|
@directory_path ||= './change_log/'
|
14
16
|
end
|
15
17
|
|
16
18
|
# Iterates thorugh each change file and yields the contents.
|
17
|
-
#
|
18
|
-
# an exception is thrown if the contents are blank
|
19
|
+
#
|
20
|
+
# an exception is thrown if the contents are blank or invalid
|
19
21
|
#
|
20
22
|
# @yield [Hash] yaml_file
|
21
23
|
def each_yaml_file
|
22
|
-
|
24
|
+
path = ''
|
25
|
+
change_directories.each_with_index do |file_path, i|
|
26
|
+
path = file_path
|
23
27
|
content = ::YAML.load_file(file_path)
|
24
|
-
raise Exceptions::YamlFileBlank
|
25
|
-
|
28
|
+
raise Exceptions::YamlFileBlank, file_path unless content
|
29
|
+
|
30
|
+
yield content, i
|
26
31
|
end
|
32
|
+
rescue Psych::SyntaxError
|
33
|
+
raise Exceptions::YamlFileInvalid, path
|
27
34
|
end
|
28
35
|
|
29
36
|
private
|
@@ -31,20 +38,22 @@ module Renogen
|
|
31
38
|
# @return [Array]
|
32
39
|
def change_directories
|
33
40
|
upgrade_versions = legacy_versions.map do |path|
|
34
|
-
File.join(path,
|
41
|
+
File.join(path, '*.yml')
|
35
42
|
end
|
36
|
-
upgrade_versions << File.join(directory_path, 'next',
|
43
|
+
upgrade_versions << File.join(directory_path, 'next', '*.yml')
|
37
44
|
|
38
45
|
Dir.glob(upgrade_versions)
|
39
46
|
end
|
40
47
|
|
41
|
-
# @return [Array]
|
48
|
+
# @return [Array]
|
42
49
|
def legacy_versions
|
43
50
|
return [] unless legacy_version
|
44
|
-
|
51
|
+
|
52
|
+
legacy_version.gsub!('v', '')
|
45
53
|
Dir.glob(File.join(directory_path, '*')).select do |dir|
|
46
|
-
dir = dir.split('/').last.gsub('v','').gsub('_','.')
|
54
|
+
dir = dir.split('/').last.gsub('v', '').gsub('_', '.')
|
47
55
|
next if dir == 'next'
|
56
|
+
|
48
57
|
Gem::Version.new(dir) > Gem::Version.new(legacy_version)
|
49
58
|
end
|
50
59
|
end
|
data/lib/renogen/formatters.rb
CHANGED
@@ -37,7 +37,9 @@ module Renogen
|
|
37
37
|
end
|
38
38
|
|
39
39
|
require_relative 'formatters/base'
|
40
|
+
require_relative 'formatters/csv'
|
40
41
|
require_relative 'formatters/plain_text'
|
41
42
|
require_relative 'formatters/markdown'
|
43
|
+
require_relative 'formatters/markdown_table'
|
42
44
|
require_relative 'formatters/html'
|
43
45
|
end
|
@@ -1,9 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Renogen
|
2
4
|
module Formatters
|
3
|
-
# Implements a template pattern that forces the implemention of required
|
5
|
+
# Implements a template pattern that forces the implemention of required
|
4
6
|
# methods in sub classes
|
5
7
|
class Base
|
6
|
-
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
# Switch to determine if the formatter is in table format(instead of group format)
|
15
|
+
#
|
16
|
+
# return [Boolean] (default: false)
|
17
|
+
def table_formatter?
|
18
|
+
false # for backward compatibility
|
7
19
|
end
|
8
20
|
|
9
21
|
# Adds class with identifier to formatters
|
@@ -13,20 +25,31 @@ module Renogen
|
|
13
25
|
Renogen::Formatters.add(identifier.to_sym, self)
|
14
26
|
end
|
15
27
|
|
28
|
+
# Generate a header for a given changelog
|
29
|
+
#
|
30
|
+
# @param changelog [Renogen::ChangeLog::Model]
|
31
|
+
#
|
32
|
+
# return [String]
|
33
|
+
def header(changelog)
|
34
|
+
"#{changelog.version} (#{changelog.date})"
|
35
|
+
end
|
36
|
+
|
16
37
|
# Outputs a line or block of text appearing at the top of the change log.
|
17
38
|
#
|
39
|
+
# @abstract
|
40
|
+
#
|
18
41
|
# @param header [String]
|
19
|
-
# @
|
42
|
+
# @raise NotImplementedError
|
20
43
|
def write_header(header)
|
21
|
-
raise NotImplementedError
|
22
44
|
end
|
23
45
|
|
24
46
|
# Outputs a line or block as a header for a group.
|
25
47
|
#
|
48
|
+
# @abstract
|
49
|
+
#
|
26
50
|
# @param group [String]
|
27
|
-
# @
|
51
|
+
# @raise NotImplementedError
|
28
52
|
def write_group(group)
|
29
|
-
raise NotImplementedError
|
30
53
|
end
|
31
54
|
|
32
55
|
# Outputs a line or block of text appearing after a group.
|
@@ -37,8 +60,10 @@ module Renogen
|
|
37
60
|
|
38
61
|
# Outputs a line or block as the body for a change.
|
39
62
|
#
|
63
|
+
# @abstract
|
64
|
+
#
|
40
65
|
# @param change [String]
|
41
|
-
# @
|
66
|
+
# @raise NotImplementedError
|
42
67
|
def write_change(change)
|
43
68
|
raise NotImplementedError
|
44
69
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renogen
|
4
|
+
module Formatters
|
5
|
+
# For formatting a change into CSV output
|
6
|
+
class Csv < Base
|
7
|
+
register :csv
|
8
|
+
|
9
|
+
attr_reader :headings
|
10
|
+
|
11
|
+
def table_formatter?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def write_header(header)
|
16
|
+
"#{header}\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_change(ticket)
|
20
|
+
headings.map do |header|
|
21
|
+
raw_line = ticket[header]
|
22
|
+
next if raw_line.nil?
|
23
|
+
|
24
|
+
parsed_line = raw_line.is_a?(Array) ? raw_line.join(',') : raw_line
|
25
|
+
parsed_line.gsub!("\n", '\n') if parsed_line.include?("\n")
|
26
|
+
|
27
|
+
if parsed_line.include?(',')
|
28
|
+
"\"#{parsed_line}\""
|
29
|
+
else
|
30
|
+
parsed_line
|
31
|
+
end
|
32
|
+
end.join(',')
|
33
|
+
end
|
34
|
+
|
35
|
+
def header(changelog)
|
36
|
+
@headings = changelog.groups.keys
|
37
|
+
@headings.join(',')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -10,7 +10,7 @@ module Renogen
|
|
10
10
|
# @param header [String]
|
11
11
|
# @return [String]
|
12
12
|
def write_header(header)
|
13
|
-
"# #{header}"
|
13
|
+
"# #{header}\n\n"
|
14
14
|
end
|
15
15
|
|
16
16
|
# Outputs a line or block as a header for a group.
|
@@ -18,7 +18,7 @@ module Renogen
|
|
18
18
|
# @param group [String]
|
19
19
|
# @return [String]
|
20
20
|
def write_group(group)
|
21
|
-
"
|
21
|
+
"## #{group}\n\n"
|
22
22
|
end
|
23
23
|
|
24
24
|
# Outputs a line or block as the body for a change.
|