easy_changelog 1.1.0 → 1.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/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/easy_changelog/configuration.rb +43 -19
- data/lib/easy_changelog/entry.rb +18 -58
- data/lib/easy_changelog/task_options_parser.rb +4 -3
- data/lib/easy_changelog/utility.rb +109 -0
- data/lib/easy_changelog/version.rb +1 -1
- data/lib/easy_changelog.rb +16 -36
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8daff142414ebf8420379e1f0536b020a9852080ecd517981d9766c5644054a7
|
|
4
|
+
data.tar.gz: 6f0c1a26f4aa96a987104b3e0feb5b72127acb996600cad537fc7a963231f741
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a3ead37ca521e143ad9b382a033e5521100094713a5712a8044902af2e7652478e74984927b02c4e217351ad39a3d1410bf7714d28919cdf1de2d09f4917659f
|
|
7
|
+
data.tar.gz: b8ab8c7b836dc92fe6d30b1e03927bd40029d4b298cea9667768d43be4838813309b15ce7af2602beaea13f42bf9962e981cffc999531815ab4eeda0748067f2
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -24,7 +24,7 @@ EasyChangelog.configure do |config|
|
|
|
24
24
|
config.changelog_filename = 'CHANGELOG.md' # the filename of your changelog
|
|
25
25
|
config.main_branch = 'master' # main branch for repository
|
|
26
26
|
config.filename_max_length = 50 # max filename length
|
|
27
|
-
config.
|
|
27
|
+
config.include_empty_card_id = false # includes a [] when task id and the project still need to track tasks without tickets
|
|
28
28
|
|
|
29
29
|
config.unreleased_header = '## master (unreleased)' # Header of changelog where the unreleased entries are located
|
|
30
30
|
config.user_signature = /\[@([\w-]+)\]\[\]/ # Regexp to list unique contributors of the project
|
|
@@ -35,7 +35,7 @@ EasyChangelog.configure do |config|
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
config.repo_url = <GITHUB_REPO_URL> # URL to your repository (Can also be defined with REPOSITORY_URL var var)
|
|
38
|
-
config.
|
|
38
|
+
config.cards_url = <YOUR_ISSUE_TRACKING_URL> # URL to your organization issue tracker (ex: JIRA, Asana, Wrike. Can also be defined with REPOSITORY_URL env var)
|
|
39
39
|
end
|
|
40
40
|
```
|
|
41
41
|
|
|
@@ -5,23 +5,28 @@ require 'date'
|
|
|
5
5
|
|
|
6
6
|
class EasyChangelog
|
|
7
7
|
class Configuration
|
|
8
|
-
attr_accessor :changelog_filename, :main_branch, :filename_max_length, :
|
|
9
|
-
:
|
|
10
|
-
attr_reader :entries_path, :unreleased_header, :entry_path_format, :user_signature, :type_mapping, :
|
|
8
|
+
attr_accessor :changelog_filename, :main_branch, :filename_max_length, :include_empty_card_id, :cards_url,
|
|
9
|
+
:entry_row_format
|
|
10
|
+
attr_reader :entries_path, :unreleased_header, :entry_path_format, :user_signature, :type_mapping, :card_id_regex,
|
|
11
|
+
:entries_order, :card_id_normalizer
|
|
12
|
+
|
|
11
13
|
attr_writer :repo_url, :release_message_template
|
|
12
14
|
|
|
13
|
-
CONFIG_PATHS = %w
|
|
15
|
+
CONFIG_PATHS = %w[
|
|
14
16
|
./.easy_changelog.rb
|
|
15
17
|
./config/initializers/easy_changelog.rb
|
|
16
18
|
./config/easy_changelog.rb
|
|
17
|
-
|
|
19
|
+
].freeze
|
|
18
20
|
|
|
21
|
+
# rubocop:disable Metrics/AbcSize
|
|
19
22
|
def initialize
|
|
20
23
|
@entries_path = 'changelog/'
|
|
24
|
+
@entries_order = :asc
|
|
21
25
|
@changelog_filename = 'CHANGELOG.md'
|
|
22
26
|
|
|
23
27
|
@main_branch = 'master'
|
|
24
28
|
@entry_path_format = '<type>_<name>_<timestamp>.md'
|
|
29
|
+
@entry_row_format = '* <ref>: <card_ref> <title> (<username>)'
|
|
25
30
|
@unreleased_header = /## #{Regexp.escape("#{@main_branch} (unreleased)")}/m
|
|
26
31
|
@user_signature = Regexp.new(format(Regexp.escape('[@%<user>s][]'), user: '([\w-]+)'))
|
|
27
32
|
|
|
@@ -31,13 +36,14 @@ class EasyChangelog
|
|
|
31
36
|
feature: { title: 'New features', level: :minor },
|
|
32
37
|
fix: { title: 'Bug fixes', level: :patch }
|
|
33
38
|
}
|
|
34
|
-
@
|
|
39
|
+
@include_empty_card_id = false
|
|
35
40
|
|
|
36
41
|
@repo_url = ENV.fetch('REPOSITORY_URL', nil)
|
|
37
|
-
@
|
|
38
|
-
@
|
|
42
|
+
@cards_url = ENV.fetch('CARDS_URL', nil)
|
|
43
|
+
@card_id_regex = %r{(?<card_id>[^/]+)/(?:.+)}
|
|
39
44
|
@release_message_template = -> { "## #{EasyChangelog::VERSION} (#{Date.today.iso8601})" }
|
|
40
45
|
end
|
|
46
|
+
# rubocop:enable Metrics/AbcSize
|
|
41
47
|
|
|
42
48
|
def repo_url
|
|
43
49
|
raise ConfigurationError, 'repo_url must be set' unless @repo_url
|
|
@@ -55,10 +61,16 @@ class EasyChangelog
|
|
|
55
61
|
message
|
|
56
62
|
end
|
|
57
63
|
|
|
58
|
-
def
|
|
59
|
-
raise ArgumentError, '
|
|
64
|
+
def card_regex=(value)
|
|
65
|
+
raise ArgumentError, 'card_regex must be a Regexp' unless value.is_a?(Regexp)
|
|
66
|
+
|
|
67
|
+
@card_regex = value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def card_id_normalizer=(value)
|
|
71
|
+
raise ArgumentError, 'card_id_normalizer must be callable' unless value.respond_to?(:call)
|
|
60
72
|
|
|
61
|
-
@
|
|
73
|
+
@card_id_normalizer = value
|
|
62
74
|
end
|
|
63
75
|
|
|
64
76
|
def unreleased_header=(value)
|
|
@@ -71,6 +83,13 @@ class EasyChangelog
|
|
|
71
83
|
@entries_path = value
|
|
72
84
|
end
|
|
73
85
|
|
|
86
|
+
def entries_order=(value)
|
|
87
|
+
value = value.to_sym
|
|
88
|
+
raise ArgumentError, 'entries_order must be :asc or :desc' unless %i[asc desc].include?(value)
|
|
89
|
+
|
|
90
|
+
@entries_order = value
|
|
91
|
+
end
|
|
92
|
+
|
|
74
93
|
def type_mapping=(value)
|
|
75
94
|
raise ArgumentError, 'type_mapping must be a Hash or :loose' unless value.is_a?(Hash) || value == :loose
|
|
76
95
|
|
|
@@ -99,12 +118,6 @@ class EasyChangelog
|
|
|
99
118
|
@type_mapping.values.map { |v| v[:title] }
|
|
100
119
|
end
|
|
101
120
|
|
|
102
|
-
def section_for(type)
|
|
103
|
-
return '' if @type_mapping == :loose
|
|
104
|
-
|
|
105
|
-
@type_mapping[type][:title]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
121
|
def entry_path_match_regexp
|
|
109
122
|
formula = @entry_path_format.gsub(/<(\w+)>/) do |match|
|
|
110
123
|
matcher = match == '<type>' ? '[^_]' : '.'
|
|
@@ -118,9 +131,20 @@ class EasyChangelog
|
|
|
118
131
|
File.join(entries_path, @entry_path_format.gsub(/<(\w+)>/) { |_match| "%<#{Regexp.last_match(1)}>s" })
|
|
119
132
|
end
|
|
120
133
|
|
|
134
|
+
def entry_row_match_regexp
|
|
135
|
+
with_optional_card_ref = Regexp.escape(@entry_row_format).gsub('<card_ref>\\ ') { |match| "(?:#{match})?" }
|
|
136
|
+
formula = with_optional_card_ref.gsub(/<(\w+)>/) { |match| "(?#{match}.+)" }
|
|
137
|
+
|
|
138
|
+
Regexp.new(formula)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def entry_row_template
|
|
142
|
+
@entry_row_format.gsub(/<(\w+)>/) { |_match| "%<#{Regexp.last_match(1)}>s" }
|
|
143
|
+
end
|
|
144
|
+
|
|
121
145
|
def load_config
|
|
122
|
-
paths = CONFIG_PATHS.map { |
|
|
123
|
-
path = paths.select { |
|
|
146
|
+
paths = CONFIG_PATHS.map { |file_path| File.expand_path(file_path) }
|
|
147
|
+
path = paths.select { |file_path| File.exist?(file_path) }.first
|
|
124
148
|
|
|
125
149
|
return unless path
|
|
126
150
|
|
data/lib/easy_changelog/entry.rb
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class EasyChangelog
|
|
4
|
-
Entry = Struct.new(:type, :body, :ref_type, :ref_id, :
|
|
5
|
-
def initialize(type:, body: last_commit_title, ref_type: nil, ref_id: nil,
|
|
6
|
-
user: github_user)
|
|
7
|
-
id, body = extract_id(body)
|
|
4
|
+
Entry = Struct.new(:type, :body, :ref_type, :ref_id, :card_id, :cards_url, :branch_name, :user, keyword_init: true) do
|
|
5
|
+
def initialize(type:, body: last_commit_title, ref_type: nil, ref_id: nil, card_id: nil, cards_url: nil,
|
|
6
|
+
user: github_user, branch_name: nil)
|
|
7
|
+
id, body = EasyChangelog::Utility.extract_id(body)
|
|
8
8
|
ref_id ||= id || last_commit_id
|
|
9
9
|
ref_type ||= id ? :pull : :commit
|
|
10
|
-
|
|
10
|
+
card_id ||= EasyChangelog::Utility.discover_card_id(branch_name)
|
|
11
11
|
|
|
12
12
|
super
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def write
|
|
16
|
-
|
|
17
|
-
FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
|
|
16
|
+
EasyChangelog::Utility.ensure_entries_dir_exists
|
|
18
17
|
|
|
19
18
|
File.write(path, content)
|
|
20
19
|
path
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def path
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
23
|
+
filename = EasyChangelog::Utility.str_to_filename(body)
|
|
24
|
+
options = { type: type, name: filename, timestamp: Time.now.strftime('%Y%m%d%H%M%S') }
|
|
25
|
+
|
|
26
|
+
format(EasyChangelog.configuration.entry_path_template, options)
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def content
|
|
31
30
|
title = body.dup
|
|
32
31
|
title += '.' unless title.end_with? '.'
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
options = { ref: ref, card_ref: card_ref, title: title, username: user }
|
|
34
|
+
|
|
35
|
+
format(EasyChangelog.configuration.entry_row_template, options)
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def ref
|
|
@@ -40,12 +41,12 @@ class EasyChangelog
|
|
|
40
41
|
"[##{ref_id}](#{EasyChangelog.configuration.repo_url}/#{ref_type}/#{ref_id})"
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
def
|
|
44
|
-
return EasyChangelog.configuration.
|
|
44
|
+
def card_ref
|
|
45
|
+
return EasyChangelog.configuration.include_empty_card_id ? '[] ' : '' if card_id.nil? || card_id.empty?
|
|
45
46
|
|
|
46
|
-
link = "[#{
|
|
47
|
-
base_url =
|
|
48
|
-
link += "(#{base_url}/#{
|
|
47
|
+
link = "[#{card_id}]"
|
|
48
|
+
base_url = cards_url || EasyChangelog.configuration.cards_url
|
|
49
|
+
link += "(#{base_url}/#{card_id})" if base_url
|
|
49
50
|
|
|
50
51
|
link
|
|
51
52
|
end
|
|
@@ -58,52 +59,11 @@ class EasyChangelog
|
|
|
58
59
|
`git log -n1 --format="%h"`.chomp
|
|
59
60
|
end
|
|
60
61
|
|
|
61
|
-
def discover_task_id
|
|
62
|
-
return if EasyChangelog.configuration.task_id_regex.nil?
|
|
63
|
-
|
|
64
|
-
branch_name = `git rev-parse --abbrev-ref HEAD`
|
|
65
|
-
return if branch_name == EasyChangelog.configuration.main_branch
|
|
66
|
-
|
|
67
|
-
EasyChangelog.configuration.task_id_regex.match(branch_name)&.named_captures&.fetch('task_id', nil)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def extract_id(body)
|
|
71
|
-
/^\[Fix(?:es)? #(\d+)\] (.*)/.match(body)&.captures || [nil, body]
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def str_to_filename(str)
|
|
75
|
-
str
|
|
76
|
-
.split
|
|
77
|
-
.reject(&:empty?)
|
|
78
|
-
.map { |s| prettify(s) }
|
|
79
|
-
.inject do |result, word|
|
|
80
|
-
s = "#{result}_#{word}"
|
|
81
|
-
return result if s.length > EasyChangelog.configuration.filename_max_length
|
|
82
|
-
|
|
83
|
-
s
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
62
|
def github_user
|
|
88
63
|
user = `git config --global credential.username`.chomp
|
|
89
64
|
warn 'Set your username with `git config --global credential.username "myusernamehere"`' if user.empty?
|
|
90
65
|
|
|
91
66
|
user
|
|
92
67
|
end
|
|
93
|
-
|
|
94
|
-
private
|
|
95
|
-
|
|
96
|
-
def prettify(str)
|
|
97
|
-
str.gsub!(/\W/, '_')
|
|
98
|
-
|
|
99
|
-
# Separate word boundaries by `_`.
|
|
100
|
-
str.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
|
|
101
|
-
(Regexp.last_match(1) || Regexp.last_match(2)) << '_'
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
str.gsub!(/\A_+|_+\z/, '')
|
|
105
|
-
str.downcase!
|
|
106
|
-
str
|
|
107
|
-
end
|
|
108
68
|
end
|
|
109
69
|
end
|
|
@@ -12,11 +12,12 @@ class EasyChangelog
|
|
|
12
12
|
opts.banner = "Usage: rake changelog:#{type} [options]"
|
|
13
13
|
|
|
14
14
|
opts.on('-u', '--user=ARG', 'Git Username') { |arg| options[:user] = arg }
|
|
15
|
-
opts.on('-b', '--
|
|
15
|
+
opts.on('-b', '--branch=ARG', 'Branch Name') { |arg| options[:branch_name] = arg }
|
|
16
|
+
opts.on('-t', '--title=ARG', 'Changelog Title Entry') { |arg| options[:body] = arg }
|
|
16
17
|
opts.on('-r', '--ref-id=ARG', 'Ref ID') { |arg| options[:ref_id] = arg }
|
|
17
18
|
opts.on('-R', '--ref-type=ARG', 'Ref type (issues|pull|commit)') { |arg| options[:ref_type] = arg }
|
|
18
|
-
opts.on('-
|
|
19
|
-
opts.on('-
|
|
19
|
+
opts.on('-c', '--card-id=ARG', 'Card ID') { |arg| options[:card_id] = arg }
|
|
20
|
+
opts.on('-C', '--cards-url=ARG', 'Cards base URL') { |arg| options[:cards_url] = arg }
|
|
20
21
|
|
|
21
22
|
opts.on('-h', '--help', 'Prints this helper') do
|
|
22
23
|
puts opts
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class EasyChangelog
|
|
4
|
+
class Utility
|
|
5
|
+
class << self
|
|
6
|
+
def ensure_entries_dir_exists
|
|
7
|
+
dir_name = EasyChangelog.configuration.entries_path
|
|
8
|
+
FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
def parse_changelog(content)
|
|
13
|
+
ss = StringScanner.new(content)
|
|
14
|
+
|
|
15
|
+
header = ss.scan_until(EasyChangelog.configuration.unreleased_header)
|
|
16
|
+
unreleased = ss.scan_until(/\n(?=## )/m)
|
|
17
|
+
|
|
18
|
+
if unreleased.nil?
|
|
19
|
+
unreleased = parse_unreleased_entries(ss.rest)
|
|
20
|
+
rest = ''
|
|
21
|
+
else
|
|
22
|
+
unreleased = parse_unreleased_entries(unreleased)
|
|
23
|
+
rest = ss.rest
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
[header, unreleased, rest]
|
|
27
|
+
end
|
|
28
|
+
# rubocop:enable Metrics/MethodLength
|
|
29
|
+
|
|
30
|
+
def update_changelog(content)
|
|
31
|
+
File.write(EasyChangelog.configuration.changelog_filename, content)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def attr_from_path(var_name, path)
|
|
35
|
+
EasyChangelog.configuration.entry_path_match_regexp.match(path)[var_name.to_sym]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def attr_from_entry(var_name, entry)
|
|
39
|
+
EasyChangelog.configuration.entry_row_match_regexp.match(entry)[var_name.to_sym]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def section_for(path)
|
|
43
|
+
entry_type = attr_from_path(:type, path).to_sym
|
|
44
|
+
|
|
45
|
+
return '' if EasyChangelog.configuration.loose?
|
|
46
|
+
|
|
47
|
+
EasyChangelog.configuration.type_mapping[entry_type][:title]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def discover_card_id(branch_name)
|
|
51
|
+
return if EasyChangelog.configuration.card_id_regex.nil?
|
|
52
|
+
|
|
53
|
+
branch_name ||= `git rev-parse --abbrev-ref HEAD`
|
|
54
|
+
return if branch_name == EasyChangelog.configuration.main_branch
|
|
55
|
+
|
|
56
|
+
id = EasyChangelog.configuration.card_id_regex.match(branch_name)&.named_captures&.fetch('card_id', nil)
|
|
57
|
+
|
|
58
|
+
normalize_card_id(id)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def extract_id(body)
|
|
62
|
+
/^\[Fix(?:es)? #(\d+)\] (.*)/.match(body)&.captures || [nil, body]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def str_to_filename(str)
|
|
66
|
+
str
|
|
67
|
+
.split
|
|
68
|
+
.reject(&:empty?)
|
|
69
|
+
.map { |s| prettify(s) }
|
|
70
|
+
.inject do |result, word|
|
|
71
|
+
s = "#{result}_#{word}"
|
|
72
|
+
return result if s.length > EasyChangelog.configuration.filename_max_length
|
|
73
|
+
|
|
74
|
+
s
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def normalize_card_id(id)
|
|
81
|
+
return id unless EasyChangelog.configuration.card_id_normalizer
|
|
82
|
+
|
|
83
|
+
EasyChangelog.configuration.card_id_normalizer.call(id)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @return [Hash<type, Array<String>]]
|
|
87
|
+
def parse_unreleased_entries(unreleased)
|
|
88
|
+
entries = unreleased.lines.map(&:chomp).reject(&:empty?)
|
|
89
|
+
|
|
90
|
+
return { '' => entries } if EasyChangelog.configuration.loose?
|
|
91
|
+
|
|
92
|
+
entries.slice_before(HEADER).to_h { |header, *header_entries| [HEADER.match(header)[1], header_entries] }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def prettify(str)
|
|
96
|
+
str.gsub!(/\W/, '_')
|
|
97
|
+
|
|
98
|
+
# Separate word boundaries by `_`.
|
|
99
|
+
str.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
|
|
100
|
+
(Regexp.last_match(1) || Regexp.last_match(2)) << '_'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
str.gsub!(/\A_+|_+\z/, '')
|
|
104
|
+
str.downcase!
|
|
105
|
+
str
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
data/lib/easy_changelog.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'easy_changelog/version'
|
|
4
4
|
require 'easy_changelog/configuration'
|
|
5
|
+
require 'easy_changelog/utility'
|
|
5
6
|
require 'easy_changelog/entry'
|
|
6
7
|
|
|
7
8
|
class EasyChangelog
|
|
@@ -55,7 +56,7 @@ class EasyChangelog
|
|
|
55
56
|
entries: EasyChangelog.read_entries)
|
|
56
57
|
require 'strscan'
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
@header, @unreleased, @rest = EasyChangelog::Utility.parse_changelog(content)
|
|
59
60
|
@entries = entries
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -65,7 +66,7 @@ class EasyChangelog
|
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def merge!
|
|
68
|
-
|
|
69
|
+
EasyChangelog::Utility.update_changelog(merge_content)
|
|
69
70
|
self
|
|
70
71
|
end
|
|
71
72
|
|
|
@@ -74,7 +75,7 @@ class EasyChangelog
|
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
def release!
|
|
77
|
-
|
|
78
|
+
EasyChangelog::Utility.update_changelog(release_content)
|
|
78
79
|
self
|
|
79
80
|
end
|
|
80
81
|
|
|
@@ -116,50 +117,26 @@ class EasyChangelog
|
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
def contributors
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
@entries.values.flat_map do |entry|
|
|
121
|
+
EasyChangelog::Utility.attr_from_entry(:username, entry)&.gsub(/@/, '')
|
|
121
122
|
end
|
|
122
|
-
|
|
123
|
-
contributors.join.scan(EasyChangelog.configuration.user_signature).flatten
|
|
124
123
|
end
|
|
125
124
|
|
|
126
125
|
private
|
|
127
126
|
|
|
128
127
|
def merge_entries(entry_map)
|
|
129
|
-
all = @unreleased.merge(entry_map)
|
|
128
|
+
all = @unreleased.merge(entry_map) do |_k, v1, v2|
|
|
129
|
+
EasyChangelog.configuration.entries_order == :desc ? v2.concat(v1) : v1.concat(v2)
|
|
130
|
+
end
|
|
130
131
|
canonical = EasyChangelog.configuration.sections.to_h { |v| [v, nil] }
|
|
131
132
|
canonical.merge(all).compact
|
|
132
133
|
end
|
|
133
134
|
|
|
134
|
-
def parse(content)
|
|
135
|
-
ss = StringScanner.new(content)
|
|
136
|
-
|
|
137
|
-
@header = ss.scan_until(EasyChangelog.configuration.unreleased_header)
|
|
138
|
-
unreleased = ss.scan_until(/\n(?=## )/m)
|
|
139
|
-
|
|
140
|
-
if unreleased.nil?
|
|
141
|
-
@unreleased = parse_release(ss.rest)
|
|
142
|
-
@rest = ''
|
|
143
|
-
else
|
|
144
|
-
@unreleased = parse_release(unreleased)
|
|
145
|
-
@rest = ss.rest
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# @return [Hash<type, Array<String>]]
|
|
150
|
-
def parse_release(unreleased)
|
|
151
|
-
entries = unreleased.lines.map(&:chomp).reject(&:empty?)
|
|
152
|
-
|
|
153
|
-
return { '' => entries } if EasyChangelog.configuration.loose?
|
|
154
|
-
|
|
155
|
-
entries.slice_before(HEADER).to_h { |header, *header_entries| [HEADER.match(header)[1], header_entries] }
|
|
156
|
-
end
|
|
157
|
-
|
|
158
135
|
def parse_entries(path_content_map)
|
|
159
136
|
changes = Hash.new { |h, k| h[k] = [] }
|
|
160
137
|
|
|
161
|
-
path_content_map.each do |path, content|
|
|
162
|
-
header = EasyChangelog.
|
|
138
|
+
sorted_entries(path_content_map).each do |path, content|
|
|
139
|
+
header = EasyChangelog::Utility.section_for(path)
|
|
163
140
|
|
|
164
141
|
changes[header].concat(content.lines.map(&:chomp))
|
|
165
142
|
end
|
|
@@ -167,7 +144,10 @@ class EasyChangelog
|
|
|
167
144
|
changes
|
|
168
145
|
end
|
|
169
146
|
|
|
170
|
-
def
|
|
171
|
-
EasyChangelog.
|
|
147
|
+
def sorted_entries(path_content_map)
|
|
148
|
+
sorted = path_content_map.sort_by { |path, _content| EasyChangelog::Utility.attr_from_path(:timestamp, path) }
|
|
149
|
+
sorted = sorted.reverse if EasyChangelog.configuration.entries_order == :desc
|
|
150
|
+
|
|
151
|
+
sorted
|
|
172
152
|
end
|
|
173
153
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: easy_changelog
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ivan de Paula Almeida Filho
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-02-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Changelog generator, based on Rubocop contributing section.
|
|
14
14
|
email:
|
|
@@ -34,6 +34,7 @@ files:
|
|
|
34
34
|
- lib/easy_changelog/railtie.rb
|
|
35
35
|
- lib/easy_changelog/task_options_parser.rb
|
|
36
36
|
- lib/easy_changelog/tasks/changelog.rake
|
|
37
|
+
- lib/easy_changelog/utility.rb
|
|
37
38
|
- lib/easy_changelog/version.rb
|
|
38
39
|
- sig/easy_changelog.rbs
|
|
39
40
|
homepage: https://github.com/ivan05almeida/easy_changelog
|