class Bake::Modernize::License::Authorship
Represents the authorship of a repository.
def add(path, author, time, id = nil)
def add(path, author, time, id = nil) modification = Modification.new(author, time, path, id) @commits[modification.key] << modification @paths[path] << modification end
def copyrights
def copyrights copyrights_for_modifications(@paths.values.flatten) end
def copyrights_for_modifications(modifications)
def copyrights_for_modifications(modifications) authors = modifications.group_by{|modification| modification.full_name} authors.map do |name, modifications| Copyright.new(modifications.map(&:time).minmax, name) end.sort end
def copyrights_for_path(path)
def copyrights_for_path(path) copyrights_for_modifications(@paths[path]) end
def extract(root = Dir.pwd)
def extract(root = Dir.pwd) mailmap = Mailmap.for(root) skip_list = SkipList.for(root) if contributors = Contributors.for(root, mailmap: mailmap) contributors.each do |path, author, time| add(path, author, time) end end walk(Rugged::Repository.discover(root), mailmap: mailmap, skip_list: skip_list) return self end
def initialize
def initialize @paths = Hash.new{|h,k| h[k] = []} @commits = Hash.new{|h,k| h[k] = []} end
def sorted_authors
def sorted_authors authors = Hash.new{|h,k| h[k] = 0} @commits.each do |key, modifications| modifications.map(&:full_name).uniq.each do |full_name| authors[full_name] += 1 end end return authors.sort_by{|k,v| [-v, k]}.map(&:first) end
def walk(repository, mailmap: nil, skip_list: nil, show: "HEAD")
def walk(repository, mailmap: nil, skip_list: nil, show: "HEAD") Rugged::Walker.walk(repository, show: show, sort: DEFAULT_SORT) do |commit| next if skip_list&.ignore?(commit) diff = commit.diff # We relax the threshold for copy and rename detection because we want to detect files that have been moved and modified more generously. diff.find_similar!( rename_threshold: 25, copy_threshold: 25, ignore_whitespace: true, ) diff.each_delta do |delta| old_path = delta.old_file[:path] new_path = delta.new_file[:path] @paths[new_path] ||= [] if old_path != new_path # The file was moved, move copyright information too: Console.logger.debug(self, "Moving #{old_path} to #{new_path}", similarity: delta.similarity) @paths[new_path].concat(@paths[old_path]) end author = commit.author if mailmap if name = mailmap.names[author[:email]] author[:name] = name end end add(new_path, author, commit.time, commit.oid) end end end