##// END OF EJS Templates
bugfix...
Nicolas Chuche -
r1858:90dc93b81c17
parent child
Show More
@@ -1,255 +1,254
1 1 #!/usr/bin/ruby
2 2
3 3 # == Synopsis
4 4 #
5 5 # reposman: manages your svn repositories with Redmine
6 6 #
7 7 # == Usage
8 8 #
9 9 # reposman [OPTIONS...] -s [DIR] -r [HOST]
10 10 #
11 11 # Examples:
12 12 # reposman --svn-dir=/var/svn --redmine-host=redmine.example.net
13 13 # reposman -s /var/svn -r redmine.example.net -u http://svn.example.net
14 14 #
15 15 # == Arguments (mandatory)
16 16 #
17 17 # -s, --svn-dir=DIR use DIR as base directory for svn repositories
18 18 # -r, --redmine-host=HOST assume Redmine is hosted on HOST. Examples:
19 19 # -r redmine.example.net
20 20 # -r http://redmine.example.net
21 21 # -r https://example.net/redmine
22 22 #
23 23 # == Options
24 24 #
25 25 # -o, --owner=OWNER owner of the repository. using the rails login
26 26 # allow user to browse the repository within
27 27 # Redmine even for private project
28 28 # -u, --url=URL the base url Redmine will use to access your
29 29 # repositories. This option is used to automatically
30 30 # register the repositories in Redmine. The project
31 31 # identifier will be appended to this url. Examples:
32 32 # -u https://example.net/svn
33 33 # -u file:///var/svn/
34 34 # if this option isn't set, reposman won't register
35 35 # the repositories in Redmine
36 36 # -c, --command=COMMAND use this command instead of "svnadmin create" to
37 37 # create a repository. This option can be used to
38 38 # create non-subversion repositories
39 39 # --scm SCM vendor used to register the repository in
40 40 # Redmine (default: Subversion). Can be one of the
41 41 # other supported SCM: Bazaar, Darcs, Filesystem,
42 42 # Git, Mercurial (case sensitive).
43 43 # This option should be used when both options --url
44 44 # and --command are used.
45 45 # -f, --force force repository creation even if the project
46 46 # repository is already declared in Redmine
47 47 # -t, --test only show what should be done
48 48 # -h, --help show help and exit
49 49 # -v, --verbose verbose
50 50 # -V, --version print version and exit
51 51 # -q, --quiet no log
52 52
53 53 require 'getoptlong'
54 54 require 'rdoc/usage'
55 55 require 'soap/wsdlDriver'
56 56 require 'find'
57 57 require 'etc'
58 58
59 59 Version = "1.1"
60 60 SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
61 61
62 62 opts = GetoptLong.new(
63 63 ['--svn-dir', '-s', GetoptLong::REQUIRED_ARGUMENT],
64 64 ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
65 65 ['--owner', '-o', GetoptLong::REQUIRED_ARGUMENT],
66 66 ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT],
67 67 ['--command' , '-c', GetoptLong::REQUIRED_ARGUMENT],
68 68 ['--scm', GetoptLong::REQUIRED_ARGUMENT],
69 69 ['--test', '-t', GetoptLong::NO_ARGUMENT],
70 70 ['--force', '-f', GetoptLong::NO_ARGUMENT],
71 71 ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
72 72 ['--version', '-V', GetoptLong::NO_ARGUMENT],
73 73 ['--help' , '-h', GetoptLong::NO_ARGUMENT],
74 74 ['--quiet' , '-q', GetoptLong::NO_ARGUMENT]
75 75 )
76 76
77 77 $verbose = 0
78 78 $quiet = false
79 79 $redmine_host = ''
80 80 $repos_base = ''
81 81 $svn_owner = 'root'
82 82 $use_groupid = true
83 83 $svn_url = false
84 84 $test = false
85 85 $command = "svnadmin create"
86 86 $force = false
87 87 $scm = 'Subversion'
88 88
89 89 def log(text,level=0, exit=false)
90 return if $quiet or level > $verbose
91 puts text
90 puts text unless $quiet or level > $verbose
92 91 exit 1 if exit
93 92 end
94 93
95 94 begin
96 95 opts.each do |opt, arg|
97 96 case opt
98 97 when '--svn-dir'; $repos_base = arg.dup
99 98 when '--redmine-host'; $redmine_host = arg.dup
100 99 when '--owner'; $svn_owner = arg.dup; $use_groupid = false;
101 100 when '--url'; $svn_url = arg.dup
102 101 when '--scm'; $scm = arg.dup; log("Invalid SCM: #{$scm}", 0, true) unless SUPPORTED_SCM.include?($scm)
103 102 when '--command'; $command = arg.dup
104 103 when '--verbose'; $verbose += 1
105 104 when '--test'; $test = true
106 105 when '--force'; $force = true
107 106 when '--version'; puts Version; exit
108 107 when '--help'; RDoc::usage
109 108 when '--quiet'; $quiet = true
110 109 end
111 110 end
112 111 rescue
113 112 exit 1
114 113 end
115 114
116 115 if $test
117 116 log("running in test mode")
118 117 end
119 118
120 119 # Make sure command is overridden if SCM vendor is not Subversion
121 120 if $scm != 'Subversion' && $command == 'svnadmin create'
122 121 log("Please use --command option to specify how to create a #{$scm} repository.", 0, true)
123 122 end
124 123
125 124
126 125 $svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
127 126
128 127 if ($redmine_host.empty? or $repos_base.empty?)
129 128 RDoc::usage
130 129 end
131 130
132 131 unless File.directory?($repos_base)
133 132 log("directory '#{$repos_base}' doesn't exists", 0, true)
134 133 end
135 134
136 135 log("querying Redmine for projects...", 1);
137 136
138 137 $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
139 138 $redmine_host.gsub!(/\/$/, '')
140 139
141 140 wsdl_url = "#{$redmine_host}/sys/service.wsdl";
142 141
143 142 begin
144 143 soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
145 144 rescue => e
146 145 log("Unable to connect to #{wsdl_url} : #{e}", 0, true)
147 146 end
148 147
149 148 projects = soap.ProjectsWithRepositoryEnabled
150 149
151 150 if projects.nil?
152 151 log('no project found, perhaps you forgot to "Enable WS for repository management"', 0, true)
153 152 end
154 153
155 154 log("retrieved #{projects.size} projects", 1)
156 155
157 156 def set_owner_and_rights(project, repos_path, &block)
158 157 if RUBY_PLATFORM =~ /mswin/
159 158 yield if block_given?
160 159 else
161 160 uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : 0)
162 161 right = project.is_public ? 0775 : 0770
163 162 yield if block_given?
164 163 Find.find(repos_path) do |f|
165 164 File.chmod right, f
166 165 File.chown uid, gid, f
167 166 end
168 167 end
169 168 end
170 169
171 170 def other_read_right?(file)
172 171 (File.stat(file).mode & 0007).zero? ? false : true
173 172 end
174 173
175 174 def owner_name(file)
176 175 RUBY_PLATFORM =~ /mswin/ ?
177 176 $svn_owner :
178 177 Etc.getpwuid( File.stat(file).uid ).name
179 178 end
180 179
181 180 projects.each do |project|
182 181 log("treating project #{project.name}", 1)
183 182
184 183 if project.identifier.empty?
185 184 log("\tno identifier for project #{project.name}")
186 185 next
187 186 elsif not project.identifier.match(/^[a-z0-9\-]+$/)
188 187 log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
189 188 next;
190 189 end
191 190
192 191 repos_path = $repos_base + "/" + project.identifier
193 192
194 193 if File.directory?(repos_path)
195 194
196 195 # we must verify that repository has the good owner and the good
197 196 # rights before leaving
198 197 other_read = other_read_right?(repos_path)
199 198 owner = owner_name(repos_path)
200 199 next if project.is_public == other_read and owner == $svn_owner
201 200
202 201 if $test
203 202 log("\tchange mode on #{repos_path}")
204 203 next
205 204 end
206 205
207 206 begin
208 207 set_owner_and_rights(project, repos_path)
209 208 rescue Errno::EPERM => e
210 209 log("\tunable to change mode on #{repos_path} : #{e}\n")
211 210 next
212 211 end
213 212
214 213 log("\tmode change on #{repos_path}");
215 214
216 215 else
217 216 # if repository is already declared in redmine, we don't create
218 217 # unless user use -f with reposman
219 218 if $force == false and not project.repository.nil?
220 219 log("\trepository for project #{project.identifier} already exists in Redmine", 1)
221 220 next
222 221 end
223 222
224 223 project.is_public ? File.umask(0002) : File.umask(0007)
225 224
226 225 if $test
227 226 log("\tcreate repository #{repos_path}")
228 227 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
229 228 next
230 229 end
231 230
232 231 begin
233 232 set_owner_and_rights(project, repos_path) do
234 233 command = "#{$command} #{repos_path}"
235 234 raise "#{command} failed" unless system( command )
236 235 end
237 236 rescue => e
238 237 log("\tunable to create #{repos_path} : #{e}\n")
239 238 next
240 239 end
241 240
242 241 if $svn_url
243 242 ret = soap.RepositoryCreated project.identifier, $scm, "#{$svn_url}#{project.identifier}"
244 243 if ret > 0
245 244 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
246 245 else
247 246 log("\trepository #{repos_path} not registered in Redmine. Look in your log to find why.");
248 247 end
249 248 end
250 249
251 250 log("\trepository #{repos_path} created");
252 251 end
253 252
254 253 end
255 254
General Comments 0
You need to be logged in to leave comments. Login now