##// END OF EJS Templates
Changes ruby bang path to #!/usr/bin/env ruby (#1876)....
Jean-Philippe Lang -
r2015:ad97165f1b04
parent child
Show More
@@ -1,129 +1,129
1 #!/usr/bin/ruby
1 #!/usr/bin/env ruby
2 2
3 3 # == Synopsis
4 4 #
5 5 # Reads an email from standard input and forward it to a Redmine server
6 6 # through a HTTP request.
7 7 #
8 8 # == Usage
9 9 #
10 10 # rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>
11 11 #
12 12 # == Arguments
13 13 #
14 14 # -u, --url URL of the Redmine server
15 15 # -k, --key Redmine API key
16 16 #
17 17 # General options:
18 18 # -h, --help show this help
19 19 # -v, --verbose show extra information
20 20 # -V, --version show version information and exit
21 21 #
22 22 # Issue attributes control options:
23 23 # -p, --project=PROJECT identifier of the target project
24 24 # -t, --tracker=TRACKER name of the target tracker
25 25 # --category=CATEGORY name of the target category
26 26 # --priority=PRIORITY name of the target priority
27 27 # -o, --allow-override=ATTRS allow email content to override attributes
28 28 # specified by previous options
29 29 # ATTRS is a comma separated list of attributes
30 30 #
31 31 # == Examples
32 32 # No project specified. Emails MUST contain the 'Project' keyword:
33 33 #
34 34 # rdm-mailhandler --url http://redmine.domain.foo --key secret
35 35 #
36 36 # Fixed project and default tracker specified, but emails can override
37 37 # both tracker and priority attributes using keywords:
38 38 #
39 39 # rdm-mailhandler --url https://domain.foo/redmine --key secret \\
40 40 # --project foo \\
41 41 # --tracker bug \\
42 42 # --allow-override tracker,priority
43 43
44 44 require 'net/http'
45 45 require 'net/https'
46 46 require 'uri'
47 47 require 'getoptlong'
48 48 require 'rdoc/usage'
49 49
50 50 module Net
51 51 class HTTPS < HTTP
52 52 def self.post_form(url, params)
53 53 request = Post.new(url.path)
54 54 request.form_data = params
55 55 request.basic_auth url.user, url.password if url.user
56 56 http = new(url.host, url.port)
57 57 http.use_ssl = (url.scheme == 'https')
58 58 http.start {|h| h.request(request) }
59 59 end
60 60 end
61 61 end
62 62
63 63 class RedmineMailHandler
64 64 VERSION = '0.1'
65 65
66 66 attr_accessor :verbose, :issue_attributes, :allow_override, :url, :key
67 67
68 68 def initialize
69 69 self.issue_attributes = {}
70 70
71 71 opts = GetoptLong.new(
72 72 [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
73 73 [ '--version', '-V', GetoptLong::NO_ARGUMENT ],
74 74 [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
75 75 [ '--url', '-u', GetoptLong::REQUIRED_ARGUMENT ],
76 76 [ '--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
77 77 [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
78 78 [ '--tracker', '-t', GetoptLong::REQUIRED_ARGUMENT],
79 79 [ '--category', GetoptLong::REQUIRED_ARGUMENT],
80 80 [ '--priority', GetoptLong::REQUIRED_ARGUMENT],
81 81 [ '--allow-override', '-o', GetoptLong::REQUIRED_ARGUMENT]
82 82 )
83 83
84 84 opts.each do |opt, arg|
85 85 case opt
86 86 when '--url'
87 87 self.url = arg.dup
88 88 when '--key'
89 89 self.key = arg.dup
90 90 when '--help'
91 91 usage
92 92 when '--verbose'
93 93 self.verbose = true
94 94 when '--version'
95 95 puts VERSION; exit
96 96 when '--project', '--tracker', '--category', '--priority'
97 97 self.issue_attributes[opt.gsub(%r{^\-\-}, '')] = arg.dup
98 98 when '--allow-override'
99 99 self.allow_override = arg.dup
100 100 end
101 101 end
102 102
103 103 RDoc.usage if url.nil?
104 104 end
105 105
106 106 def submit(email)
107 107 uri = url.gsub(%r{/*$}, '') + '/mail_handler'
108 108
109 109 data = { 'key' => key, 'email' => email, 'allow_override' => allow_override }
110 110 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
111 111
112 112 debug "Posting to #{uri}..."
113 113 response = Net::HTTPS.post_form(URI.parse(uri), data)
114 114 debug "Response received: #{response.code}"
115 115
116 116 puts "Request was denied by your Redmine server. " +
117 117 "Please, make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key." if response.code == '403'
118 118 response.code == '201' ? 0 : 1
119 119 end
120 120
121 121 private
122 122
123 123 def debug(msg)
124 124 puts msg if verbose
125 125 end
126 126 end
127 127
128 128 handler = RedmineMailHandler.new
129 129 handler.submit(STDIN.read)
@@ -1,289 +1,289
1 #!/usr/bin/ruby
1 #!/usr/bin/env 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 93 def log(text, options={})
94 94 level = options[:level] || 0
95 95 puts text unless $quiet or level > $verbose
96 96 exit 1 if options[:exit]
97 97 end
98 98
99 99 def system_or_raise(command)
100 100 raise "\"#{command}\" failed" unless system command
101 101 end
102 102
103 103 module SCM
104 104
105 105 module Subversion
106 106 def self.create(path)
107 107 system_or_raise "svnadmin create #{path}"
108 108 end
109 109 end
110 110
111 111 module Git
112 112 def self.create(path)
113 113 Dir.mkdir path
114 114 Dir.chdir(path) do
115 115 system_or_raise "git --bare init --shared"
116 116 system_or_raise "git update-server-info"
117 117 end
118 118 end
119 119 end
120 120
121 121 end
122 122
123 123 begin
124 124 opts.each do |opt, arg|
125 125 case opt
126 126 when '--svn-dir'; $repos_base = arg.dup
127 127 when '--redmine-host'; $redmine_host = arg.dup
128 128 when '--owner'; $svn_owner = arg.dup; $use_groupid = false;
129 129 when '--url'; $svn_url = arg.dup
130 130 when '--scm'; $scm = arg.dup.capitalize; log("Invalid SCM: #{$scm}", :exit => true) unless SUPPORTED_SCM.include?($scm)
131 131 when '--command'; $command = arg.dup
132 132 when '--verbose'; $verbose += 1
133 133 when '--test'; $test = true
134 134 when '--force'; $force = true
135 135 when '--version'; puts Version; exit
136 136 when '--help'; RDoc::usage
137 137 when '--quiet'; $quiet = true
138 138 end
139 139 end
140 140 rescue
141 141 exit 1
142 142 end
143 143
144 144 if $test
145 145 log("running in test mode")
146 146 end
147 147
148 148 # Make sure command is overridden if SCM vendor is not handled internally (for the moment Subversion and Git)
149 149 if $command.nil?
150 150 begin
151 151 scm_module = SCM.const_get($scm)
152 152 rescue
153 153 log("Please use --command option to specify how to create a #{$scm} repository.", :exit => true)
154 154 end
155 155 end
156 156
157 157 $svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
158 158
159 159 if ($redmine_host.empty? or $repos_base.empty?)
160 160 RDoc::usage
161 161 end
162 162
163 163 unless File.directory?($repos_base)
164 164 log("directory '#{$repos_base}' doesn't exists", :exit => true)
165 165 end
166 166
167 167 log("querying Redmine for projects...", :level => 1);
168 168
169 169 $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
170 170 $redmine_host.gsub!(/\/$/, '')
171 171
172 172 wsdl_url = "#{$redmine_host}/sys/service.wsdl";
173 173
174 174 begin
175 175 soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
176 176 rescue => e
177 177 log("Unable to connect to #{wsdl_url} : #{e}", :exit => true)
178 178 end
179 179
180 180 projects = soap.ProjectsWithRepositoryEnabled
181 181
182 182 if projects.nil?
183 183 log('no project found, perhaps you forgot to "Enable WS for repository management"', :exit => true)
184 184 end
185 185
186 186 log("retrieved #{projects.size} projects", :level => 1)
187 187
188 188 def set_owner_and_rights(project, repos_path, &block)
189 189 if RUBY_PLATFORM =~ /mswin/
190 190 yield if block_given?
191 191 else
192 192 uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : 0)
193 193 right = project.is_public ? 0775 : 0770
194 194 yield if block_given?
195 195 Find.find(repos_path) do |f|
196 196 File.chmod right, f
197 197 File.chown uid, gid, f
198 198 end
199 199 end
200 200 end
201 201
202 202 def other_read_right?(file)
203 203 (File.stat(file).mode & 0007).zero? ? false : true
204 204 end
205 205
206 206 def owner_name(file)
207 207 RUBY_PLATFORM =~ /mswin/ ?
208 208 $svn_owner :
209 209 Etc.getpwuid( File.stat(file).uid ).name
210 210 end
211 211
212 212 projects.each do |project|
213 213 log("treating project #{project.name}", :level => 1)
214 214
215 215 if project.identifier.empty?
216 216 log("\tno identifier for project #{project.name}")
217 217 next
218 218 elsif not project.identifier.match(/^[a-z0-9\-]+$/)
219 219 log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
220 220 next;
221 221 end
222 222
223 223 repos_path = File.join($repos_base, project.identifier).gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
224 224
225 225 if File.directory?(repos_path)
226 226
227 227 # we must verify that repository has the good owner and the good
228 228 # rights before leaving
229 229 other_read = other_read_right?(repos_path)
230 230 owner = owner_name(repos_path)
231 231 next if project.is_public == other_read and owner == $svn_owner
232 232
233 233 if $test
234 234 log("\tchange mode on #{repos_path}")
235 235 next
236 236 end
237 237
238 238 begin
239 239 set_owner_and_rights(project, repos_path)
240 240 rescue Errno::EPERM => e
241 241 log("\tunable to change mode on #{repos_path} : #{e}\n")
242 242 next
243 243 end
244 244
245 245 log("\tmode change on #{repos_path}");
246 246
247 247 else
248 248 # if repository is already declared in redmine, we don't create
249 249 # unless user use -f with reposman
250 250 if $force == false and not project.repository.nil?
251 251 log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1)
252 252 next
253 253 end
254 254
255 255 project.is_public ? File.umask(0002) : File.umask(0007)
256 256
257 257 if $test
258 258 log("\tcreate repository #{repos_path}")
259 259 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
260 260 next
261 261 end
262 262
263 263 begin
264 264 set_owner_and_rights(project, repos_path) do
265 265 if scm_module.nil?
266 266 system_or_raise "#{$command} #{repos_path}"
267 267 else
268 268 scm_module.create(repos_path)
269 269 end
270 270 end
271 271 rescue => e
272 272 log("\tunable to create #{repos_path} : #{e}\n")
273 273 next
274 274 end
275 275
276 276 if $svn_url
277 277 ret = soap.RepositoryCreated project.identifier, $scm, "#{$svn_url}#{project.identifier}"
278 278 if ret > 0
279 279 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
280 280 else
281 281 log("\trepository #{repos_path} not registered in Redmine. Look in your log to find why.");
282 282 end
283 283 end
284 284
285 285 log("\trepository #{repos_path} created");
286 286 end
287 287
288 288 end
289 289
@@ -1,10 +1,10
1 #!/usr/bin/ruby
1 #!/usr/bin/env ruby
2 2
3 3 require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
4 4
5 5 # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
6 6 # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
7 7 require "dispatcher"
8 8
9 9 ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
10 10 Dispatcher.dispatch No newline at end of file
@@ -1,24 +1,24
1 #!/usr/bin/ruby
1 #!/usr/bin/env ruby
2 2 #
3 3 # You may specify the path to the FastCGI crash log (a log of unhandled
4 4 # exceptions which forced the FastCGI instance to exit, great for debugging)
5 5 # and the number of requests to process before running garbage collection.
6 6 #
7 7 # By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
8 8 # and the GC period is nil (turned off). A reasonable number of requests
9 9 # could range from 10-100 depending on the memory footprint of your app.
10 10 #
11 11 # Example:
12 12 # # Default log path, normal GC behavior.
13 13 # RailsFCGIHandler.process!
14 14 #
15 15 # # Default log path, 50 requests between GC.
16 16 # RailsFCGIHandler.process! nil, 50
17 17 #
18 18 # # Custom log path, normal GC behavior.
19 19 # RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
20 20 #
21 21 require File.dirname(__FILE__) + "/../config/environment"
22 22 require 'fcgi_handler'
23 23
24 24 RailsFCGIHandler.process!
@@ -1,10 +1,10
1 #!/usr/bin/ruby
1 #!/usr/bin/env ruby
2 2
3 3 require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
4 4
5 5 # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
6 6 # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
7 7 require "dispatcher"
8 8
9 9 ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
10 10 Dispatcher.dispatch No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now