Mercurial > hg > soundsoftware-site
view extra/soundsoftware/create-repo-authormaps.rb @ 1628:9c5f8e24dadc live tip
Quieten this cron script
author | Chris Cannam |
---|---|
date | Tue, 25 Aug 2020 11:38:49 +0100 |
parents | e5c9809534a2 |
children |
line wrap: on
line source
#!/usr/bin/env ruby # Create authormap files for hg repos based on the changeset & project # member info available to Redmine. # # We have a set of hg repos in a given directory: # # /var/hg/repo_1 # /var/hg/repo_2 # /var/hg/repo_3 # # and we want to produce authormap files in another directory: # # /var/repo-export/authormap/authormap_repo_1 # /var/repo-export/authormap/authormap_repo_2 # /var/repo-export/authormap/authormap_repo_3 # # This script does that, if given the two directory names as arguments # to the -s and -o options. In the above example: # # ./script/rails runner -e production extra/soundsoftware/create-repo-authormaps.rb -s /var/hg -o /var/repo-export/authormap # # Note that this script will overwrite any existing authormap # files. (That's why the output files are given an authormap_ prefix, # so we're less likely to clobber something else if the user gets the # arguments wrong.) require 'getoptlong' opts = GetoptLong.new( ['--scm-dir', '-s', GetoptLong::REQUIRED_ARGUMENT], ['--out-dir', '-o', GetoptLong::REQUIRED_ARGUMENT], ['--environment', '-e', GetoptLong::OPTIONAL_ARGUMENT] ) $repos_base = '' $out_base = '' def usage puts "See source code for supported options" exit end begin opts.each do |opt, arg| case opt when '--scm-dir'; $repos_base = arg.dup when '--out-dir'; $out_base = arg.dup end end rescue exit 1 end if ($repos_base.empty? or $out_base.empty?) usage end unless File.directory?($repos_base) puts "input directory '#{$repos_base}' doesn't exist" exit 1 end unless File.directory?($out_base) puts "output directory '#{$out_base}' doesn't exist" exit 1 end projects = Project.find(:all) if projects.nil? puts 'No projects found' exit 1 end projects.each do |proj| next unless proj.is_public next unless proj.respond_to?(:repository) repo = proj.repository next if repo.nil? or repo.url.empty? repo_url = repo.url repo_url = repo_url.gsub(/^file:\/*/, "/"); if repo_url != File.join($repos_base, proj.identifier) puts "Project #{proj.identifier} has repo in unsupported location #{repo_url}, skipping" next end committers = repo.committers authormap = "" committers.each do |c, uid| # Some of our repos have broken email addresses in them: e.g. one # changeset has a committer name of the form # # NAME <name <NAME <name@example.com"> # # I don't know how it got like that... If the committer has more # than one '<' in it, truncate it just before the first one, and # then look up the author name again. # if c =~ /<.*</ then # So this is a completely pathological case user = User.find_by_id uid if user.nil? then # because the given committer is bogus, we must write something in the map name = c.sub(/\s*<.*$/, "") authormap << "#{c}=#{name} <unknown@example.com>\n" else authormap << "#{c}=#{user.name} <#{user.mail}>\n" end elsif not c =~ /[^<]+<.*@.*>/ then # This is the "normal" case that needs work, where a user has # their name in the commit but no email address user = User.find_by_id uid authormap << "#{c}=#{user.name} <#{user.mail}>\n" unless user.nil? end end File.open(File.join($out_base, "authormap_#{proj.identifier}"), "w") do |f| f.puts(authormap) end end