lib/knife/changelog/policyfile.rb in knife-changelog-1.4.2 vs lib/knife/changelog/policyfile.rb in knife-changelog-1.5.0
- old
+ new
@@ -105,28 +105,46 @@
#
# @param source_url [String] Git repository URL
# @param current [String] current cookbook version tag
# @param target [String] target cookbook version tag
# @return [String] changelog between tags for one cookbook
- def git_changelog(source_url, current, target)
+ def git_changelog(source_url, current, target, cookbook = nil)
dir = Dir.mktmpdir(TMP_PREFIX)
repo = Git.clone(source_url, dir)
- repo.log.between(git_ref(current, repo), git_ref(target, repo)).map do |commit|
+ cookbook_path = cookbook ? git_cookbook_path(repo, cookbook) : '.'
+ repo.log.path(cookbook_path).between(git_ref(current, repo, cookbook), git_ref(target, repo, cookbook)).map do |commit|
"#{commit.sha[0, 7]} #{commit.message.lines.first.strip}"
end.join("\n")
end
+ # Tries to find the location of a specific cookbook in the given repo
+ #
+ # @param repo [Git::Base] Git repository object
+ # @param cookbook [String] name of the cookbook to search the location
+ # @return [String] reative location of the cookbook in the repo
+ def git_cookbook_path(repo, cookbook)
+ metadata_files = ['metadata.rb', '*/metadata.rb'].flat_map { |location| repo.ls_files(location).keys }
+ metadata_path = metadata_files.find do |path|
+ path = ::File.join(repo.dir.to_s, path)
+ ::Chef::Cookbook::Metadata.new.tap { |m| m.from_file(path) }.name == cookbook
+ end
+ raise "Impossible to find matching metadata for #{cookbook} in #{repo.remote.url}" unless metadata_path
+ ::File.dirname(metadata_path)
+ end
+
# Tries to convert a supermarket tag to a git reference
# if there is a difference in formatting between the two.
# This is issue is present for the 'java' cookbook.
# https://github.com/agileorbit-cookbooks/java/issues/450
#
# @param ref [String] version reference
# @param repo [Git::Base] Git repository object
+ # @param cookbook [String] name of the cookbook to ref against
# @return [String]
- def git_ref(myref, repo)
+ def git_ref(myref, repo, cookbook_name = nil)
possible_refs = ['v' + myref, myref]
+ possible_refs += possible_refs.map { |ref| "#{cookbook_name}-#{ref}" } if cookbook_name
possible_refs += possible_refs.map { |ref| ref.chomp('.0') } if myref[/\.0$/]
existing_ref = possible_refs.find do |ref|
begin
repo.checkout(ref)
rescue ::Git::GitExecuteError
@@ -160,10 +178,10 @@
# @return [String] formatted changelog
def format_output(name, data)
output = ["\nChangelog for #{name}: #{data['current_version']}->#{data['target_version']}"]
output << '=' * output.first.size
output << if data['current_version']
- git_changelog(data['source_url'], data['current_version'], data['target_version'])
+ git_changelog(data['source_url'], data['current_version'], data['target_version'], name)
else
'Cookbook was not in the Policyfile.lock.json'
end
output.join("\n")