Chris@1538: #!/usr/bin/env ruby Chris@1538: Chris@1538: # Create authormap files for hg repos based on the changeset & project Chris@1538: # member info available to Redmine. Chris@1538: # Chris@1538: # We have a set of hg repos in a given directory: Chris@1538: # Chris@1538: # /var/hg/repo_1 Chris@1538: # /var/hg/repo_2 Chris@1538: # /var/hg/repo_3 Chris@1538: # Chris@1538: # and we want to produce authormap files in another directory: Chris@1538: # Chris@1538: # /var/repo-export/authormap/authormap_repo_1 Chris@1538: # /var/repo-export/authormap/authormap_repo_2 Chris@1538: # /var/repo-export/authormap/authormap_repo_3 Chris@1538: # Chris@1538: # This script does that, if given the two directory names as arguments Chris@1538: # to the -s and -o options. In the above example: Chris@1538: # Chris@1538: # create-repo-authormaps.rb -s /var/hg -o /var/repo-export/authormap Chris@1538: # Chris@1538: # Note that this script will overwrite any existing authormap Chris@1538: # files. (That's why the output files are given an authormap_ prefix, Chris@1538: # so we're less likely to clobber something else if the user gets the Chris@1538: # arguments wrong.) Chris@1538: Chris@1538: require 'getoptlong' Chris@1538: Chris@1538: opts = GetoptLong.new( Chris@1538: ['--scm-dir', '-s', GetoptLong::REQUIRED_ARGUMENT], Chris@1538: ['--out-dir', '-o', GetoptLong::REQUIRED_ARGUMENT] Chris@1538: ) Chris@1538: Chris@1538: $repos_base = '' Chris@1538: $out_base = '' Chris@1538: Chris@1538: def usage Chris@1538: puts "See source code for supported options" Chris@1538: exit Chris@1538: end Chris@1538: Chris@1538: begin Chris@1538: opts.each do |opt, arg| Chris@1538: case opt Chris@1538: when '--scm-dir'; $repos_base = arg.dup Chris@1538: when '--out-dir'; $out_base = arg.dup Chris@1538: end Chris@1538: end Chris@1538: rescue Chris@1538: exit 1 Chris@1538: end Chris@1538: Chris@1538: if ($repos_base.empty? or $out_base.empty?) Chris@1538: usage Chris@1538: end Chris@1538: Chris@1538: unless File.directory?($repos_base) Chris@1538: log("input directory '#{$repos_base}' doesn't exist", :exit => true) Chris@1538: end Chris@1538: Chris@1538: unless File.directory?($out_base) Chris@1538: log("output directory '#{$out_base}' doesn't exist", :exit => true) Chris@1538: end Chris@1538: Chris@1538: projects = Project.find(:all) Chris@1538: Chris@1538: if projects.nil? Chris@1538: log('No projects found', :exit => true) Chris@1538: end Chris@1538: Chris@1538: projects.each do |proj| Chris@1538: next unless proj.respond_to?(:repository) Chris@1538: Chris@1538: repo = proj.repository Chris@1538: Chris@1538: repo_url = repo.url Chris@1538: repo_url = repo_url.gsub(/^file:\/*/, "/"); Chris@1538: if repo_url != File.join($repos_base, proj.identifier) Chris@1538: log('Project #{proj.identifier} has repo in unsupported location #{repo_url}, skipping') Chris@1538: next Chris@1538: end Chris@1538: Chris@1538: csets = repo.changesets Chris@1538: committers = csets.map do |c| c.committer end.sort.uniq Chris@1538: Chris@1538: authormap = "" Chris@1538: committers.each do |c| Chris@1538: if not c =~ /[^<]+<.*@.*>/ then Chris@1538: user = repo.find_committer_user c Chris@1538: authormap << "#{c}=#{u.name} <#{u.mail}>\n" unless u.nil? Chris@1538: end Chris@1538: end Chris@1538: Chris@1538: File.open (File.join($out_base, "authormap_#{proj.identifier}"), "w") do |f| Chris@1538: f.puts(authormap) Chris@1538: end Chris@1538: Chris@1538: end Chris@1538: