##// END OF EJS Templates
reposman: change #log arguments....
Jean-Philippe Lang -
r1873:36aeeb99d901
parent child
Show More
@@ -1,288 +1,289
1 1 #!/usr/bin/ruby
2 2
3 3 # == Synopsis
4 4 #
5 5 # reposman: manages your 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 --scm subversion
13 13 # reposman -s /var/git -r redmine.example.net -u http://svn.example.net --scm git
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. If you want to share repositories
28 28 # through Redmine.pm, you need to use the apache owner.
29 29 # --scm=SCM the kind of SCM repository you want to create (and register) in
30 30 # Redmine (default: Subversion). reposman is able to create Git
31 31 # and Subversion repositories. For all other kind (Bazaar,
32 32 # Darcs, Filesystem, Mercurial) you must specify a --command option
33 33 # -u, --url=URL the base url Redmine will use to access your
34 34 # repositories. This option is used to automatically
35 35 # register the repositories in Redmine. The project
36 36 # identifier will be appended to this url. Examples:
37 37 # -u https://example.net/svn
38 38 # -u file:///var/svn/
39 39 # if this option isn't set, reposman won't register
40 40 # the repositories in Redmine
41 41 # -c, --command=COMMAND use this command instead of "svnadmin create" to
42 42 # create a repository. This option can be used to
43 43 # create repositories other than subversion and git kind.
44 44 # This command override the default creation for git and subversion.
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 # == References
54 54 #
55 55 # You can find more information on the redmine's wiki : http://www.redmine.org/wiki/redmine/HowTos
56 56
57 57
58 58 require 'getoptlong'
59 59 require 'rdoc/usage'
60 60 require 'soap/wsdlDriver'
61 61 require 'find'
62 62 require 'etc'
63 63
64 64 Version = "1.1"
65 65 SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
66 66
67 67 opts = GetoptLong.new(
68 68 ['--svn-dir', '-s', GetoptLong::REQUIRED_ARGUMENT],
69 69 ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
70 70 ['--owner', '-o', GetoptLong::REQUIRED_ARGUMENT],
71 71 ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT],
72 72 ['--command' , '-c', GetoptLong::REQUIRED_ARGUMENT],
73 73 ['--scm', GetoptLong::REQUIRED_ARGUMENT],
74 74 ['--test', '-t', GetoptLong::NO_ARGUMENT],
75 75 ['--force', '-f', GetoptLong::NO_ARGUMENT],
76 76 ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
77 77 ['--version', '-V', GetoptLong::NO_ARGUMENT],
78 78 ['--help' , '-h', GetoptLong::NO_ARGUMENT],
79 79 ['--quiet' , '-q', GetoptLong::NO_ARGUMENT]
80 80 )
81 81
82 82 $verbose = 0
83 83 $quiet = false
84 84 $redmine_host = ''
85 85 $repos_base = ''
86 86 $svn_owner = 'root'
87 87 $use_groupid = true
88 88 $svn_url = false
89 89 $test = false
90 90 $force = false
91 91 $scm = 'Subversion'
92 92
93 def log(text,level=0, exit=false)
93 def log(text, options={})
94 level = options[:level] || 0
94 95 puts text unless $quiet or level > $verbose
95 exit 1 if exit
96 exit 1 if options[:exit]
96 97 end
97 98
98 99 def system_or_raise(command)
99 100 raise "\"#{command}\" failed" unless system command
100 101 end
101 102
102 103 module SCM
103 104
104 105 module Subversion
105 106 def self.create(path)
106 107 system_or_raise "svnadmin create #{path}"
107 108 end
108 109 end
109 110
110 111 module Git
111 112 def self.create(path)
112 113 Dir.mkdir path
113 114 Dir.chdir(path) do
114 115 system_or_raise "git --bare init --shared"
115 116 system_or_raise "git-update-server-info"
116 117 end
117 118 end
118 119 end
119 120
120 121 end
121 122
122 123 begin
123 124 opts.each do |opt, arg|
124 125 case opt
125 126 when '--svn-dir'; $repos_base = arg.dup
126 127 when '--redmine-host'; $redmine_host = arg.dup
127 128 when '--owner'; $svn_owner = arg.dup; $use_groupid = false;
128 129 when '--url'; $svn_url = arg.dup
129 when '--scm'; $scm = arg.dup.capitalize; log("Invalid SCM: #{$scm}", 0, true) unless SUPPORTED_SCM.include?($scm)
130 when '--scm'; $scm = arg.dup.capitalize; log("Invalid SCM: #{$scm}", :exit => true) unless SUPPORTED_SCM.include?($scm)
130 131 when '--command'; $command = arg.dup
131 132 when '--verbose'; $verbose += 1
132 133 when '--test'; $test = true
133 134 when '--force'; $force = true
134 135 when '--version'; puts Version; exit
135 136 when '--help'; RDoc::usage
136 137 when '--quiet'; $quiet = true
137 138 end
138 139 end
139 140 rescue
140 141 exit 1
141 142 end
142 143
143 144 if $test
144 145 log("running in test mode")
145 146 end
146 147
147 148 # Make sure command is overridden if SCM vendor is not handled internally (for the moment Subversion and Git)
148 149 if $command.nil?
149 150 begin
150 151 scm_module = SCM.const_get($scm)
151 152 rescue
152 log("Please use --command option to specify how to create a #{$scm} repository.", 0, true)
153 log("Please use --command option to specify how to create a #{$scm} repository.", :exit => true)
153 154 end
154 155 end
155 156
156 157 $svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
157 158
158 159 if ($redmine_host.empty? or $repos_base.empty?)
159 160 RDoc::usage
160 161 end
161 162
162 163 unless File.directory?($repos_base)
163 log("directory '#{$repos_base}' doesn't exists", 0, true)
164 log("directory '#{$repos_base}' doesn't exists", :exit => true)
164 165 end
165 166
166 log("querying Redmine for projects...", 1);
167 log("querying Redmine for projects...", :level => 1);
167 168
168 169 $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
169 170 $redmine_host.gsub!(/\/$/, '')
170 171
171 172 wsdl_url = "#{$redmine_host}/sys/service.wsdl";
172 173
173 174 begin
174 175 soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
175 176 rescue => e
176 log("Unable to connect to #{wsdl_url} : #{e}", 0, true)
177 log("Unable to connect to #{wsdl_url} : #{e}", :exit => true)
177 178 end
178 179
179 180 projects = soap.ProjectsWithRepositoryEnabled
180 181
181 182 if projects.nil?
182 log('no project found, perhaps you forgot to "Enable WS for repository management"', 0, true)
183 log('no project found, perhaps you forgot to "Enable WS for repository management"', :exit => true)
183 184 end
184 185
185 log("retrieved #{projects.size} projects", 1)
186 log("retrieved #{projects.size} projects", :level => 1)
186 187
187 188 def set_owner_and_rights(project, repos_path, &block)
188 189 if RUBY_PLATFORM =~ /mswin/
189 190 yield if block_given?
190 191 else
191 192 uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : 0)
192 193 right = project.is_public ? 0775 : 0770
193 194 yield if block_given?
194 195 Find.find(repos_path) do |f|
195 196 File.chmod right, f
196 197 File.chown uid, gid, f
197 198 end
198 199 end
199 200 end
200 201
201 202 def other_read_right?(file)
202 203 (File.stat(file).mode & 0007).zero? ? false : true
203 204 end
204 205
205 206 def owner_name(file)
206 207 RUBY_PLATFORM =~ /mswin/ ?
207 208 $svn_owner :
208 209 Etc.getpwuid( File.stat(file).uid ).name
209 210 end
210 211
211 212 projects.each do |project|
212 log("treating project #{project.name}", 1)
213 log("treating project #{project.name}", :level => 1)
213 214
214 215 if project.identifier.empty?
215 216 log("\tno identifier for project #{project.name}")
216 217 next
217 218 elsif not project.identifier.match(/^[a-z0-9\-]+$/)
218 219 log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
219 220 next;
220 221 end
221 222
222 223 repos_path = $repos_base + "/" + project.identifier
223 224
224 225 if File.directory?(repos_path)
225 226
226 227 # we must verify that repository has the good owner and the good
227 228 # rights before leaving
228 229 other_read = other_read_right?(repos_path)
229 230 owner = owner_name(repos_path)
230 231 next if project.is_public == other_read and owner == $svn_owner
231 232
232 233 if $test
233 234 log("\tchange mode on #{repos_path}")
234 235 next
235 236 end
236 237
237 238 begin
238 239 set_owner_and_rights(project, repos_path)
239 240 rescue Errno::EPERM => e
240 241 log("\tunable to change mode on #{repos_path} : #{e}\n")
241 242 next
242 243 end
243 244
244 245 log("\tmode change on #{repos_path}");
245 246
246 247 else
247 248 # if repository is already declared in redmine, we don't create
248 249 # unless user use -f with reposman
249 250 if $force == false and not project.repository.nil?
250 log("\trepository for project #{project.identifier} already exists in Redmine", 1)
251 log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1)
251 252 next
252 253 end
253 254
254 255 project.is_public ? File.umask(0002) : File.umask(0007)
255 256
256 257 if $test
257 258 log("\tcreate repository #{repos_path}")
258 259 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
259 260 next
260 261 end
261 262
262 263 begin
263 264 set_owner_and_rights(project, repos_path) do
264 265 if scm_module.nil?
265 266 system_or_raise "#{$command} #{repos_path}"
266 267 else
267 268 scm_module.create(repos_path)
268 269 end
269 270 end
270 271 rescue => e
271 272 log("\tunable to create #{repos_path} : #{e}\n")
272 273 next
273 274 end
274 275
275 276 if $svn_url
276 277 ret = soap.RepositoryCreated project.identifier, $scm, "#{$svn_url}#{project.identifier}"
277 278 if ret > 0
278 279 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
279 280 else
280 281 log("\trepository #{repos_path} not registered in Redmine. Look in your log to find why.");
281 282 end
282 283 end
283 284
284 285 log("\trepository #{repos_path} created");
285 286 end
286 287
287 288 end
288 289
General Comments 0
You need to be logged in to leave comments. Login now