Project

General

Profile

« Previous | Next » 

Revision 860

SVN integration: reposman.rb can now register created repositories in Redmine, so that the administrator doesn't have to enter the repository url in Redmine once it's created.
To do so, use the --url option when running reposman (see reposman help).

View differences:

trunk/app/apis/sys_api.rb
20 20
             :expects => [],
21 21
             :returns => [[Project]]
22 22
  api_method :repository_created,
23
             :expects => [:int, :string],
23
             :expects => [:string, :string],
24 24
             :returns => [:int]
25 25
end
trunk/app/controllers/sys_controller.rb
22 22
  
23 23
  before_invocation :check_enabled
24 24
  
25
  # Returns the projects list, with their repositories
25 26
  def projects
26 27
    Project.find(:all, :include => :repository)
27 28
  end
28 29

  
29
  def repository_created(project_id, url)
30
    project = Project.find_by_id(project_id)
30
  # Registers a repository for the given project identifier
31
  # (Subversion specific)
32
  def repository_created(identifier, url)
33
    project = Project.find_by_identifier(identifier)
34
    # Do not create the repository if the project has already one
31 35
    return 0 unless project && project.repository.nil?
32
    logger.debug "Repository for #{project.name} created"
33
    repository = Repository.new(:project => project, :url => url)
34
    repository.root_url = url
36
    logger.debug "Repository for #{project.name} was created"
37
    repository = Repository.factory('Subversion', :project => project, :url => url)
35 38
    repository.save
36
    repository.id
39
    repository.id || 0
37 40
  end
38 41

  
39 42
protected
trunk/extra/svn/reposman.rb
2 2

  
3 3
# == Synopsis
4 4
#
5
# reposman: manages your svn repositories with redMine
5
# reposman: manages your svn repositories with Redmine
6 6
#
7 7
# == Usage
8 8
#
......
16 16
#    use DIR as base directory for svn repositories
17 17
#
18 18
# -r, --redmine-host=HOST
19
#    assume redMine is hosted on HOST.
19
#    assume Redmine is hosted on HOST.
20 20
#    you can use :
21 21
#    * -r redmine.mydomain.foo        (will add http://)
22 22
#    * -r http://redmine.mydomain.foo
23 23
#    * -r https://mydomain.foo/redmine
24 24
#
25 25
# == Options
26
# 
26
#
27
# -o, --owner=OWNER
28
#    owner of the repository. using the rails login allow user to browse
29
#    the repository in Redmine even for private project
30
#
31
# -u, --url=URL
32
#    the base url Redmine will use to access your repositories. This
33
#    will be used to register the repository in Redmine so that user
34
#    doesn't need to do anything. reposman will add the identifier to this url :
35
#
36
#    -u https://my.svn.server/my/reposity/root # if the repository can be access by http
37
#    -u file:///var/svn/                       # if the repository is local
38
#    if this option isn't set, reposman won't register the repository
39
#
40
#
27 41
# -h, --help:
28 42
#    show help and exit
29 43
#
......
48 62
opts = GetoptLong.new(
49 63
                      ['--svn-dir',      '-s', GetoptLong::REQUIRED_ARGUMENT],
50 64
                      ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
65
                      ['--owner',        '-o', GetoptLong::REQUIRED_ARGUMENT],
66
                      ['--url',          '-u', GetoptLong::REQUIRED_ARGUMENT],
51 67
                      ['--verbose',      '-v', GetoptLong::NO_ARGUMENT],
52 68
                      ['--version',      '-V', GetoptLong::NO_ARGUMENT],
53 69
                      ['--help'   ,      '-h', GetoptLong::NO_ARGUMENT],
......
58 74
$quiet        = false
59 75
$redmine_host = ''
60 76
$repos_base   = ''
77
$svn_owner    = 'root'
78
$svn_url      = false
61 79

  
62 80
def log(text,level=0, exit=false)
63 81
  return if $quiet or level > $verbose
......
68 86
begin
69 87
  opts.each do |opt, arg|
70 88
    case opt
71
    when '--svn-dir';        $repos_base = arg.dup
89
    when '--svn-dir';        $repos_base   = arg.dup
72 90
    when '--redmine-host';   $redmine_host = arg.dup
91
    when '--owner';          $svn_owner    = arg.dup
92
    when '--url';            $svn_url      = arg.dup
73 93
    when '--verbose';        $verbose += 1
74 94
    when '--version';        puts Version; exit
75 95
    when '--help';           RDoc::usage
......
80 100
  exit 1
81 101
end
82 102

  
103
$svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
104

  
83 105
if ($redmine_host.empty? or $repos_base.empty?)
84 106
  RDoc::usage
85 107
end
......
88 110
  log("directory '#{$repos_base}' doesn't exists", 0, true)
89 111
end
90 112

  
91
log("querying redMine for projects...", 1);
113
log("querying Redmine for projects...", 1);
92 114

  
93 115
$redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
94 116
$redmine_host.gsub!(/\/$/, '')
......
109 131

  
110 132
log("retrieved #{projects.size} projects", 1)
111 133

  
112
projects.each do |p|
113
  log("treating project #{p.name}", 1)
134
def set_owner_and_rights(project, repos_path, &block)
135
  if RUBY_PLATFORM =~ /mswin/
136
    yield if block_given?
137
  else
138
    uid, gid = Etc.getpwnam($svn_owner).uid, Etc.getgrnam(project.identifier).gid
139
    right = project.is_public ? 0575 : 0570
140
    yield if block_given?
141
    Find.find(repos_path) do |f|
142
      File.chmod right, f
143
      File.chown uid, gid, f
144
    end
145
  end
146
end
114 147

  
115
  if p.identifier.empty?
116
    log("\tno identifier for project #{p.name}")
148
def other_read_right?(file)
149
  (File.stat(file).mode & 0007).zero? ? false : true
150
end
151

  
152
def owner_name(file)
153
  RUBY_PLATFORM =~ /mswin/ ?
154
    $svn_owner :
155
    Etc.getpwuid( File.stat(file).uid ).name  
156
end
157

  
158
projects.each do |project|
159
  log("treating project #{project.name}", 1)
160

  
161
  if project.identifier.empty?
162
    log("\tno identifier for project #{project.name}")
117 163
    next
118
  elsif not p.identifier.match(/^[a-z0-9\-]+$/)
119
    log("\tinvalid identifier for project #{p.name} : #{p.identifier}");
164
  elsif not project.identifier.match(/^[a-z0-9\-]+$/)
165
    log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
120 166
    next;
121 167
  end
122 168

  
123
  repos_path = $repos_base + "/" + p.identifier
169
  repos_path = $repos_base + "/" + project.identifier
124 170

  
125 171
  if File.directory?(repos_path)
126 172

  
127
    other_read = (File.stat(repos_path).mode & 0007).zero? ? false : true
128
    next if p.is_public == other_read
173
    # we must verify that repository has the good owner and the good
174
    # rights before leaving
175
    other_read = other_read_right?(repos_path)
176
    owner      = owner_name(repos_path)
177
    next if project.is_public == other_read and owner == $svn_owner
129 178

  
130
    right = p.is_public ? 0775 : 0770
131

  
132 179
    begin
133
      Find.find(repos_path) { |f| File.chmod right, f }
180
      set_owner_and_rights(project, repos_path)
134 181
    rescue Errno::EPERM => e
135 182
      log("\tunable to change mode on #{repos_path} : #{e}\n")
136 183
      next
......
139 186
    log("\tmode change on #{repos_path}");
140 187

  
141 188
  else
142
    p.is_public ? File.umask(0002) : File.umask(0007)
189
    project.is_public ? File.umask(0202) : File.umask(0207)
143 190

  
144 191
    begin
145
      uid, gid = Etc.getpwnam("root").uid, Etc.getgrnam(p.identifier).gid
146
      raise "svnadmin create #{repos_path} failed" unless system("svnadmin", "create", repos_path)
147
      Find.find(repos_path) { |f| File.chown uid, gid, f }
192
      set_owner_and_rights(project, repos_path) do
193
        raise "svnadmin create #{repos_path} failed" unless system("svnadmin", "create", repos_path)
194
      end
148 195
    rescue => e
149 196
      log("\tunable to create #{repos_path} : #{e}\n")
150 197
      next
151 198
    end
152 199

  
200
    if $svn_url
201
      ret = soap.RepositoryCreated project.identifier, "#{$svn_url}#{project.identifier}"
202
      if ret > 0
203
        log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
204
      else
205
        log("\trepository #{repos_path} not registered in Redmine. Look in your log to find why.");
206
      end
207
    end
208

  
153 209
    log("\trepository #{repos_path} created");
154 210
  end
155 211

  

Also available in: Unified diff