Module: SafeMemoize::ReleaseTooling Private

Defined in:
lib/safe_memoize/release_tooling.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Constant Summary collapse

VERSION_PATTERN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/VERSION = "[^"]+"/
SEMVER_PATTERN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/\A\d+\.\d+\.\d+(?:[-.][0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?\z/
UNRELEASED_HEADING =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

"## [Unreleased]"

Class Method Summary collapse

Class Method Details

.extract_release_notes(contents, version) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Raises:

  • (ArgumentError)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/safe_memoize/release_tooling.rb', line 74

def extract_release_notes(contents, version)
  normalized_version = normalize_version(version)
  lines = contents.lines
  release_heading = /^## \[#{Regexp.escape(normalized_version)}\](?: - .+)?$/
  start_index = lines.index { |line| line.match?(release_heading) }

  raise ArgumentError, "CHANGELOG.md is missing release notes for #{normalized_version}" unless start_index

  body = lines[(start_index + 1)..].take_while { |line| !line.start_with?("## [") }.join.strip
  body = "- No changes listed." if body.empty?

  <<~MARKDOWN
    ## SafeMemoize #{normalized_version}

    #{body}
  MARKDOWN
end

.finalize_changelog(contents, version, date = Date.today) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/safe_memoize/release_tooling.rb', line 34

def finalize_changelog(contents, version, date = Date.today)
  normalized_version = normalize_version(version)
  release_heading = "## [#{normalized_version}] - #{date.iso8601}"

  unless contents.include?(UNRELEASED_HEADING)
    raise ArgumentError, "CHANGELOG.md must contain an Unreleased heading"
  end

  if contents.match?(/^## \[#{Regexp.escape(normalized_version)}\](?: - .+)?$/)
    raise ArgumentError, "CHANGELOG.md already contains #{normalized_version}"
  end

  contents.sub(UNRELEASED_HEADING, "#{UNRELEASED_HEADING}\n\n#{release_heading}")
end

.normalize_version(version) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



14
15
16
17
18
19
20
21
22
# File 'lib/safe_memoize/release_tooling.rb', line 14

def normalize_version(version)
  normalized_version = version.to_s.sub(/\Av/, "")

  unless normalized_version.match?(SEMVER_PATTERN)
    raise ArgumentError, "version must look like x.y.z"
  end

  normalized_version
end

.prune_roadmap(contents) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes milestone sections from ROADMAP.md where every feature row has "Shipped" status. Non-milestone sections (Versioning policy, Contributing, etc.) and sections with any non-Shipped row are left untouched.

Sections are delimited by the +\n\n---\n\n+ horizontal-rule separator that the ROADMAP uses between headings. A milestone section is any section whose first non-blank line starts with +## v+.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/safe_memoize/release_tooling.rb', line 56

def prune_roadmap(contents)
  separator = "\n\n---\n\n"
  sections = contents.split(separator)

  pruned = sections.reject do |section|
    next false unless section.lstrip.start_with?("## v")

    # Table rows: lines starting with "|"; drop alignment rows (only |, -, :, whitespace)
    rows = section.lines.select { |l| l.strip.start_with?("|") }
    rows = rows.reject { |l| l.match?(/\A[\s|:-]+\z/) }
    data_rows = rows.drop(1) # first row is the header

    data_rows.any? && data_rows.all? { |row| row.strip.end_with?("Shipped |") }
  end

  pruned.join(separator)
end

.update_version_file(contents, version) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



24
25
26
27
28
29
30
31
32
# File 'lib/safe_memoize/release_tooling.rb', line 24

def update_version_file(contents, version)
  normalized_version = normalize_version(version)

  unless contents.match?(VERSION_PATTERN)
    raise ArgumentError, "version file does not define VERSION"
  end

  contents.sub(VERSION_PATTERN, %(VERSION = "#{normalized_version}"))
end