reissue 0.4.1 → 0.4.2
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 +4 -12
- data/README.md +74 -3
- data/Rakefile +2 -1
- data/lib/reissue/changelog_updater.rb +17 -10
- data/lib/reissue/{fragment_reader.rb → fragment_handler/directory_fragment_handler.rb} +19 -3
- data/lib/reissue/fragment_handler/git_fragment_handler.rb +93 -0
- data/lib/reissue/fragment_handler/null_fragment_handler.rb +20 -0
- data/lib/reissue/fragment_handler.rb +45 -0
- data/lib/reissue/rake.rb +59 -9
- data/lib/reissue/version.rb +1 -1
- data/lib/reissue.rb +28 -13
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58c406237f6e7ef96ad4a4e1ed1aa2ba3e4cb10145edd6d44bff791a8e37d5be
|
4
|
+
data.tar.gz: 26b103713df3d7de9c1f9af49df079a2e9954b9b7e96a58bc8e3e203607e531d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01d186d7b5f87e5c3ef2be402eb758971ff4dec3626d2e2aed8d67d5fd6418d064687682176b509b038b39710e8c313279047e807e42d927c902e4b5bbee649e
|
7
|
+
data.tar.gz: 63d5c29928e104484ce0f1c5ce6ef101a8909ed8727ae441c3a5bb81c9aaf6ecbfb46b7f4af69540f6665fc71ea8e9f9a73d1ea928371d3f8fb7a84b7077198c
|
data/CHANGELOG.md
CHANGED
@@ -5,22 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
|
-
## [0.4.
|
9
|
-
|
10
|
-
### Added
|
11
|
-
|
12
|
-
- Add GitHub Actions workflow to release gems with Reissue
|
13
|
-
- Add `reissue:clear_fragments` task to clear fragments after release
|
8
|
+
## [0.4.2] - 2025-09-16
|
14
9
|
|
15
10
|
### Changed
|
16
11
|
|
17
|
-
-
|
18
|
-
- Updated the shared gem release workflow to work with hyphenated gem names.
|
19
|
-
- Rely on `rubygems/configure-rubygems-credentials` action.
|
12
|
+
- New version was never created after the last release.
|
20
13
|
|
21
|
-
## [0.4.
|
14
|
+
## [0.4.2] - 2025-09-16
|
22
15
|
|
23
16
|
### Changed
|
24
17
|
|
25
|
-
-
|
26
|
-
- Update the `reissue:branch` task to force create a new branch if it already exists.
|
18
|
+
- New version was never created after the last release.
|
data/README.md
CHANGED
@@ -57,6 +57,7 @@ Additional tasks (usually run automatically):
|
|
57
57
|
- `rake reissue[segment]` - Bump version (major, minor, patch)
|
58
58
|
- `rake reissue:finalize[date]` - Add release date to changelog
|
59
59
|
- `rake reissue:reformat[version_limit]` - Clean up changelog formatting
|
60
|
+
- `rake reissue:preview` - Preview changelog entries from fragments or git trailers
|
60
61
|
- `rake reissue:clear_fragments` - Clear changelog fragments after release
|
61
62
|
|
62
63
|
### Non-Gem Projects
|
@@ -104,13 +105,22 @@ Reissue::Task.create :reissue do |task|
|
|
104
105
|
# Options: false, true (push working branch), :branch (create and push new branch)
|
105
106
|
task.push_finalize = :branch
|
106
107
|
|
107
|
-
# Optional:
|
108
|
-
|
108
|
+
# Optional: Configure fragment handling for changelog entries. Defaults to nil (disabled)
|
109
|
+
# Options:
|
110
|
+
# - nil or false: Fragments disabled
|
111
|
+
# - String path: Use directory-based fragments (e.g., "changelog_fragments")
|
112
|
+
# - :git: Extract changelog entries from git commit trailers
|
113
|
+
task.fragment = "changelog_fragments"
|
114
|
+
# task.fragment = :git # Use git trailers for changelog entries
|
109
115
|
|
110
116
|
# Optional: Whether to clear fragment files after releasing. Defaults to false
|
111
|
-
# When true, fragments are cleared after a release
|
117
|
+
# When true, fragments are cleared after a release (only applies when using directory fragments)
|
118
|
+
# Note: Has no effect when using :git fragments
|
112
119
|
task.clear_fragments = true
|
113
120
|
|
121
|
+
# Deprecated: Use `fragment` instead of `fragment_directory`
|
122
|
+
# task.fragment_directory = "changelog_fragments" # DEPRECATED: Use task.fragment instead
|
123
|
+
|
114
124
|
# Optional: Retain changelog files for previous versions. Defaults to false
|
115
125
|
# Options: true (retain in "changelogs" directory), "path/to/archive", or a Proc
|
116
126
|
task.retain_changelogs = true
|
@@ -125,6 +135,67 @@ Reissue::Task.create :reissue do |task|
|
|
125
135
|
end
|
126
136
|
```
|
127
137
|
|
138
|
+
## Using Git Trailers for Changelog Entries
|
139
|
+
|
140
|
+
Reissue can extract changelog entries directly from git commit messages using trailers. This keeps your changelog data close to the code changes.
|
141
|
+
|
142
|
+
### Configuration
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
Reissue::Task.create :reissue do |task|
|
146
|
+
task.version_file = "lib/my_gem/version.rb"
|
147
|
+
task.fragment = :git # Enable git trailer extraction
|
148
|
+
end
|
149
|
+
```
|
150
|
+
|
151
|
+
### Adding Trailers to Commits
|
152
|
+
|
153
|
+
Use changelog section names as trailer keys in your commit messages:
|
154
|
+
|
155
|
+
```bash
|
156
|
+
git commit -m "Implement user authentication
|
157
|
+
|
158
|
+
Added: User login and logout functionality
|
159
|
+
Added: Password reset via email
|
160
|
+
Fixed: Session timeout not working correctly
|
161
|
+
Security: Rate limiting on login attempts"
|
162
|
+
```
|
163
|
+
|
164
|
+
### Supported Sections
|
165
|
+
|
166
|
+
Git trailers use the standard Keep a Changelog sections:
|
167
|
+
- `Added:` for new features
|
168
|
+
- `Changed:` for changes in existing functionality
|
169
|
+
- `Deprecated:` for soon-to-be removed features
|
170
|
+
- `Removed:` for now removed features
|
171
|
+
- `Fixed:` for any bug fixes
|
172
|
+
- `Security:` for vulnerability fixes
|
173
|
+
|
174
|
+
### How It Works
|
175
|
+
|
176
|
+
1. When you run `rake reissue`, it finds all commits since the last version tag
|
177
|
+
2. Extracts trailers matching changelog sections from commit messages
|
178
|
+
3. Adds them to the appropriate sections in your CHANGELOG.md
|
179
|
+
4. Trailers are case-insensitive (e.g., `fixed:`, `Fixed:`, `FIXED:` all work)
|
180
|
+
|
181
|
+
### Example Workflow
|
182
|
+
|
183
|
+
```bash
|
184
|
+
# Make your changes
|
185
|
+
git add .
|
186
|
+
git commit -m "Add export functionality
|
187
|
+
|
188
|
+
Added: CSV export for user data
|
189
|
+
Added: PDF report generation
|
190
|
+
Fixed: Date formatting in exports"
|
191
|
+
|
192
|
+
# Release (trailers are automatically extracted)
|
193
|
+
rake build:checksum
|
194
|
+
rake release
|
195
|
+
```
|
196
|
+
|
197
|
+
The changelog will be updated with the entries from your commit trailers.
|
198
|
+
|
128
199
|
## Development
|
129
200
|
|
130
201
|
After checking out the repo, run `bin/setup` to install dependencies. Then run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt.
|
data/Rakefile
CHANGED
@@ -16,6 +16,7 @@ require_relative "lib/reissue/gem"
|
|
16
16
|
|
17
17
|
Reissue::Task.create :reissue do |task|
|
18
18
|
task.version_file = "lib/reissue/version.rb"
|
19
|
+
task.fragment = :git # Use git trailers for changelog entries
|
19
20
|
task.push_finalize = :branch
|
20
|
-
|
21
|
+
# Note: clear_fragments has no effect with :git
|
21
22
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative "parser"
|
2
2
|
require_relative "printer"
|
3
|
-
require_relative "
|
3
|
+
require_relative "fragment_handler"
|
4
4
|
|
5
5
|
module Reissue
|
6
6
|
# Updates the changelog file with new versions and changes.
|
@@ -19,9 +19,16 @@ module Reissue
|
|
19
19
|
# @param changes [Hash] The changes for the version (default: {}).
|
20
20
|
# @param changelog_file [String] The path to the changelog file (default: @changelog_file).
|
21
21
|
# @param version_limit [Integer] The number of versions to keep (default: 2).
|
22
|
-
# @param
|
23
|
-
|
24
|
-
|
22
|
+
# @param fragment [String] The fragment source configuration (default: nil).
|
23
|
+
# @param fragment_directory [String] @deprecated Use fragment instead
|
24
|
+
def call(version, date: "Unreleased", changes: {}, changelog_file: @changelog_file, version_limit: 2, retain_changelogs: false, fragment: nil, fragment_directory: nil)
|
25
|
+
# Handle deprecation
|
26
|
+
if fragment_directory && !fragment
|
27
|
+
warn "[DEPRECATION] `fragment_directory` parameter is deprecated. Please use `fragment` instead."
|
28
|
+
fragment = fragment_directory
|
29
|
+
end
|
30
|
+
|
31
|
+
update(version, date:, changes:, version_limit:, fragment:)
|
25
32
|
write(changelog_file, retain_changelogs:)
|
26
33
|
|
27
34
|
changelog
|
@@ -48,16 +55,16 @@ module Reissue
|
|
48
55
|
# @param date [String] The release date (default: "Unreleased").
|
49
56
|
# @param changes [Hash] The changes for the version (default: {}).
|
50
57
|
# @param version_limit [Integer] The number of versions to keep (default: 2).
|
51
|
-
# @param
|
58
|
+
# @param fragment [String] The fragment source configuration (default: nil).
|
52
59
|
# @return [Hash] The updated changelog.
|
53
|
-
def update(version, date: "Unreleased", changes: {}, version_limit: 2,
|
60
|
+
def update(version, date: "Unreleased", changes: {}, version_limit: 2, fragment: nil)
|
54
61
|
@changelog = Parser.parse(File.read(@changelog_file))
|
55
62
|
|
56
|
-
# Merge fragment changes if
|
63
|
+
# Merge fragment changes if source is provided
|
57
64
|
merged_changes = changes.dup
|
58
|
-
if
|
59
|
-
|
60
|
-
fragment_changes =
|
65
|
+
if fragment
|
66
|
+
handler = FragmentHandler.for(fragment)
|
67
|
+
fragment_changes = handler.read
|
61
68
|
fragment_changes.each do |section, entries|
|
62
69
|
merged_changes[section] ||= []
|
63
70
|
merged_changes[section].concat(entries)
|
@@ -1,14 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "pathname"
|
2
4
|
|
3
5
|
module Reissue
|
4
|
-
|
6
|
+
# Handler for reading fragments from a directory
|
7
|
+
class DirectoryFragmentHandler < FragmentHandler
|
5
8
|
DEFAULT_VALID_SECTIONS = %w[added changed deprecated removed fixed security].freeze
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
attr_reader :directory, :valid_sections
|
11
|
+
|
12
|
+
# Initialize the handler with a directory path
|
13
|
+
#
|
14
|
+
# @param directory [String] The path to the fragments directory
|
15
|
+
# @param valid_sections [Array<String>, nil] List of valid section names, or nil to allow all
|
16
|
+
def initialize(directory, valid_sections: DEFAULT_VALID_SECTIONS)
|
17
|
+
@directory = directory
|
18
|
+
@fragment_directory = Pathname.new(directory)
|
9
19
|
@valid_sections = valid_sections
|
10
20
|
end
|
11
21
|
|
22
|
+
# Read fragments from the directory
|
23
|
+
#
|
24
|
+
# @return [Hash] A hash of changelog entries organized by category
|
12
25
|
def read
|
13
26
|
return {} unless @fragment_directory.exist?
|
14
27
|
|
@@ -35,6 +48,9 @@ module Reissue
|
|
35
48
|
fragments
|
36
49
|
end
|
37
50
|
|
51
|
+
# Clear all fragment files from the directory
|
52
|
+
#
|
53
|
+
# @return [nil]
|
38
54
|
def clear
|
39
55
|
return unless @fragment_directory.exist?
|
40
56
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reissue
|
4
|
+
class FragmentHandler
|
5
|
+
# Handles reading changelog entries from git commit trailers
|
6
|
+
class GitFragmentHandler < FragmentHandler
|
7
|
+
# Regex to match changelog section trailers in commit messages
|
8
|
+
TRAILER_REGEX = /^(Added|Changed|Deprecated|Removed|Fixed|Security):\s*(.+)$/i
|
9
|
+
|
10
|
+
# Valid changelog sections that can be used as trailers
|
11
|
+
VALID_SECTIONS = %w[Added Changed Deprecated Removed Fixed Security].freeze
|
12
|
+
|
13
|
+
# Read changelog entries from git commit trailers
|
14
|
+
#
|
15
|
+
# @return [Hash] A hash of changelog entries organized by section
|
16
|
+
def read
|
17
|
+
return {} unless git_available? && in_git_repo?
|
18
|
+
|
19
|
+
commits = commits_since_last_tag
|
20
|
+
parse_trailers_from_commits(commits)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Clear operation is a no-op for git trailers
|
24
|
+
#
|
25
|
+
# @return [nil]
|
26
|
+
def clear
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def git_available?
|
33
|
+
system("git --version", out: File::NULL, err: File::NULL)
|
34
|
+
end
|
35
|
+
|
36
|
+
def in_git_repo?
|
37
|
+
system("git rev-parse --git-dir", out: File::NULL, err: File::NULL)
|
38
|
+
end
|
39
|
+
|
40
|
+
def commits_since_last_tag
|
41
|
+
last_tag = find_last_tag
|
42
|
+
|
43
|
+
commit_range = if last_tag
|
44
|
+
# Get commits since the last tag
|
45
|
+
"#{last_tag}..HEAD"
|
46
|
+
else
|
47
|
+
# No tags found, get all commits
|
48
|
+
"HEAD"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get commit messages with trailers, in reverse order (oldest first)
|
52
|
+
output = `git log #{commit_range} --reverse --format=%B 2>/dev/null`
|
53
|
+
return [] if output.empty?
|
54
|
+
|
55
|
+
# Split by double newline to separate commits
|
56
|
+
output.split(/\n\n+/)
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_last_tag
|
60
|
+
# Try to find the most recent tag
|
61
|
+
tag = `git describe --tags --abbrev=0 2>/dev/null`.strip
|
62
|
+
tag.empty? ? nil : tag
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_trailers_from_commits(commits)
|
66
|
+
result = {}
|
67
|
+
|
68
|
+
commits.each do |commit|
|
69
|
+
# Split commit into lines and look for trailers
|
70
|
+
commit.lines.each do |line|
|
71
|
+
line = line.strip
|
72
|
+
next if line.empty?
|
73
|
+
|
74
|
+
if (match = line.match(TRAILER_REGEX))
|
75
|
+
section_name = normalize_section_name(match[1])
|
76
|
+
trailer_value = match[2].strip
|
77
|
+
|
78
|
+
result[section_name] ||= []
|
79
|
+
result[section_name] << trailer_value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
def normalize_section_name(name)
|
88
|
+
# Normalize to proper case (e.g., "FIXED" -> "Fixed", "added" -> "Added")
|
89
|
+
name.capitalize
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reissue
|
4
|
+
# Handler for when no fragment source is configured
|
5
|
+
class NullFragmentHandler < FragmentHandler
|
6
|
+
# Read fragments (returns empty hash since no source is configured)
|
7
|
+
#
|
8
|
+
# @return [Hash] An empty hash
|
9
|
+
def read
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Clear fragments (no-op since no source is configured)
|
14
|
+
#
|
15
|
+
# @return [nil]
|
16
|
+
def clear
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reissue
|
4
|
+
# Base class for handling fragment reading from various sources
|
5
|
+
class FragmentHandler
|
6
|
+
# Read fragments from the configured source
|
7
|
+
#
|
8
|
+
# @return [Hash] A hash of changelog entries organized by category
|
9
|
+
# @raise [NotImplementedError] Must be implemented by subclasses
|
10
|
+
def read
|
11
|
+
raise NotImplementedError, "Subclasses must implement #read"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Clear fragments from the configured source
|
15
|
+
#
|
16
|
+
# @raise [NotImplementedError] Must be implemented by subclasses
|
17
|
+
def clear
|
18
|
+
raise NotImplementedError, "Subclasses must implement #clear"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Factory method to create the appropriate handler for the given option
|
22
|
+
#
|
23
|
+
# @param fragment_option [nil, String, Symbol] The fragment configuration
|
24
|
+
# @param valid_sections [Array<String>, nil] List of valid section names (for directory handler)
|
25
|
+
# @return [FragmentHandler] The appropriate handler instance
|
26
|
+
# @raise [ArgumentError] If the option is not supported
|
27
|
+
def self.for(fragment_option, valid_sections: nil)
|
28
|
+
case fragment_option
|
29
|
+
when nil
|
30
|
+
require_relative "fragment_handler/null_fragment_handler"
|
31
|
+
NullFragmentHandler.new
|
32
|
+
when String
|
33
|
+
require_relative "fragment_handler/directory_fragment_handler"
|
34
|
+
options = {}
|
35
|
+
options[:valid_sections] = valid_sections if valid_sections
|
36
|
+
DirectoryFragmentHandler.new(fragment_option, **options)
|
37
|
+
when :git
|
38
|
+
require_relative "fragment_handler/git_fragment_handler"
|
39
|
+
GitFragmentHandler.new
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Invalid fragment option: #{fragment_option.inspect}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/reissue/rake.rb
CHANGED
@@ -36,9 +36,24 @@ module Reissue
|
|
36
36
|
# Provide a callable to decide how to store the files.
|
37
37
|
attr_accessor :retain_changelogs
|
38
38
|
|
39
|
-
# The
|
40
|
-
#
|
41
|
-
|
39
|
+
# The fragment configuration for changelog entries.
|
40
|
+
# @return [String, nil] nil (disabled) or a directory path string for fragment files
|
41
|
+
# @example Using directory-based fragments
|
42
|
+
# task.fragment = "changelog_fragments"
|
43
|
+
# @note Default: nil (disabled)
|
44
|
+
attr_accessor :fragment
|
45
|
+
|
46
|
+
# @deprecated Use {#fragment} instead
|
47
|
+
def fragment_directory=(value)
|
48
|
+
warn "[DEPRECATION] `fragment_directory` is deprecated. Please use `fragment` instead."
|
49
|
+
self.fragment = value
|
50
|
+
end
|
51
|
+
|
52
|
+
# @deprecated Use {#fragment} instead
|
53
|
+
def fragment_directory
|
54
|
+
warn "[DEPRECATION] `fragment_directory` is deprecated. Please use `fragment` instead."
|
55
|
+
@fragment
|
56
|
+
end
|
42
57
|
|
43
58
|
# Whether to clear fragment files after processing.
|
44
59
|
# Default: false.
|
@@ -85,7 +100,7 @@ module Reissue
|
|
85
100
|
@updated_paths = []
|
86
101
|
@changelog_file = "CHANGELOG.md"
|
87
102
|
@retain_changelogs = false
|
88
|
-
@
|
103
|
+
@fragment = nil
|
89
104
|
@clear_fragments = false
|
90
105
|
@commit = true
|
91
106
|
@commit_finalize = true
|
@@ -132,7 +147,7 @@ module Reissue
|
|
132
147
|
version_file:,
|
133
148
|
version_limit:,
|
134
149
|
version_redo_proc:,
|
135
|
-
|
150
|
+
fragment: fragment
|
136
151
|
)
|
137
152
|
bundle
|
138
153
|
|
@@ -177,7 +192,7 @@ module Reissue
|
|
177
192
|
date,
|
178
193
|
changelog_file:,
|
179
194
|
retain_changelogs:,
|
180
|
-
|
195
|
+
fragment: fragment
|
181
196
|
)
|
182
197
|
finalize_message = "Finalize the changelog for version #{version} on #{date}"
|
183
198
|
if commit_finalize
|
@@ -218,14 +233,49 @@ module Reissue
|
|
218
233
|
system("git push origin HEAD")
|
219
234
|
end
|
220
235
|
|
236
|
+
desc "Preview changelog entries that will be added from fragments or git trailers"
|
237
|
+
task "#{name}:preview" do
|
238
|
+
if fragment
|
239
|
+
require_relative "fragment_handler"
|
240
|
+
handler = Reissue::FragmentHandler.for(fragment)
|
241
|
+
entries = handler.read
|
242
|
+
|
243
|
+
if entries.empty?
|
244
|
+
puts "No changelog entries found."
|
245
|
+
if fragment == :git
|
246
|
+
puts " (No git trailers found since last version tag)"
|
247
|
+
else
|
248
|
+
puts " (No fragment files found in '#{fragment}')"
|
249
|
+
end
|
250
|
+
else
|
251
|
+
puts "Changelog entries that will be added:\n\n"
|
252
|
+
# Sort sections in Keep a Changelog order
|
253
|
+
section_order = %w[Added Changed Deprecated Removed Fixed Security]
|
254
|
+
sorted_sections = entries.keys.sort_by { |k| section_order.index(k) || 999 }
|
255
|
+
|
256
|
+
sorted_sections.each do |section|
|
257
|
+
items = entries[section]
|
258
|
+
puts "### #{section}\n"
|
259
|
+
items.each { |item| puts "- #{item}" }
|
260
|
+
puts
|
261
|
+
end
|
262
|
+
|
263
|
+
puts "Total: #{entries.values.flatten.count} entries across #{entries.keys.count} sections"
|
264
|
+
end
|
265
|
+
else
|
266
|
+
puts "Fragment handling is not configured."
|
267
|
+
puts "Set task.fragment to a directory path or :git to enable changelog fragments."
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
221
271
|
desc "Clear fragments"
|
222
272
|
task "#{name}:clear_fragments" do
|
223
273
|
# Clear fragments after release if configured
|
224
|
-
if
|
225
|
-
formatter.clear_fragments(
|
274
|
+
if fragment && clear_fragments
|
275
|
+
formatter.clear_fragments(fragment)
|
226
276
|
clear_message = "Clear changelog fragments"
|
227
277
|
if commit_clear_fragments
|
228
|
-
system("git add #{
|
278
|
+
system("git add #{fragment}")
|
229
279
|
system("git commit -m '#{clear_message}'")
|
230
280
|
else
|
231
281
|
system("echo '#{clear_message}'")
|
data/lib/reissue/version.rb
CHANGED
data/lib/reissue.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative "reissue/version"
|
4
4
|
require_relative "reissue/version_updater"
|
5
5
|
require_relative "reissue/changelog_updater"
|
6
|
-
require_relative "reissue/
|
6
|
+
require_relative "reissue/fragment_handler"
|
7
7
|
|
8
8
|
# Reissue is a module that provides functionality for updating version numbers and changelogs.
|
9
9
|
module Reissue
|
@@ -15,7 +15,8 @@ module Reissue
|
|
15
15
|
# @param date [String] The release date. Default: Unreleased
|
16
16
|
# @param changes [Hash] The changes made in this release. Default: {}
|
17
17
|
# @param version_limit [Integer] The number of versions to retain in the changes. Default: 2
|
18
|
-
# @param
|
18
|
+
# @param fragment [String, nil] The fragment source configuration (directory path or nil to disable). Default: nil
|
19
|
+
# @param fragment_directory [String] @deprecated Use fragment parameter instead
|
19
20
|
#
|
20
21
|
# @return [String] The new version number.
|
21
22
|
def self.call(
|
@@ -27,13 +28,20 @@ module Reissue
|
|
27
28
|
changes: {},
|
28
29
|
version_limit: 2,
|
29
30
|
version_redo_proc: nil,
|
31
|
+
fragment: nil,
|
30
32
|
fragment_directory: nil
|
31
33
|
)
|
34
|
+
# Handle deprecation
|
35
|
+
if fragment_directory && !fragment
|
36
|
+
warn "[DEPRECATION] `fragment_directory` parameter is deprecated. Please use `fragment` instead."
|
37
|
+
fragment = fragment_directory
|
38
|
+
end
|
39
|
+
|
32
40
|
version_updater = VersionUpdater.new(version_file, version_redo_proc:)
|
33
41
|
new_version = version_updater.call(segment, version_file:)
|
34
42
|
if changelog_file
|
35
43
|
changelog_updater = ChangelogUpdater.new(changelog_file)
|
36
|
-
changelog_updater.call(new_version, date:, changes:, changelog_file:, version_limit:, retain_changelogs:,
|
44
|
+
changelog_updater.call(new_version, date:, changes:, changelog_file:, version_limit:, retain_changelogs:, fragment:)
|
37
45
|
end
|
38
46
|
new_version
|
39
47
|
end
|
@@ -42,14 +50,21 @@ module Reissue
|
|
42
50
|
#
|
43
51
|
# @param date [String] The release date.
|
44
52
|
# @param changelog_file [String] The path to the changelog file.
|
45
|
-
# @param
|
53
|
+
# @param fragment [String, nil] The fragment source configuration (directory path or nil to disable). Default: nil
|
54
|
+
# @param fragment_directory [String] @deprecated Use fragment parameter instead
|
46
55
|
#
|
47
56
|
# @return [Array] The version number and release date.
|
48
|
-
def self.finalize(date = Date.today, changelog_file: "CHANGELOG.md", retain_changelogs: false, fragment_directory: nil)
|
57
|
+
def self.finalize(date = Date.today, changelog_file: "CHANGELOG.md", retain_changelogs: false, fragment: nil, fragment_directory: nil)
|
58
|
+
# Handle deprecation
|
59
|
+
if fragment_directory && !fragment
|
60
|
+
warn "[DEPRECATION] `fragment_directory` parameter is deprecated. Please use `fragment` instead."
|
61
|
+
fragment = fragment_directory
|
62
|
+
end
|
63
|
+
|
49
64
|
changelog_updater = ChangelogUpdater.new(changelog_file)
|
50
65
|
|
51
66
|
# If fragments are present, we need to update the unreleased version with them first
|
52
|
-
if
|
67
|
+
if fragment
|
53
68
|
# Get the current changelog to find the unreleased version
|
54
69
|
changelog = Parser.parse(File.read(changelog_file))
|
55
70
|
unreleased_version = changelog["versions"].find { |v| v["date"] == "Unreleased" }
|
@@ -60,7 +75,7 @@ module Reissue
|
|
60
75
|
unreleased_version["version"],
|
61
76
|
date: "Unreleased",
|
62
77
|
changes: unreleased_version["changes"] || {},
|
63
|
-
|
78
|
+
fragment: fragment,
|
64
79
|
version_limit: changelog["versions"].size
|
65
80
|
)
|
66
81
|
changelog_updater.write(changelog_file, retain_changelogs: false)
|
@@ -113,13 +128,13 @@ module Reissue
|
|
113
128
|
)
|
114
129
|
end
|
115
130
|
|
116
|
-
# Clears all fragment files in the specified
|
131
|
+
# Clears all fragment files in the specified source.
|
117
132
|
#
|
118
|
-
# @param
|
119
|
-
def self.clear_fragments(
|
120
|
-
return unless
|
133
|
+
# @param fragment [String] The fragment source configuration.
|
134
|
+
def self.clear_fragments(fragment)
|
135
|
+
return unless fragment
|
121
136
|
|
122
|
-
|
123
|
-
|
137
|
+
handler = FragmentHandler.for(fragment)
|
138
|
+
handler.clear
|
124
139
|
end
|
125
140
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reissue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
@@ -36,7 +36,10 @@ files:
|
|
36
36
|
- Rakefile
|
37
37
|
- lib/reissue.rb
|
38
38
|
- lib/reissue/changelog_updater.rb
|
39
|
-
- lib/reissue/
|
39
|
+
- lib/reissue/fragment_handler.rb
|
40
|
+
- lib/reissue/fragment_handler/directory_fragment_handler.rb
|
41
|
+
- lib/reissue/fragment_handler/git_fragment_handler.rb
|
42
|
+
- lib/reissue/fragment_handler/null_fragment_handler.rb
|
40
43
|
- lib/reissue/gem.rb
|
41
44
|
- lib/reissue/markdown.rb
|
42
45
|
- lib/reissue/parser.rb
|