To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / extra / soundsoftware / create-repo-authormaps.rb @ 1567:3ad53f43483d
History | View | Annotate | Download (3.37 KB)
| 1 |
#!/usr/bin/env ruby
|
|---|---|
| 2 |
|
| 3 |
# Create authormap files for hg repos based on the changeset & project
|
| 4 |
# member info available to Redmine.
|
| 5 |
#
|
| 6 |
# We have a set of hg repos in a given directory:
|
| 7 |
#
|
| 8 |
# /var/hg/repo_1
|
| 9 |
# /var/hg/repo_2
|
| 10 |
# /var/hg/repo_3
|
| 11 |
#
|
| 12 |
# and we want to produce authormap files in another directory:
|
| 13 |
#
|
| 14 |
# /var/repo-export/authormap/authormap_repo_1
|
| 15 |
# /var/repo-export/authormap/authormap_repo_2
|
| 16 |
# /var/repo-export/authormap/authormap_repo_3
|
| 17 |
#
|
| 18 |
# This script does that, if given the two directory names as arguments
|
| 19 |
# to the -s and -o options. In the above example:
|
| 20 |
#
|
| 21 |
# ./script/rails runner -e production extra/soundsoftware/create-repo-authormaps.rb -s /var/hg -o /var/repo-export/authormap
|
| 22 |
#
|
| 23 |
# Note that this script will overwrite any existing authormap
|
| 24 |
# files. (That's why the output files are given an authormap_ prefix,
|
| 25 |
# so we're less likely to clobber something else if the user gets the
|
| 26 |
# arguments wrong.)
|
| 27 |
|
| 28 |
require 'getoptlong'
|
| 29 |
|
| 30 |
opts = GetoptLong.new(
|
| 31 |
['--scm-dir', '-s', GetoptLong::REQUIRED_ARGUMENT], |
| 32 |
['--out-dir', '-o', GetoptLong::REQUIRED_ARGUMENT], |
| 33 |
['--environment', '-e', GetoptLong::OPTIONAL_ARGUMENT] |
| 34 |
) |
| 35 |
|
| 36 |
$repos_base = '' |
| 37 |
$out_base = '' |
| 38 |
|
| 39 |
def usage |
| 40 |
puts "See source code for supported options"
|
| 41 |
exit |
| 42 |
end
|
| 43 |
|
| 44 |
begin
|
| 45 |
opts.each do |opt, arg|
|
| 46 |
case opt
|
| 47 |
when '--scm-dir'; $repos_base = arg.dup |
| 48 |
when '--out-dir'; $out_base = arg.dup |
| 49 |
end
|
| 50 |
end
|
| 51 |
rescue
|
| 52 |
exit 1
|
| 53 |
end
|
| 54 |
|
| 55 |
if ($repos_base.empty? or $out_base.empty?) |
| 56 |
usage |
| 57 |
end
|
| 58 |
|
| 59 |
unless File.directory?($repos_base) |
| 60 |
puts "input directory '#{$repos_base}' doesn't exist"
|
| 61 |
exit 1
|
| 62 |
end
|
| 63 |
|
| 64 |
unless File.directory?($out_base) |
| 65 |
puts "output directory '#{$out_base}' doesn't exist"
|
| 66 |
exit 1
|
| 67 |
end
|
| 68 |
|
| 69 |
projects = Project.find(:all) |
| 70 |
|
| 71 |
if projects.nil?
|
| 72 |
puts 'No projects found'
|
| 73 |
exit 1
|
| 74 |
end
|
| 75 |
|
| 76 |
projects.each do |proj|
|
| 77 |
|
| 78 |
next unless proj.is_public |
| 79 |
|
| 80 |
next unless proj.respond_to?(:repository) |
| 81 |
|
| 82 |
repo = proj.repository |
| 83 |
next if repo.nil? or repo.url.empty? |
| 84 |
|
| 85 |
repo_url = repo.url |
| 86 |
repo_url = repo_url.gsub(/^file:\/*/, "/"); |
| 87 |
if repo_url != File.join($repos_base, proj.identifier) |
| 88 |
puts "Project #{proj.identifier} has repo in unsupported location #{repo_url}, skipping"
|
| 89 |
next
|
| 90 |
end
|
| 91 |
|
| 92 |
committers = repo.committers |
| 93 |
|
| 94 |
authormap = ""
|
| 95 |
committers.each do |c, uid|
|
| 96 |
|
| 97 |
# Some of our repos have broken email addresses in them: e.g. one
|
| 98 |
# changeset has a committer name of the form
|
| 99 |
#
|
| 100 |
# NAME <name <NAME <name@example.com">
|
| 101 |
#
|
| 102 |
# I don't know how it got like that... If the committer has more
|
| 103 |
# than one '<' in it, truncate it just before the first one, and
|
| 104 |
# then look up the author name again.
|
| 105 |
#
|
| 106 |
if c =~ /<.*</ then |
| 107 |
# So this is a completely pathological case
|
| 108 |
user = User.find_by_id uid
|
| 109 |
if user.nil? then |
| 110 |
# because the given committer is bogus, we must write something in the map
|
| 111 |
name = c.sub(/\s*<.*$/, "") |
| 112 |
authormap << "#{c}=#{name} <unknown@example.com>\n"
|
| 113 |
else
|
| 114 |
authormap << "#{c}=#{user.name} <#{user.mail}>\n"
|
| 115 |
end
|
| 116 |
elsif not c =~ /[^<]+<.*@.*>/ then |
| 117 |
# This is the "normal" case that needs work, where a user has
|
| 118 |
# their name in the commit but no email address
|
| 119 |
user = User.find_by_id uid
|
| 120 |
authormap << "#{c}=#{user.name} <#{user.mail}>\n" unless user.nil? |
| 121 |
end
|
| 122 |
end
|
| 123 |
|
| 124 |
File.open(File.join($out_base, "authormap_#{proj.identifier}"), "w") do |f| |
| 125 |
f.puts(authormap) |
| 126 |
end
|
| 127 |
|
| 128 |
end
|
| 129 |
|