Module: PDK::Util::ChangelogGenerator

Defined in:
lib/pdk/util/changelog_generator.rb

Constant Summary collapse

VERSION_REGEX =

Taken from the version regex in forgeapi.puppet.com/schemas/module.json

%r{^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$}
GEM =
'github_changelog_generator'.freeze

Class Method Summary collapse

Class Method Details

.changelog_contentObject



114
115
116
117
# File 'lib/pdk/util/changelog_generator.rb', line 114

def self.changelog_content
  return '' if changelog_file.nil?
  PDK::Util::Filesystem.read_file(changelog_file, open_args: 'rb:utf-8')
end

.changelog_fileObject



109
110
111
112
# File 'lib/pdk/util/changelog_generator.rb', line 109

def self.changelog_file
  # Default Changelog file is CHANGELOG.md, but also search for the .MD prefix as well.
  @changelog_file ||= ['CHANGELOG.md', 'CHANGELOG.MD'].map { |file| PDK::Util::Filesystem.expand_path(file) }.find { |path| PDK::Util::Filesystem.file?(path) }
end

.compute_next_version(current_version) ⇒ String

Computes the next version, based on the content of a changelog

Parameters:

  • current_version (String, Gem::Version)

    The current version of the module

Returns:

  • (String)

    The new version. May be the same as the current version if there are no notable changes

Raises:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pdk/util/changelog_generator.rb', line 42

def self.compute_next_version(current_version)
  raise PDK::CLI::ExitWithError, _('Invalid version string %{version}' % { version: current_version }) unless current_version =~ VERSION_REGEX
  version = Gem::Version.create(current_version).segments
  PDK.logger.info _('Determing the target version from \'%{file}\'') % { file: changelog_file }

  # Grab all lines that start with ## between from the latest changes
  # For example given the changelog below

  # ```
  # # Change log
  #
  # All notable changes to this project will be documented in this file.
  #
  # ## [v4.0.0](https://github.com/puppetlabs/puppetlabs-inifile/tree/v4.
  #
  # [Full Changelog](https://github.com/puppetlabs/puppetlabs-inifile/com   --+
  #                                                                           |
  # ### Changed                                                               |
  #                                                                           |
  # - pdksync - FM-8499 - remove ubuntu14 support [\#363](https://github.     |  It's this piece of text we are interested in
  #                                                                           |
  # ### Added                                                                 |
  #                                                                           |
  # - FM-8402 add debian 10 support [\#352](https://github.com/puppetlabs     |
  #                                                                           |
  # ## [v3.1.0](https://github.com/puppetlabs/puppetlabs-inifile/tree/v3.     |
  #                                                                         --+
  # [Full Changelog](https://github.com/puppetlabs/puppetlabs-inifile/com
  #
  # ### Added
  #
  # - FM-8222 - Port Module inifile to Litmus [\#344](https://github.com/
  # - \(FM-8154\) Add Windows Server 2019 support [\#340](https://github.
  # - \(FM-8041\) Add RedHat 8 support [\#339](https://github.com/puppetl
  # ````
  data = ''
  in_changelog_entry = false
  changelog_content.each_line do |line|
    line.strip!
    if line.start_with?('[')
      # We're leaving the latest changes so we can break
      break if in_changelog_entry
      in_changelog_entry = true
    end
    if in_changelog_entry && line.start_with?('##')
      data += line
    end
  end

  # Check for meta headers in first two header line matches
  if data =~ %r{^### Changed}
    # Major Version bump
    version[0] += 1
    version[1] = 0
    version[2] = 0
  elsif data =~ %r{^### Added}
    # Minor Version bump
    version[1] += 1
    version[2] = 0
  elsif data =~ %r{^### Fixed}
    # Patch Version bump
    version[2] += 1
  end

  version.join('.')
end

.generate_changelogObject

Runs the Changelog Generator gem (in the module’s context) to automatically create a CHANGLELOG.MD file



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/pdk/util/changelog_generator.rb', line 23

def self.generate_changelog
  github_changelog_generator_available!

  changelog_command = PDK::CLI::Exec::InteractiveCommand.new(PDK::CLI::Exec.bundle_bin, 'exec', 'rake', 'changelog')
  changelog_command.context = :module

  result = changelog_command.execute!
  raise PDK::CLI::ExitWithError, _('Error generating changelog: %{stdout}' % { stdout: result[:stdout] }) unless result[:exit_code].zero?

  output = changelog_content

  raise PDK::CLI::ExitWithError, _('The generated changelog contains uncategorized Pull Requests. Please label them and try again. See %{changelog_file} for more details' % { changelog_file: changelog_file }) if output =~ %r{UNCATEGORIZED PRS; GO LABEL THEM} # rubocop:disable Metrics/LineLength
  output
end

.github_changelog_generator_available!Object

Raises if the github_changelog_generator is not available



11
12
13
14
15
16
17
18
# File 'lib/pdk/util/changelog_generator.rb', line 11

def self.github_changelog_generator_available!
  require 'bundler'
  return if ::Bundler.rubygems.find_name(GEM).any?

  raise PDK::CLI::ExitWithError, _(
    'Unable to generate the changelog as the %{gem} gem is not installed',
  ) % { gem: GEM }
end