reissue 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cea3fe8e5fffe1889e022f6acb6caf168c28e3af84c94639fbda06ce33dbf326
4
- data.tar.gz: 68e0a7d97426359fdd708fbf147e62fc0904acaa93f245f3f1e4f39f7d1d940a
3
+ metadata.gz: a1a62997c7d2c3f990658a361c9db7e9c197b13acacf8ed25f600f862aca6eda
4
+ data.tar.gz: a427559b697af802e3048ac24e96fffb783bbbd8ee9e970e28075f39580f3ae0
5
5
  SHA512:
6
- metadata.gz: 87626ce0220e19646aab027249f9555a5c201767db04ab146b2bb962aad302423a2f067a93c8c9993d62bafd208de0ff470c9b45376e7030efa4b2fa6c1f1d08
7
- data.tar.gz: 159120e2c1656e1d30470f57bb9c7f2914747f1d8fd8ae88d2fa6f17a9bff8267f7c29be71d0c49c21d6898cff850532578ab1a2263c5cbcb5a4d0266e254966
6
+ metadata.gz: b83c26346790a184c193d577428eb5ed32419f9a68ed9c7e0a60e8a97bf5d4aad654cfdd591fe4e277cace7050bd3b77282967386df58a8e65e878b37fa2863e
7
+ data.tar.gz: bd7fdc98ce401fd1012bacb7d123a131163c666d8061f5996b2ef312371b807c87b81cab48c5e8ccbf9b49c2c656b21b1ce61745fac05c72a5e07ff24923e7ea
data/CHANGELOG.md CHANGED
@@ -1,9 +1,35 @@
1
1
  # Change log
2
+
2
3
  All notable changes to this project will be documented in this file.
3
4
 
4
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
6
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
7
 
7
- ## 0.1.0 - 2024-04-11
8
+ ## [0.1.1] - 2024-06-08
9
+
8
10
  ### Added:
11
+
12
+ - bundle install when running reissue
13
+ - handling of brackets in the changelog version numbers
14
+ - Reissue::Parser class to parse the changelog file
15
+ - Reissue::Printer class to print the changelog file
16
+ - Reissue::Task class to handle the creation of reissue tasks
17
+ - Return version and date from Reissue.finalize
18
+ - Ability to limit the number of versions to maintain
19
+ - Gem release support
20
+ - Description of how to use and configure the gem in the README.md
21
+
22
+ ### Fixed:
23
+
24
+ - bug in tests loading the changelog fixture
25
+ - format of the changelog file
26
+
27
+ ### Removed:
28
+
29
+ - dependency on the keepachangelog gem
30
+
31
+ ## [0.1.0] - 2024-04-11
32
+
33
+ ### Added:
34
+
9
35
  - Initial release
data/README.md CHANGED
@@ -24,10 +24,75 @@ If bundler is not being used to manage dependencies, install the gem by executin
24
24
 
25
25
  ## Usage
26
26
 
27
- Build your own release with rake tasks provided by the gem. The following tasks are available:
27
+ If you are working with a gem, you can add the following to the Rakefile:
28
28
 
29
- - `rake reissue[segment]` - Prepare a new version for future work for the given version segment.
30
- - `rake reissue:finalize` - Update the CHANGELOG.md file with a date for the latest version.
29
+ ```ruby
30
+ require "reissue/gem"
31
+
32
+ Reissue::Task.create :reissue do |task|
33
+ # Required: The file to update with the new version number.
34
+ task.version_file = "lib/my_gem/version.rb"
35
+ end
36
+ ```
37
+
38
+ This will add the following rake tasks:
39
+
40
+ - `rake reissue[segment]` - Prepare a new version for future work for the given
41
+ version segment.
42
+ - `rake reissue:finalize[date]` - Update the CHANGELOG.md file with a date for
43
+ the latest version.
44
+ - `rake reissue:reformat[version_limit]` - Reformat the CHANGELOG.md file and
45
+ optionally limit the number of versions to maintain.
46
+
47
+ This will also update the `build` task from rubygems to first run
48
+ `reissue:finalize` and then build the gem, ensuring that your changelog is
49
+ up-to-date before the gem is built.
50
+
51
+ It updates the `release` task from rubygems to run `reissue` after the gem is
52
+ pushed to rubygems.
53
+
54
+ Build your own release with rake tasks provided by the gem.
55
+
56
+ Add the following to the Rakefile:
57
+
58
+ ```ruby
59
+ require "reissue/rake"
60
+
61
+ Reissue::Task.create :reissue do |task|
62
+ # Required: The file to update with the new version number.
63
+ task.version_file = "path/to/version.rb"
64
+ end
65
+ ```
66
+
67
+ When creating your task, you have additional options to customize the behavior:
68
+
69
+ ```ruby
70
+ require "reissue/rake"
71
+
72
+ Reissue::Task.create :your_name_and_namespace do |task|
73
+
74
+ # Required: The file to update with the new version number.
75
+ task.version_file = "path/to/version.rb"
76
+
77
+ # Optional: The name of the task. Defaults to "reissue".
78
+ task.name = "your_name_and_namespace"
79
+
80
+ # Optional: The description of the task.
81
+ task.description = "Prepare the next version of the gem."
82
+
83
+ # Optional: The file to update with the new version number.
84
+ task.changelog_file = "path/to/CHANGELOG.md"
85
+
86
+ # Optional: The number of versions to maintain in the changelog.
87
+ task.version_limit = 5
88
+
89
+ # Optional: Whether to commit the changes automatically. Defaults to true.
90
+ task.commit = false
91
+
92
+ # Optional: Whether or not to commit the results of the finalize task. Defaults to true.
93
+ task.finalize_commit = false
94
+ end
95
+ ```
31
96
 
32
97
  ## Development
33
98
 
@@ -35,4 +100,4 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
35
100
 
36
101
  ## Contributing
37
102
 
38
- Bug reports and pull requests are welcome on GitHub at https://github.com/[SOFware]/reissue.
103
+ Bug reports and pull requests are welcome on GitHub at https://github.com/SOFware/reissue.
data/Rakefile CHANGED
@@ -12,17 +12,10 @@ end
12
12
 
13
13
  task default: :test
14
14
 
15
- desc "Prepare the code for work on a new version."
16
- task :reissue, [:segment] => ["build:checksum"] do |task, args|
17
- require "reissue"
18
- segment = args[:segment] || "patch"
19
- Reissue.call(segment: segment, version_file: "lib/reissue/version.rb")
20
- end
15
+ require_relative "lib/reissue/gem"
21
16
 
22
- namespace :reissue do
23
- task :finalize, [:date] do |task, args|
24
- require "reissue"
25
- date = args[:date] || Time.now.strftime("%Y-%m-%d")
26
- Reissue.finalize(date, changelog_file: "CHANGELOG.md")
27
- end
17
+ Reissue::Task.create :reissue do |task|
18
+ task.updated_paths << "checksums"
19
+ task.version_file = "lib/reissue/version.rb"
20
+ task.commit = false
28
21
  end
@@ -1,4 +1,5 @@
1
- require "keepachangelog"
1
+ require_relative "parser"
2
+ require_relative "printer"
2
3
 
3
4
  module Reissue
4
5
  # Updates the changelog file with new versions and changes.
@@ -16,23 +17,24 @@ module Reissue
16
17
  # @param date [String] The release date (default: "Unreleased").
17
18
  # @param changes [Hash] The changes for the version (default: {}).
18
19
  # @param changelog_file [String] The path to the changelog file (default: @changelog_file).
19
- def call(version, date: "Unreleased", changes: {}, changelog_file: @changelog_file)
20
- update(version, date: date, changes: changes)
20
+ # @param version_limit [Integer] The number of versions to keep (default: 2).
21
+ def call(version, date: "Unreleased", changes: {}, changelog_file: @changelog_file, version_limit: 2)
22
+ update(version, date:, changes:, version_limit:)
21
23
  write(changelog_file)
22
24
  changelog
23
25
  end
24
26
 
25
27
  def finalize(date: Date.today, changelog_file: @changelog_file)
26
- @changelog = Keepachangelog::MarkdownParser.parse(File.read(changelog_file))
28
+ @changelog = Parser.parse(File.read(changelog_file))
27
29
  # find the highest version number and if it is unreleased, update the date
28
- version = changelog["versions"].keys.max
29
- version_date = changelog.dig("versions", version, "date")
30
+ version = changelog["versions"].max_by { |v| ::Gem::Version.new(v["version"]) }
31
+ version_date = version["date"]
30
32
  if version_date.nil? || version_date == "Unreleased"
31
- updated = changelog["versions"].delete(version)
32
- new_version = version.sub(/\s-.*/, "")
33
- changelog["versions"][new_version] = updated.merge("date" => date)
33
+ changelog["versions"].find do |v|
34
+ v["version"] == version["version"]
35
+ end["date"] = date
34
36
  end
35
- write(changelog_file)
37
+ write
36
38
  changelog
37
39
  end
38
40
 
@@ -41,13 +43,24 @@ module Reissue
41
43
  # @param version [String] The version number.
42
44
  # @param date [String] The release date (default: "Unreleased").
43
45
  # @param changes [Hash] The changes for the version (default: {}).
44
- def update(version, date: "Unreleased", changes: {})
45
- @changelog = Keepachangelog::MarkdownParser.parse(File.read(@changelog_file))
46
+ # @param version_limit [Integer] The number of versions to keep (default: 2).
47
+ # @return [Hash] The updated changelog.
48
+ def update(version, date: "Unreleased", changes: {}, version_limit: 2)
49
+ @changelog = Parser.parse(File.read(@changelog_file))
46
50
 
47
- changelog["versions"][version] = { "date" => date, "changes" => changes }
48
- changes.each do |section, change|
49
- changelog["versions"][version]["changes"][section] = change
50
- end
51
+ changelog["versions"].unshift({"version" => version, "date" => date, "changes" => changes})
52
+ changelog["versions"] = changelog["versions"].first(version_limit)
53
+ changelog
54
+ end
55
+
56
+ # Reformats the changelog file to ensure it is correctly formatted.
57
+ #
58
+ # @param changelog_file [String] The path to the changelog file (default: @changelog_file).
59
+ # @return [Hash] The parsed changelog.
60
+ def reformat(result_file = @changelog_file, version_limit: 2)
61
+ @changelog = Parser.parse(File.read(@changelog_file))
62
+ changelog["versions"] = changelog["versions"].first(version_limit)
63
+ write(result_file)
51
64
  changelog
52
65
  end
53
66
 
@@ -55,7 +68,7 @@ module Reissue
55
68
  #
56
69
  # @return [String] The Markdown string representation of the changelog.
57
70
  def to_s
58
- Keepachangelog::MarkdownPrinter.new(changelog["versions"]).to_s
71
+ Printer.new(changelog).to_s
59
72
  end
60
73
 
61
74
  # Writes the changelog to the specified file.
@@ -0,0 +1,20 @@
1
+ require_relative "rake"
2
+ require "rubygems"
3
+
4
+ module Reissue
5
+ module Gem
6
+ def initialize(...)
7
+ super
8
+ @updated_paths << "checksums"
9
+ end
10
+ end
11
+ end
12
+ Reissue::Task.prepend Reissue::Gem
13
+
14
+ # Run rake reissue:finalize _before_ the build task as a prerequisite.
15
+ Rake::Task[:build].enhance(["reissue:finalize"])
16
+
17
+ # Run the reissue task after the release task.
18
+ Rake::Task["release"].enhance do
19
+ Rake::Task["reissue"].invoke
20
+ end
@@ -0,0 +1,99 @@
1
+ require "strscan"
2
+
3
+ module Reissue
4
+ class Parser
5
+ def self.parse(changelog)
6
+ new(changelog).parse
7
+ end
8
+
9
+ def initialize(changelog)
10
+ @changelog = changelog
11
+ @versions = {}
12
+ @parts = []
13
+ end
14
+
15
+ def parse
16
+ scanner = StringScanner.new(@changelog)
17
+ @parts << parse_title(scanner)
18
+ @parts << parse_preamble(scanner)
19
+ @parts << parse_versions(scanner)
20
+ @parts.compact.reduce(&:merge)
21
+ end
22
+
23
+ VERSION_BREAK = "## "
24
+ CHANGE_BREAK = "### "
25
+ VERSION_MATCH = /^#{VERSION_BREAK}/
26
+ VERSION_OR_CHANGE_MATCH = Regexp.union(CHANGE_BREAK, VERSION_BREAK)
27
+ VERSION_OR_CHANGE_OR_NEWLINE_MATCH = Regexp.union(/\n/, CHANGE_BREAK, VERSION_BREAK)
28
+
29
+ private
30
+
31
+ def parse_title(scanner)
32
+ scanner.scan(/# ([\w\s]+)$/)
33
+ title = scanner[1].strip
34
+ {"title" => title}
35
+ end
36
+
37
+ def parse_preamble(scanner)
38
+ preamble = scanner.scan_until(VERSION_MATCH)
39
+ preamble = preamble.gsub(VERSION_BREAK, "").strip
40
+ scanner.unscan
41
+ {"preamble" => preamble.strip}
42
+ end
43
+
44
+ def parse_versions(scanner)
45
+ until scanner.eos?
46
+ scanner.skip(/\s+/)
47
+ next_line = scanner.scan_until(VERSION_OR_CHANGE_OR_NEWLINE_MATCH)
48
+ break if next_line.nil? || next_line.strip.empty?
49
+ unless next_line.match?(VERSION_OR_CHANGE_MATCH)
50
+ parse_versions(scanner)
51
+ end
52
+ if next_line.match?(VERSION_MATCH)
53
+ scanner.scan_until(/(.+)\n/)
54
+ version, date = scanner[1].split(" - ")
55
+ date ||= "Unreleased"
56
+ version = version.gsub(VERSION_BREAK, "").strip.tr("[]", "")
57
+ changes = parse_changes(scanner)
58
+ @versions[version] = {"version" => version, "date" => date, "changes" => changes}
59
+ parse_versions(scanner)
60
+ end
61
+ end
62
+ {"versions" => @versions.values}
63
+ end
64
+
65
+ def parse_changes(scanner, changes: {})
66
+ return changes if scanner.eos?
67
+ scanner.skip(/\s+/)
68
+
69
+ next_line = scanner.scan_until(/\n/)
70
+ if next_line.nil? || next_line.strip.empty? || next_line.match?(VERSION_MATCH)
71
+ scanner.unscan
72
+ return changes
73
+ end
74
+
75
+ if next_line.match?(CHANGE_BREAK)
76
+ change_type = next_line.gsub(CHANGE_BREAK, "").strip
77
+ changes[change_type] = parse_change_list(scanner)
78
+ end
79
+ parse_changes(scanner, changes: changes)
80
+ end
81
+
82
+ def parse_change_list(scanner, collection: [])
83
+ return collection if scanner.eos?
84
+ scanner.skip(/\s+/)
85
+ change = scanner.scan_until(/\n/)
86
+ if change.nil? || change.strip.empty?
87
+ return collection
88
+ elsif change.match?(VERSION_OR_CHANGE_MATCH)
89
+ scanner.unscan
90
+ return collection
91
+ else
92
+ item = change.sub(/^\s?-\s?/, "").strip
93
+ collection << item
94
+ parse_change_list(scanner, collection:)
95
+ end
96
+ collection.reject(&:empty?).compact
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,43 @@
1
+ module Reissue
2
+ class Printer
3
+ def initialize(changelog)
4
+ @changelog = changelog
5
+ @title = @changelog["title"]
6
+ @preamble = @changelog["preamble"]
7
+ @versions = versions
8
+ end
9
+
10
+ def to_s = <<~MARKDOWN
11
+ # #{@title}
12
+
13
+ #{@preamble}
14
+
15
+ #{@versions}
16
+ MARKDOWN
17
+
18
+ private
19
+
20
+ def versions
21
+ @changelog["versions"].map do |data|
22
+ version = data["version"]
23
+ date = data["date"]
24
+ changes = data.fetch("changes") do
25
+ {}
26
+ end
27
+ version_string = "## [#{version}] - #{date}"
28
+ changes_string = changes.map do |section, changes|
29
+ format_section(section, changes)
30
+ end.join("\n\n")
31
+ [version_string, changes_string].filter_map { |str| str unless str.empty? }.join("\n\n")
32
+ end.join("\n\n")
33
+ end
34
+
35
+ def format_section(section, changes)
36
+ <<~MARKDOWN.strip
37
+ ### #{section}
38
+
39
+ #{changes.map { |change| "- #{change}" }.join("\n")}
40
+ MARKDOWN
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake/tasklib"
4
+ require_relative "../reissue"
5
+
6
+ module Reissue
7
+ class Task < Rake::TaskLib
8
+ def self.create name = :reissue, &block
9
+ task = new name
10
+ task.instance_eval(&block) if block
11
+ raise "No Reissue task.version_file specified" unless task.version_file
12
+ task.define
13
+ task
14
+ end
15
+
16
+ # The name of the main task and the namespace for the other tasks.
17
+ attr_accessor :name
18
+
19
+ # A description of the main task.
20
+ attr_accessor :description
21
+
22
+ # The path to the version file. Required.
23
+ attr_accessor :version_file
24
+
25
+ # The path to the changelog file.
26
+ attr_accessor :changelog_file
27
+
28
+ # Additional paths to add to the commit.
29
+ attr_accessor :updated_paths
30
+
31
+ # The number of versions to retain in the changelog file. Defaults to 2.
32
+ attr_accessor :version_limit
33
+
34
+ # Whether to commit the changes. Default: true.
35
+ attr_accessor :commit
36
+
37
+ # Whether to commit the finalize change to the changelog. Default: true.
38
+ attr_accessor :commit_finalize
39
+
40
+ def initialize(name = :reissue)
41
+ @name = name
42
+ @description = "Prepare the code for work on a new version."
43
+ @version_file = nil
44
+ @updated_paths = []
45
+ @changelog_file = "CHANGELOG.md"
46
+ @commit = true
47
+ @commit_finalize = true
48
+ @version_limit = 2
49
+ end
50
+
51
+ def define
52
+ desc description
53
+ task name, [:segment] do |task, args|
54
+ segment = args[:segment] || "patch"
55
+ new_version = Reissue.call(segment:, version_file:, version_limit:)
56
+ if defined?(Bundler)
57
+ Bundler.with_unbundled_env do
58
+ system("bundle install")
59
+ end
60
+ end
61
+
62
+ system("git add -u")
63
+ if updated_paths.any?
64
+ system("git add #{updated_paths.join(" ")}")
65
+ end
66
+
67
+ bump_message = "Bump version to #{new_version}"
68
+ if commit
69
+ system("git commit -m '#{bump_message}'")
70
+ else
71
+ system("echo '#{bump_message}'")
72
+ end
73
+ end
74
+
75
+ desc "Reformat the changelog file to ensure it is correctly formatted."
76
+ task "#{name}:reformat", [:version_limit] do |task, args|
77
+ version_limit = args[:version_limit].to_i || version_limit
78
+ Reissue.reformat(changelog_file, version_limit:)
79
+ end
80
+
81
+ desc "Finalize the changelog for an unreleased version to set the release date."
82
+ task "#{name}:finalize", [:date] do |task, args|
83
+ date = args[:date] || Time.now.strftime("%Y-%m-%d")
84
+ Reissue.finalize(date, changelog_file:)
85
+ if commit_finalize
86
+ system("git add -u")
87
+ system("git commit -m 'Finalize the changelog for version '")
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reissue
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/reissue.rb CHANGED
@@ -9,17 +9,26 @@ module Reissue
9
9
  # Updates the version number and changelog.
10
10
  #
11
11
  # @param version_file [String] The path to the version file.
12
- # @param changelog_file [String] The path to the changelog file.
13
- # @param segment [String] The segment of the version number to update.
14
- # @param date [String] The release date.
15
- # @param changes [Hash] The changes made in this release.
12
+ # @param changelog_file [String] The path to the changelog file. Default: CHANGELOG.md
13
+ # @param segment [String] The segment of the version number to update. Default: patch
14
+ # @param date [String] The release date. Default: Unreleased
15
+ # @param changes [Hash] The changes made in this release. Default: {}
16
+ # @param version_limit [Integer] The number of versions to retain in the changes. Default: 2
17
+ #
16
18
  # @return [String] The new version number.
17
- def self.call(version_file:, changelog_file: "CHANGELOG.md", segment: "patch", date: "Unreleased", changes: {})
19
+ def self.call(
20
+ version_file:,
21
+ changelog_file: "CHANGELOG.md",
22
+ segment: "patch",
23
+ date: "Unreleased",
24
+ changes: {},
25
+ version_limit: 2
26
+ )
18
27
  version_updater = VersionUpdater.new(version_file)
19
28
  new_version = version_updater.call(segment, version_file:)
20
29
  if changelog_file
21
30
  changelog_updater = ChangelogUpdater.new(changelog_file)
22
- changelog_updater.call(new_version, date:, changes:, changelog_file:)
31
+ changelog_updater.call(new_version, date:, changes:, changelog_file:, version_limit:)
23
32
  end
24
33
  new_version
25
34
  end
@@ -28,8 +37,20 @@ module Reissue
28
37
  #
29
38
  # @param date [String] The release date.
30
39
  # @param changelog_file [String] The path to the changelog file.
40
+ #
41
+ # @return [Array] The version number and release date.
31
42
  def self.finalize(date = Date.today, changelog_file: "CHANGELOG.md")
32
43
  changelog_updater = ChangelogUpdater.new(changelog_file)
33
- changelog_updater.finalize(date:, changelog_file:)
44
+ changelog = changelog_updater.finalize(date:, changelog_file:)
45
+ changelog["versions"].first.slice("version", "date")
46
+ end
47
+
48
+ # Reformats the changelog file to ensure it is correctly formatted.
49
+ #
50
+ # @param file [String] The path to the changelog file.
51
+ # @param version_limit [Integer] The number of versions to retain in the changelog. Default: 2
52
+ def self.reformat(file, version_limit: 2)
53
+ changelog_updater = ChangelogUpdater.new(file)
54
+ changelog_updater.reformat(version_limit:)
34
55
  end
35
56
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reissue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-12 00:00:00.000000000 Z
11
+ date: 2024-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: keepachangelog
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -37,6 +37,10 @@ files:
37
37
  - Rakefile
38
38
  - lib/reissue.rb
39
39
  - lib/reissue/changelog_updater.rb
40
+ - lib/reissue/gem.rb
41
+ - lib/reissue/parser.rb
42
+ - lib/reissue/printer.rb
43
+ - lib/reissue/rake.rb
40
44
  - lib/reissue/version.rb
41
45
  - lib/reissue/version_updater.rb
42
46
  homepage: https://github.com/SOFware/reissue
@@ -60,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
64
  - !ruby/object:Gem::Version
61
65
  version: '0'
62
66
  requirements: []
63
- rubygems_version: 3.5.5
67
+ rubygems_version: 3.5.9
64
68
  signing_key:
65
69
  specification_version: 4
66
70
  summary: Keep your versions and changelogs up to date and prepared for release.