buildr 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +566 -268
- data/DISCLAIMER +7 -1
- data/KEYS +151 -0
- data/NOTICE +23 -8
- data/README +122 -22
- data/Rakefile +49 -229
- data/{lib → addon}/buildr/antlr.rb +23 -10
- data/addon/buildr/cobertura.rb +232 -0
- data/{lib → addon}/buildr/hibernate.rb +20 -4
- data/{lib → addon}/buildr/javacc.rb +27 -12
- data/addon/buildr/jdepend.rb +60 -0
- data/{lib → addon}/buildr/jetty.rb +34 -18
- data/addon/buildr/nailgun.rb +892 -0
- data/{lib → addon}/buildr/openjpa.rb +23 -6
- data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
- data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
- data/{lib → addon}/buildr/xmlbeans.rb +39 -14
- data/bin/buildr +21 -7
- data/buildr.gemspec +50 -0
- data/doc/css/default.css +225 -0
- data/doc/css/print.css +95 -0
- data/doc/css/syntax.css +43 -0
- data/doc/images/apache-incubator-logo.png +0 -0
- data/doc/images/buildr-hires.png +0 -0
- data/doc/images/buildr.png +0 -0
- data/doc/images/note.png +0 -0
- data/doc/images/tip.png +0 -0
- data/doc/images/zbuildr.tif +0 -0
- data/doc/pages/artifacts.textile +317 -0
- data/doc/pages/building.textile +501 -0
- data/doc/pages/contributing.textile +178 -0
- data/doc/pages/download.textile +25 -0
- data/doc/pages/extending.textile +229 -0
- data/doc/pages/getting_started.textile +337 -0
- data/doc/pages/index.textile +63 -0
- data/doc/pages/mailing_lists.textile +17 -0
- data/doc/pages/more_stuff.textile +367 -0
- data/doc/pages/packaging.textile +592 -0
- data/doc/pages/projects.textile +449 -0
- data/doc/pages/recipes.textile +127 -0
- data/doc/pages/settings_profiles.textile +339 -0
- data/doc/pages/testing.textile +475 -0
- data/doc/pages/troubleshooting.textile +121 -0
- data/doc/pages/whats_new.textile +389 -0
- data/doc/print.haml +52 -0
- data/doc/print.toc.yaml +28 -0
- data/doc/scripts/buildr-git.rb +411 -0
- data/doc/scripts/install-jruby.sh +44 -0
- data/doc/scripts/install-linux.sh +64 -0
- data/doc/scripts/install-osx.sh +52 -0
- data/doc/site.haml +55 -0
- data/doc/site.toc.yaml +44 -0
- data/lib/buildr.rb +28 -45
- data/lib/buildr/core.rb +27 -0
- data/lib/buildr/core/application.rb +373 -0
- data/lib/buildr/core/application_cli.rb +134 -0
- data/lib/{core → buildr/core}/build.rb +91 -77
- data/lib/{core → buildr/core}/checks.rb +116 -95
- data/lib/buildr/core/common.rb +155 -0
- data/lib/buildr/core/compile.rb +594 -0
- data/lib/buildr/core/environment.rb +120 -0
- data/lib/buildr/core/filter.rb +258 -0
- data/lib/{core → buildr/core}/generate.rb +22 -5
- data/lib/buildr/core/help.rb +118 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/{core → buildr/core}/project.rb +468 -213
- data/lib/buildr/core/test.rb +690 -0
- data/lib/{core → buildr/core}/transports.rb +107 -127
- data/lib/buildr/core/util.rb +235 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/{java → buildr/ide}/eclipse.rb +86 -60
- data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
- data/lib/buildr/ide/idea.rb +194 -0
- data/lib/buildr/ide/idea7x.ipr.template +290 -0
- data/lib/buildr/ide/idea7x.rb +210 -0
- data/lib/buildr/java.rb +26 -0
- data/lib/buildr/java/ant.rb +71 -0
- data/lib/buildr/java/bdd_frameworks.rb +267 -0
- data/lib/buildr/java/commands.rb +210 -0
- data/lib/buildr/java/compilers.rb +432 -0
- data/lib/buildr/java/deprecated.rb +141 -0
- data/lib/buildr/java/groovyc.rb +137 -0
- data/lib/buildr/java/jruby.rb +99 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
- data/lib/buildr/java/packaging.rb +706 -0
- data/lib/{java → buildr/java}/pom.rb +20 -4
- data/lib/buildr/java/rjb.rb +142 -0
- data/lib/buildr/java/test_frameworks.rb +290 -0
- data/lib/buildr/java/version_requirement.rb +172 -0
- data/lib/buildr/packaging.rb +21 -0
- data/lib/{java → buildr/packaging}/artifact.rb +170 -179
- data/lib/buildr/packaging/artifact_namespace.rb +957 -0
- data/lib/buildr/packaging/artifact_search.rb +140 -0
- data/lib/buildr/packaging/gems.rb +102 -0
- data/lib/buildr/packaging/package.rb +233 -0
- data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
- data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
- data/rakelib/apache.rake +126 -0
- data/rakelib/changelog.rake +56 -0
- data/rakelib/doc.rake +103 -0
- data/rakelib/package.rake +44 -0
- data/rakelib/release.rake +53 -0
- data/rakelib/rspec.rake +81 -0
- data/rakelib/rubyforge.rake +45 -0
- data/rakelib/scm.rake +49 -0
- data/rakelib/setup.rake +59 -0
- data/rakelib/stage.rake +45 -0
- data/spec/application_spec.rb +316 -0
- data/spec/archive_spec.rb +494 -0
- data/spec/artifact_namespace_spec.rb +635 -0
- data/spec/artifact_spec.rb +738 -0
- data/spec/build_spec.rb +193 -0
- data/spec/checks_spec.rb +537 -0
- data/spec/common_spec.rb +579 -0
- data/spec/compile_spec.rb +561 -0
- data/spec/groovy_compilers_spec.rb +239 -0
- data/spec/java_bdd_frameworks_spec.rb +238 -0
- data/spec/java_compilers_spec.rb +446 -0
- data/spec/java_packaging_spec.rb +1042 -0
- data/spec/java_test_frameworks_spec.rb +414 -0
- data/spec/packaging_helper.rb +63 -0
- data/spec/packaging_spec.rb +589 -0
- data/spec/project_spec.rb +739 -0
- data/spec/sandbox.rb +116 -0
- data/spec/scala_compilers_spec.rb +239 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helpers.rb +283 -0
- data/spec/test_spec.rb +871 -0
- data/spec/transport_spec.rb +300 -0
- data/spec/version_requirement_spec.rb +115 -0
- metadata +188 -77
- data/lib/buildr/cobertura.rb +0 -89
- data/lib/buildr/jdepend.rb +0 -40
- data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
- data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
- data/lib/buildr/jetty/JettyWrapper.class +0 -0
- data/lib/buildr/scala.rb +0 -368
- data/lib/core/application.rb +0 -188
- data/lib/core/common.rb +0 -562
- data/lib/core/help.rb +0 -72
- data/lib/core/rake_ext.rb +0 -81
- data/lib/java/ant.rb +0 -71
- data/lib/java/compile.rb +0 -589
- data/lib/java/idea.rb +0 -159
- data/lib/java/java.rb +0 -432
- data/lib/java/packaging.rb +0 -581
- data/lib/java/test.rb +0 -795
- data/lib/tasks/concat.rb +0 -35
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with this
|
|
3
|
+
# work for additional information regarding copyright ownership. The ASF
|
|
4
|
+
# licenses this file to you under the Apache License, Version 2.0 (the
|
|
5
|
+
# "License"); you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
13
|
+
# License for the specific language governing permissions and limitations under
|
|
14
|
+
# the License.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
require 'cgi'
|
|
18
|
+
require 'net/http'
|
|
19
|
+
require 'net/https'
|
|
20
|
+
require 'net/ssh'
|
|
21
|
+
require 'net/sftp'
|
|
22
|
+
require 'uri'
|
|
23
|
+
require 'uri/sftp'
|
|
24
|
+
require 'digest/md5'
|
|
25
|
+
require 'digest/sha1'
|
|
26
|
+
require 'tempfile'
|
|
27
|
+
require 'buildr/core/progressbar'
|
|
13
28
|
|
|
14
29
|
|
|
15
30
|
# Monkeypatching: SFTP never defines the mkdir method on its session or the underlying
|
|
@@ -49,11 +64,11 @@ module URI
|
|
|
49
64
|
# the second form yields to the block with each chunk of content (usually more than one).
|
|
50
65
|
#
|
|
51
66
|
# For example:
|
|
52
|
-
# File.open
|
|
53
|
-
# URI.read(
|
|
67
|
+
# File.open 'image.jpg', 'w' do |file|
|
|
68
|
+
# URI.read('http://example.com/image.jpg') { |chunk| file.write chunk }
|
|
54
69
|
# end
|
|
55
70
|
# Shorter version:
|
|
56
|
-
# File.open(
|
|
71
|
+
# File.open('image.jpg', 'w') { |file| file.write URI.read('http://example.com/image.jpg') }
|
|
57
72
|
#
|
|
58
73
|
# Supported options:
|
|
59
74
|
# * :modified -- Only download if file modified since this timestamp. Returns nil if not modified.
|
|
@@ -86,11 +101,11 @@ module URI
|
|
|
86
101
|
# block. Each yield should return up to the specified number of bytes, the last yield returns nil.
|
|
87
102
|
#
|
|
88
103
|
# For example:
|
|
89
|
-
# File.open
|
|
90
|
-
# write(
|
|
104
|
+
# File.open 'killer-app.jar', 'rb' do |file|
|
|
105
|
+
# write('sftp://localhost/jars/killer-app.jar') { |chunk| file.read(chunk) }
|
|
91
106
|
# end
|
|
92
107
|
# Or:
|
|
93
|
-
# write
|
|
108
|
+
# write 'sftp://localhost/jars/killer-app.jar', File.read('killer-app.jar')
|
|
94
109
|
#
|
|
95
110
|
# Supported options:
|
|
96
111
|
# * :progress -- Show the progress bar while reading.
|
|
@@ -126,7 +141,7 @@ module URI
|
|
|
126
141
|
#
|
|
127
142
|
# For options, see URI::read.
|
|
128
143
|
def read(options = nil, &block)
|
|
129
|
-
fail
|
|
144
|
+
fail 'This protocol doesn\'t support reading (yet, how about helping by implementing it?)'
|
|
130
145
|
end
|
|
131
146
|
|
|
132
147
|
# :call-seq:
|
|
@@ -158,7 +173,7 @@ module URI
|
|
|
158
173
|
read({:progress=>verbose}.merge(options || {}).merge(:modified=>target.mtime)) { |chunk| target.write chunk }
|
|
159
174
|
target.flush
|
|
160
175
|
else
|
|
161
|
-
raise ArgumentError,
|
|
176
|
+
raise ArgumentError, 'Expecting a target that is either a file name (string, task) or object that responds to write (file, pipe).' unless target.respond_to?(:write)
|
|
162
177
|
read({:progress=>verbose}.merge(options || {})) { |chunk| target.write chunk }
|
|
163
178
|
target.flush
|
|
164
179
|
end
|
|
@@ -177,7 +192,7 @@ module URI
|
|
|
177
192
|
options = args.pop if Hash === args.last
|
|
178
193
|
options ||= {}
|
|
179
194
|
if String === args.first
|
|
180
|
-
ios = StringIO.new(args.first,
|
|
195
|
+
ios = StringIO.new(args.first, 'r')
|
|
181
196
|
write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
|
|
182
197
|
elsif args.first.respond_to?(:read)
|
|
183
198
|
size = args.first.size rescue nil
|
|
@@ -185,7 +200,7 @@ module URI
|
|
|
185
200
|
elsif args.empty? && block
|
|
186
201
|
write_internal options, &block
|
|
187
202
|
else
|
|
188
|
-
raise ArgumentError,
|
|
203
|
+
raise ArgumentError, 'Either give me the content, or pass me a block, otherwise what would I upload?'
|
|
189
204
|
end
|
|
190
205
|
end
|
|
191
206
|
|
|
@@ -203,14 +218,14 @@ module URI
|
|
|
203
218
|
source = source.name if Rake::Task === source
|
|
204
219
|
options ||= {}
|
|
205
220
|
if String === source
|
|
206
|
-
raise NotFoundError,
|
|
221
|
+
raise NotFoundError, 'No source file/directory to upload.' unless File.exist?(source)
|
|
207
222
|
if File.directory?(source)
|
|
208
223
|
Dir.glob("#{source}/**/*").reject { |file| File.directory?(file) }.each do |file|
|
|
209
|
-
uri = self + (File.join(self.path, file.sub(source,
|
|
224
|
+
uri = self + (File.join(self.path, file.sub(source, '')))
|
|
210
225
|
uri.upload file, {:digests=>[]}.merge(options)
|
|
211
226
|
end
|
|
212
227
|
else
|
|
213
|
-
File.open(source,
|
|
228
|
+
File.open(source, 'rb') { |input| upload input, options }
|
|
214
229
|
end
|
|
215
230
|
elsif source.respond_to?(:read)
|
|
216
231
|
digests = (options[:digests] || [:md5, :sha1]).
|
|
@@ -226,14 +241,14 @@ module URI
|
|
|
226
241
|
(options).merge(:progress=>false)
|
|
227
242
|
end
|
|
228
243
|
else
|
|
229
|
-
raise ArgumentError,
|
|
244
|
+
raise ArgumentError, 'Expecting source to be a file name (string, task) or any object that responds to read (file, pipe).'
|
|
230
245
|
end
|
|
231
246
|
end
|
|
232
247
|
|
|
233
248
|
protected
|
|
234
249
|
|
|
235
250
|
# :call-seq:
|
|
236
|
-
# with_progress_bar(
|
|
251
|
+
# with_progress_bar(show, file_name, size) { |progress| ... }
|
|
237
252
|
#
|
|
238
253
|
# Displays a progress bar while executing the block. The first argument must be true for the
|
|
239
254
|
# progress bar to show (TTY output also required), as a convenient for selectively using the
|
|
@@ -243,45 +258,10 @@ module URI
|
|
|
243
258
|
#
|
|
244
259
|
# The block is yielded with a progress object that implements a single method.
|
|
245
260
|
# Call << for each block of bytes down/uploaded.
|
|
246
|
-
def with_progress_bar(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
class << progress_bar
|
|
251
|
-
def total()
|
|
252
|
-
convert_bytes(@total)
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
# Squeeze the filename into 30 characters.
|
|
256
|
-
if file_name.size > 30
|
|
257
|
-
base, ext = file_name.split(".")
|
|
258
|
-
truncated = "#{base[0..26-ext.to_s.size]}...#{ext}"
|
|
259
|
-
else
|
|
260
|
-
truncated = file_name
|
|
261
|
-
end
|
|
262
|
-
progress_bar.format = "#{truncated}: %3d%% %s %s/%s %s"
|
|
263
|
-
progress_bar.format = "%3d%% %s %s/%s %s"
|
|
264
|
-
progress_bar.format_arguments = [:percentage, :bar, :bytes, :total, :stat]
|
|
265
|
-
progress_bar.bar_mark = "."
|
|
266
|
-
|
|
267
|
-
begin
|
|
268
|
-
class << progress_bar
|
|
269
|
-
def <<(bytes)
|
|
270
|
-
inc bytes.respond_to?(:size) ? bytes.size : bytes
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
yield progress_bar
|
|
274
|
-
ensure
|
|
275
|
-
progress_bar.finish
|
|
276
|
-
end
|
|
277
|
-
else
|
|
278
|
-
progress_bar = Object.new
|
|
279
|
-
class << progress_bar
|
|
280
|
-
def <<(bytes)
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
yield progress_bar
|
|
284
|
-
end
|
|
261
|
+
def with_progress_bar(show, file_name, size, &block) #:nodoc:
|
|
262
|
+
options = { :total=>size, :title=>file_name }
|
|
263
|
+
options[:hidden] = true unless show
|
|
264
|
+
ProgressBar.start options, &block
|
|
285
265
|
end
|
|
286
266
|
|
|
287
267
|
# :call-seq:
|
|
@@ -292,13 +272,13 @@ module URI
|
|
|
292
272
|
def proxy_uri()
|
|
293
273
|
proxy = ENV["#{scheme.upcase}_PROXY"]
|
|
294
274
|
proxy = URI.parse(proxy) if String === proxy
|
|
295
|
-
excludes =
|
|
275
|
+
excludes = ENV['NO_PROXY'].to_s.split(/\s*,\s*/).compact
|
|
296
276
|
excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
|
|
297
277
|
return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
|
|
298
278
|
end
|
|
299
279
|
|
|
300
280
|
def write_internal(options, &block) #:nodoc:
|
|
301
|
-
fail
|
|
281
|
+
fail 'This protocol doesn\'t support writing (yet, how about helping by implementing it?)'
|
|
302
282
|
end
|
|
303
283
|
|
|
304
284
|
end
|
|
@@ -309,54 +289,54 @@ module URI
|
|
|
309
289
|
# See URI::Generic#read
|
|
310
290
|
def read(options = nil, &block)
|
|
311
291
|
options ||= {}
|
|
292
|
+
headers = { 'If-Modified-Since' => CGI.rfc1123_date(options[:modified].utc) } if options[:modified]
|
|
312
293
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
http.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
294
|
+
if proxy = proxy_uri
|
|
295
|
+
proxy = URI.parse(proxy) if String === proxy
|
|
296
|
+
http = Net::HTTP.new(host, port, proxy.host, proxy.port, proxy.user, proxy.password)
|
|
297
|
+
else
|
|
298
|
+
http = Net::HTTP.new(host, port)
|
|
299
|
+
end
|
|
300
|
+
http.use_ssl = true if self.instance_of? URI::HTTPS
|
|
301
|
+
|
|
302
|
+
puts "Requesting #{self}" if Buildr.application.options.trace
|
|
303
|
+
request = Net::HTTP::Get.new(path.empty? ? '/' : path, headers)
|
|
304
|
+
request.basic_auth self.user, self.password if self.user
|
|
305
|
+
http.request request do |response|
|
|
306
|
+
case response
|
|
307
|
+
#case response = http.request(request)
|
|
308
|
+
when Net::HTTPNotModified
|
|
309
|
+
# No modification, nothing to do.
|
|
310
|
+
puts 'Not modified since last download' if Buildr.application.options.trace
|
|
311
|
+
return nil
|
|
312
|
+
when Net::HTTPRedirection
|
|
313
|
+
# Try to download from the new URI, handle relative redirects.
|
|
314
|
+
puts "Redirected to #{response['Location']}" if Buildr.application.options.trace
|
|
315
|
+
return (self + URI.parse(response['location'])).read(options, &block)
|
|
316
|
+
when Net::HTTPOK
|
|
317
|
+
puts "Downloading #{self}" if verbose
|
|
318
|
+
result = nil
|
|
319
|
+
with_progress_bar options[:progress], path.split('/').last, response.content_length do |progress|
|
|
320
|
+
if block
|
|
321
|
+
response.read_body do |chunk|
|
|
322
|
+
block.call chunk
|
|
323
|
+
progress << chunk
|
|
324
|
+
end
|
|
325
|
+
else
|
|
326
|
+
result = ''
|
|
327
|
+
response.read_body do |chunk|
|
|
328
|
+
result << chunk
|
|
329
|
+
progress << chunk
|
|
342
330
|
end
|
|
343
331
|
end
|
|
344
|
-
|
|
345
|
-
when Net::HTTPNotFound
|
|
346
|
-
raise NotFoundError, "Looking for #{self} and all I got was a 404!"
|
|
347
|
-
else
|
|
348
|
-
raise RuntimeError, "Failed to download #{self}: #{response.message}"
|
|
349
332
|
end
|
|
333
|
+
return result
|
|
334
|
+
when Net::HTTPNotFound
|
|
335
|
+
raise NotFoundError, "Looking for #{self} and all I got was a 404!"
|
|
336
|
+
else
|
|
337
|
+
raise RuntimeError, "Failed to download #{self}: #{response.message}"
|
|
350
338
|
end
|
|
351
339
|
end
|
|
352
|
-
|
|
353
|
-
if proxy = proxy_uri
|
|
354
|
-
proxy = URI.parse(proxy) if String === proxy
|
|
355
|
-
Net::HTTP.start(host, port, proxy.host, proxy.port, proxy.user, proxy.password) { |http| request[http] }
|
|
356
|
-
else
|
|
357
|
-
Net::HTTP.start(host, port) { |http| request[http] }
|
|
358
|
-
end
|
|
359
|
-
result
|
|
360
340
|
end
|
|
361
341
|
|
|
362
342
|
end
|
|
@@ -366,7 +346,7 @@ module URI
|
|
|
366
346
|
|
|
367
347
|
class << self
|
|
368
348
|
# Caching of passwords, so we only need to ask once.
|
|
369
|
-
def passwords
|
|
349
|
+
def passwords
|
|
370
350
|
@passwords ||= {}
|
|
371
351
|
end
|
|
372
352
|
end
|
|
@@ -375,16 +355,16 @@ module URI
|
|
|
375
355
|
|
|
376
356
|
def write_internal(options, &block) #:nodoc:
|
|
377
357
|
# SSH options are based on the username/password from the URI.
|
|
378
|
-
ssh_options = { :port=>port, :username=>user }.merge(options[:ssh_options] || {})
|
|
358
|
+
ssh_options = { :port=>port, :username=>user, :password=>password }.merge(options[:ssh_options] || {})
|
|
379
359
|
ssh_options[:password] ||= SFTP.passwords[host]
|
|
380
360
|
begin
|
|
381
|
-
puts "Connecting to #{host}" if
|
|
361
|
+
puts "Connecting to #{host}" if Buildr.application.options.trace
|
|
382
362
|
session = Net::SSH.start(host, ssh_options)
|
|
383
363
|
SFTP.passwords[host] = ssh_options[:password]
|
|
384
364
|
rescue Net::SSH::AuthenticationFailed=>ex
|
|
385
365
|
# Only if running with console, prompt for password.
|
|
386
366
|
if !ssh_options[:password] && $stdout.isatty
|
|
387
|
-
password =
|
|
367
|
+
password = ask("Password for #{host}:") { |q| q.echo = '*' }
|
|
388
368
|
ssh_options[:password] = password
|
|
389
369
|
retry
|
|
390
370
|
end
|
|
@@ -392,20 +372,20 @@ module URI
|
|
|
392
372
|
end
|
|
393
373
|
|
|
394
374
|
session.sftp.connect do |sftp|
|
|
395
|
-
puts
|
|
375
|
+
puts 'connected' if Buildr.application.options.trace
|
|
396
376
|
|
|
397
377
|
# To create a path, we need to create all its parent. We use realpath to determine if
|
|
398
378
|
# the path already exists, otherwise mkdir fails.
|
|
399
|
-
puts "Creating path #{
|
|
400
|
-
File.dirname(path).split(
|
|
379
|
+
puts "Creating path #{path}" if Buildr.application.options.trace
|
|
380
|
+
File.dirname(path).split('/').inject('') do |base, part|
|
|
401
381
|
combined = base + part
|
|
402
382
|
sftp.realpath combined rescue sftp.mkdir combined, {}
|
|
403
383
|
"#{combined}/"
|
|
404
384
|
end
|
|
405
385
|
|
|
406
|
-
with_progress_bar options[:progress] && options[:size], path.split(
|
|
407
|
-
puts "Uploading to #{path}" if
|
|
408
|
-
sftp.open_handle(path,
|
|
386
|
+
with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress|
|
|
387
|
+
puts "Uploading to #{path}" if Buildr.application.options.trace
|
|
388
|
+
sftp.open_handle(path, 'w') do |handle|
|
|
409
389
|
# Writing in chunks gives us the benefit of a progress bar,
|
|
410
390
|
# but also require that we maintain a position in the file,
|
|
411
391
|
# since write() with two arguments always writes at position 0.
|
|
@@ -442,7 +422,7 @@ module URI
|
|
|
442
422
|
end
|
|
443
423
|
end
|
|
444
424
|
# Sadly, file://something really means file://something/ (something being server)
|
|
445
|
-
set_path
|
|
425
|
+
set_path '/' if path.empty?
|
|
446
426
|
|
|
447
427
|
# On windows, file://c:/something is not a valid URL, but people do it anyway, so if we see a drive-as-host,
|
|
448
428
|
# we'll just be nice enough to fix it. (URI actually strips the colon here)
|
|
@@ -455,14 +435,14 @@ module URI
|
|
|
455
435
|
# See URI::Generic#read
|
|
456
436
|
def read(options = nil, &block)
|
|
457
437
|
options ||= {}
|
|
458
|
-
raise ArgumentError,
|
|
438
|
+
raise ArgumentError, 'Either you\'re attempting to read a file from another host (which we don\'t support), or you used two slashes by mistake, where you should have file:///<path>.' if host
|
|
459
439
|
|
|
460
440
|
path = real_path
|
|
461
441
|
# TODO: complain about clunky URLs
|
|
462
442
|
raise NotFoundError, "Looking for #{self} and can't find it." unless File.exists?(path)
|
|
463
443
|
raise NotFoundError, "Looking for the file #{self}, and it happens to be a directory." if File.directory?(path)
|
|
464
|
-
File.open path,
|
|
465
|
-
with_progress_bar options[:progress], path.split(
|
|
444
|
+
File.open path, 'rb' do |input|
|
|
445
|
+
with_progress_bar options[:progress], path.split('/').last, input.stat.size do |progress|
|
|
466
446
|
block ? block.call(input.read) : input.read
|
|
467
447
|
end
|
|
468
448
|
end
|
|
@@ -482,11 +462,11 @@ module URI
|
|
|
482
462
|
protected
|
|
483
463
|
|
|
484
464
|
def write_internal(options, &block) #:nodoc:
|
|
485
|
-
raise ArgumentError,
|
|
465
|
+
raise ArgumentError, 'Either you\'re attempting to write a file to another host (which we don\'t support), or you used two slashes by mistake, where you should have file:///<path>.' if host
|
|
486
466
|
temp = nil
|
|
487
467
|
Tempfile.open File.basename(path) do |temp|
|
|
488
468
|
temp.binmode
|
|
489
|
-
with_progress_bar options[:progress] && options[:size], path.split(
|
|
469
|
+
with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress|
|
|
490
470
|
while chunk = yield(32 * 4096)
|
|
491
471
|
temp.write chunk
|
|
492
472
|
progress << chunk
|
|
@@ -499,7 +479,7 @@ module URI
|
|
|
499
479
|
end
|
|
500
480
|
end
|
|
501
481
|
|
|
502
|
-
@@schemes[
|
|
482
|
+
@@schemes['FILE'] = FILE
|
|
503
483
|
|
|
504
484
|
end
|
|
505
485
|
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with this
|
|
3
|
+
# work for additional information regarding copyright ownership. The ASF
|
|
4
|
+
# licenses this file to you under the Apache License, Version 2.0 (the
|
|
5
|
+
# "License"); you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
13
|
+
# License for the specific language governing permissions and limitations under
|
|
14
|
+
# the License.
|
|
15
|
+
|
|
16
|
+
require 'rbconfig'
|
|
17
|
+
require 'pathname'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
module Buildr
|
|
21
|
+
|
|
22
|
+
module Util
|
|
23
|
+
extend self
|
|
24
|
+
|
|
25
|
+
def java_platform?
|
|
26
|
+
RUBY_PLATFORM =~ /java/
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# In order to determine if we are running on a windows OS,
|
|
30
|
+
# prefer this function instead of using Gem.win_platform?.
|
|
31
|
+
#
|
|
32
|
+
# Gem.win_platform? only checks the RUBY_PLATFORM global,
|
|
33
|
+
# that in some cases like when running on JRuby is not
|
|
34
|
+
# succifient for our purpose:
|
|
35
|
+
#
|
|
36
|
+
# For JRuby, the value for RUBY_PLATFORM will always be 'java'
|
|
37
|
+
# That's why this function checks on Config::CONFIG['host_os']
|
|
38
|
+
def win_os?
|
|
39
|
+
Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Runs Ruby with these command line arguments. The last argument may be a hash,
|
|
43
|
+
# supporting the following keys:
|
|
44
|
+
# :command -- Runs the specified script (e.g., :command=>'gem')
|
|
45
|
+
# :sudo -- Run as sudo on operating systems that require it.
|
|
46
|
+
# :verbose -- Override Rake's verbose flag.
|
|
47
|
+
def ruby(*args)
|
|
48
|
+
options = Hash === args.last ? args.pop : {}
|
|
49
|
+
cmd = []
|
|
50
|
+
ruby_bin = File.expand_path(Config::CONFIG['ruby_install_name'], Config::CONFIG['bindir'])
|
|
51
|
+
if options.delete(:sudo) && !(win_os? || Process.uid == File.stat(ruby_bin).uid)
|
|
52
|
+
cmd << 'sudo' << '-u' << "##{File.stat(ruby_bin).uid}"
|
|
53
|
+
end
|
|
54
|
+
cmd << ruby_bin
|
|
55
|
+
cmd << '-S' << options.delete(:command) if options[:command]
|
|
56
|
+
sh *cmd.push(*args.flatten).push(options) do |ok, status|
|
|
57
|
+
ok or fail "Command failed with status (#{status ? status.exitstatus : 'unknown'}): [#{cmd.join(" ")}]"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Just like File.expand_path, but for windows systems it
|
|
62
|
+
# capitalizes the drive name and ensures backslashes are used
|
|
63
|
+
def normalize_path(path, *dirs)
|
|
64
|
+
path = File.expand_path(path, *dirs)
|
|
65
|
+
if win_os?
|
|
66
|
+
path.gsub!('/', '\\').gsub!(/^[a-zA-Z]+:/) { |s| s.upcase }
|
|
67
|
+
else
|
|
68
|
+
path
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Return the timestamp of file, without having to create a file task
|
|
73
|
+
def timestamp(file)
|
|
74
|
+
if File.exist?(file)
|
|
75
|
+
File.mtime(file)
|
|
76
|
+
else
|
|
77
|
+
Rake::EARLY
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Return the path to the first argument, starting from the path provided by the
|
|
82
|
+
# second argument.
|
|
83
|
+
#
|
|
84
|
+
# For example:
|
|
85
|
+
# relative_path('foo/bar', 'foo')
|
|
86
|
+
# => 'bar'
|
|
87
|
+
# relative_path('foo/bar', 'baz')
|
|
88
|
+
# => '../foo/bar'
|
|
89
|
+
# relative_path('foo/bar')
|
|
90
|
+
# => 'foo/bar'
|
|
91
|
+
# relative_path('/foo/bar', 'baz')
|
|
92
|
+
# => '/foo/bar'
|
|
93
|
+
def relative_path(to, from = '.')
|
|
94
|
+
to = Pathname.new(to).cleanpath
|
|
95
|
+
return to.to_s if from.nil?
|
|
96
|
+
to_path = Pathname.new(File.expand_path(to.to_s, "/"))
|
|
97
|
+
from_path = Pathname.new(File.expand_path(from.to_s, "/"))
|
|
98
|
+
to_path.relative_path_from(from_path).to_s
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Generally speaking, it's not a good idea to operate on dot files (files starting with dot).
|
|
102
|
+
# These are considered invisible files (.svn, .hg, .irbrc, etc). Dir.glob/FileList ignore them
|
|
103
|
+
# on purpose. There are few cases where we do have to work with them (filter, zip), a better
|
|
104
|
+
# solution is welcome, maybe being more explicit with include. For now, this will do.
|
|
105
|
+
def recursive_with_dot_files(*dirs)
|
|
106
|
+
FileList[dirs.map { |dir| File.join(dir, '/**/{*,.*}') }].reject { |file| File.basename(file) =~ /^[.]{1,2}$/ }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
module Kernel #:nodoc:
|
|
114
|
+
# Borrowed from Ruby 1.9.
|
|
115
|
+
def tap
|
|
116
|
+
yield self if block_given?
|
|
117
|
+
self
|
|
118
|
+
end unless method_defined?('tap')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Symbol #:nodoc:
|
|
123
|
+
# Borrowed from Ruby 1.9.
|
|
124
|
+
def to_proc
|
|
125
|
+
Proc.new{|*args| args.shift.__send__(self, *args)}
|
|
126
|
+
end unless method_defined?('to_proc')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Also borrowed from Ruby 1.9.
|
|
131
|
+
class BasicObject #:nodoc:
|
|
132
|
+
(instance_methods - ['__send__', '__id__', '==', 'send', 'send!', 'respond_to?', 'equal?', 'object_id']).
|
|
133
|
+
each do |method|
|
|
134
|
+
undef_method method
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def self.ancestors
|
|
138
|
+
[Kernel]
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class OpenObject < Hash
|
|
144
|
+
|
|
145
|
+
def initialize(source=nil, &block)
|
|
146
|
+
@hash = Hash.new(&block)
|
|
147
|
+
@hash.update(source) if source
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def [](key)
|
|
151
|
+
@hash[key]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def []=(key, value)
|
|
155
|
+
@hash[key] = value
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def delete(key)
|
|
159
|
+
@hash.delete(key)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def to_hash
|
|
163
|
+
@hash.clone
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def method_missing(symbol, *args)
|
|
167
|
+
if symbol.to_s =~ /=$/
|
|
168
|
+
self[symbol.to_s[0..-2].to_sym] = args.first
|
|
169
|
+
else
|
|
170
|
+
self[symbol]
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class Hash
|
|
177
|
+
|
|
178
|
+
class << self
|
|
179
|
+
|
|
180
|
+
# :call-seq:
|
|
181
|
+
# Hash.from_java_properties(string)
|
|
182
|
+
#
|
|
183
|
+
# Returns a hash from a string in the Java properties file format. For example:
|
|
184
|
+
# str = 'foo=bar\nbaz=fab'
|
|
185
|
+
# Hash.from_properties(str)
|
|
186
|
+
# => { 'foo'=>'bar', 'baz'=>'fab' }.to_properties
|
|
187
|
+
def from_java_properties(string)
|
|
188
|
+
string.gsub(/\\\n/, '').split("\n").select { |line| line =~ /^[^#].*=.*/ }.
|
|
189
|
+
map { |line| line.gsub(/\\[trnf\\]/) { |escaped| {?t=>"\t", ?r=>"\r", ?n=>"\n", ?f=>"\f", ?\\=>"\\"}[escaped[1]] } }.
|
|
190
|
+
map { |line| line.split('=') }.
|
|
191
|
+
inject({}) { |hash, (name, value)| hash.merge(name=>value) }
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# :call-seq:
|
|
197
|
+
# only(keys*) => hash
|
|
198
|
+
#
|
|
199
|
+
# Returns a new hash with only the specified keys.
|
|
200
|
+
#
|
|
201
|
+
# For example:
|
|
202
|
+
# { :a=>1, :b=>2, :c=>3, :d=>4 }.only(:a, :c)
|
|
203
|
+
# => { :a=>1, :c=>3 }
|
|
204
|
+
def only(*keys)
|
|
205
|
+
keys.inject({}) { |hash, key| has_key?(key) ? hash.merge(key=>self[key]) : hash }
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# :call-seq:
|
|
210
|
+
# except(keys*) => hash
|
|
211
|
+
#
|
|
212
|
+
# Returns a new hash without the specified keys.
|
|
213
|
+
#
|
|
214
|
+
# For example:
|
|
215
|
+
# { :a=>1, :b=>2, :c=>3, :d=>4 }.except(:a, :c)
|
|
216
|
+
# => { :b=>2, :d=>4 }
|
|
217
|
+
def except(*keys)
|
|
218
|
+
(self.keys - keys).inject({}) { |hash, key| hash.merge(key=>self[key]) }
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# :call-seq:
|
|
222
|
+
# to_java_properties => string
|
|
223
|
+
#
|
|
224
|
+
# Convert hash to string format used for Java properties file. For example:
|
|
225
|
+
# { 'foo'=>'bar', 'baz'=>'fab' }.to_properties
|
|
226
|
+
# => foo=bar
|
|
227
|
+
# baz=fab
|
|
228
|
+
def to_java_properties
|
|
229
|
+
keys.sort.map { |key|
|
|
230
|
+
value = self[key].gsub(/[\t\r\n\f\\]/) { |escape| "\\" + {"\t"=>"t", "\r"=>"r", "\n"=>"n", "\f"=>"f", "\\"=>"\\"}[escape] }
|
|
231
|
+
"#{key}=#{value}"
|
|
232
|
+
}.join("\n")
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
end
|