buildr 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +1,40 @@
1
1
  require "core/project"
2
2
  require "java/java"
3
+ require "antwrap"
4
+ require "core/help"
5
+
3
6
 
4
7
  module Buildr
5
8
  module Ant
6
9
 
7
- # Libraries used by #ant.
8
- REQUIRES = [ "ant:ant:jar:1.6.5", "ant:ant-launcher:jar:1.6.5", "xerces:xercesImpl:jar:2.6.2" ]
10
+ # Which version of Ant we're using by default.
11
+ VERSION = "1.7.0"
9
12
 
10
- # Make sure Ant and friends show on the classpath. Antwrap must only be loaded after RJB.
11
- Java.rjb.classpath << REQUIRES
12
- Java.rjb.onload { require "antwrap" }
13
+ # Libraries used by Ant.
14
+ REQUIRES = [ "org.apache.ant:ant:jar:#{VERSION}", "org.apache.ant:ant-launcher:jar:#{VERSION}", "xerces:xercesImpl:jar:2.6.2" ]
15
+ Java.rjb.onload { |rjb| rjb.classpath << REQUIRES }
13
16
 
14
17
  class << self
15
18
 
16
- # :call-seq:
17
- # declarative(name, options?) => AntProject
18
- # declarative(name, options?) { |AntProject| ... } => AntProject
19
- #
20
- # Returns a declarative AntProject with the specified name. Ant tasks created in this project
21
- # are not executed until you tell them to.
22
- #
23
- # See #ant for more information about options and the block.
19
+ # *Deprecated* Use ant { ... } instead.
24
20
  def declarative(name, options = nil, &block)
25
- options ||= {}
26
- options = (options || {}).merge(:name=>name, :base_dir=>Dir.pwd, :declarative=>false)
27
- Java.rjb { AntProject.new(options).tap { |project| yield project if block_given? } }
21
+ warn_deprecated "Use ant { ... } instead."
22
+ Buildr.ant name, options, &block
28
23
  end
29
24
 
30
- # :call-seq:
31
- # executable(name, options?) => AntProject
32
- # executable(name, options?) { |AntProject| ... } => AntProject
33
- #
34
- # Returns an executable AntProject with the specified name. Ant tasks created in this project
35
- # are executed immediately.
36
- #
37
- # See #ant for more information about options and the block.
25
+ # *Deprecated* Use ant { ... } instead.
38
26
  def executable(name, options = nil, &block)
39
- options ||= {}
40
- options = (options || {}).merge(:name=>name, :base_dir=>Dir.pwd, :declarative=>true)
41
- Java.rjb { AntProject.new(options).tap { |project| yield project if block_given? } }
27
+ warn_deprecated "Use ant { ... } instead."
28
+ Buildr.ant name, options, &block
42
29
  end
30
+
43
31
  end
44
32
 
45
33
  # :call-seq:
46
- # ant(name, options?) => AntProject
47
- # ant(name, options?) { |AntProject| ... } => AntProject
48
- #
49
- # Returns a new AntProject with the specified name. Ant tasks created in this project are
50
- # executed immediately.
34
+ # ant(name) { |AntProject| ... } => AntProject
51
35
  #
52
- # The options hash is passed to the Ant project definition, along with the current directory.
53
- # When used in a Buildr project, the Ant project will have the same base directory.
54
- # If you pass a block, yields to the block with the Ant project.
36
+ # Creates a new AntProject with the specified name, yield to the block for defining various
37
+ # Ant tasks, and executes each task as it's defined.
55
38
  #
56
39
  # For example:
57
40
  # ant("hibernatedoclet") do |doclet|
@@ -63,11 +46,25 @@ module Buildr
63
46
  # end
64
47
  # end
65
48
  def ant(name, options=nil, &block)
66
- Ant.executable(name, options, &block)
49
+ warn_deprecated "Options are ignored." if options
50
+ options = { :name=>name, :basedir=>Dir.pwd, :declarative=>true }
51
+ Java.rjb do
52
+ AntProject.new(options).tap do |project|
53
+ # Set Ant logging level to debug (--trace), info (default) or error only (--quiet).
54
+ project.project.getBuildListeners().get(0).
55
+ setMessageOutputLevel((Rake.application.options.trace && 4) || (verbose && 2) || 0)
56
+ yield project if block_given?
57
+ end
58
+ end
67
59
  end
68
60
 
69
61
  end
70
62
 
71
63
  include Ant
72
64
 
65
+ task("help") do
66
+ puts
67
+ puts "Using Java #{Java.version}, Ant #{Ant::VERSION}."
68
+ end
69
+
73
70
  end
@@ -1,5 +1,6 @@
1
1
  require "core/project"
2
2
  require "core/transports"
3
+ require "builder"
3
4
 
4
5
  module Buildr
5
6
 
@@ -73,6 +74,52 @@ module Buildr
73
74
  Buildr.artifact(:group=>group, :id=>id, :version=>version, :type=>:pom, :classifier=>classifier)
74
75
  end
75
76
 
77
+ # :call-seq:
78
+ # pom_xml() => string
79
+ #
80
+ # Creates POM XML for this artifact.
81
+ def pom_xml()
82
+ xml = Builder::XmlMarkup.new(:indent=>2)
83
+ xml.instruct!
84
+ xml.project do
85
+ xml.modelVersion "4.0.0"
86
+ xml.groupId group
87
+ xml.artifactId id
88
+ xml.version version
89
+ xml.classifier classifier if classifier
90
+ end
91
+ end
92
+
93
+ # :call-seq:
94
+ # upload()
95
+ # upload(url)
96
+ # upload(options)
97
+ #
98
+ # Uploads the artifact, its POM and digital signatures to remote server.
99
+ #
100
+ # In the first form, uses the upload options specified by repositories.release_to.
101
+ # In the second form, uses a URL that includes all the relevant information.
102
+ # In the third form, uses a hash with the options :url, :username, :password,
103
+ # :proxy and :permissions. All but :url are optional.
104
+ def upload(upload_to = nil)
105
+ # Where do we release to?
106
+ upload_to ||= Buildr.repositories.release_to
107
+ upload_to = { :url=>upload_to } unless Hash === upload_to
108
+ raise ArgumentError, "Don't know where to upload, perhaps you forgot to set repositories.release_to" if upload_to[:url].blank?
109
+
110
+ # Set the upload URI, including mandatory slash (we expect it to be the base directory).
111
+ # Username/password may be part of URI, or separate entities.
112
+ uri = URI.parse(upload_to[:url].clone)
113
+ uri.path = uri.path + "/" unless uri.path[-1] == "/"
114
+ uri.user = upload_to[:username] if upload_to[:username]
115
+ uri.password = upload_to[:password] if upload_to[:password]
116
+
117
+ # Upload artifact relative to base URL, need to create path before uploading.
118
+ puts "Deploying #{to_spec}" if verbose
119
+ path = group.gsub(".", "/") + "/#{id}/#{version}/#{File.basename(name)}"
120
+ URI.upload uri + path, name, :proxy=>Buildr.options.proxy, :permissions=>upload_to[:permissions]
121
+ end
122
+
76
123
  protected
77
124
 
78
125
  # Apply specification to this artifact.
@@ -102,30 +149,6 @@ module Buildr
102
149
 
103
150
  class << self
104
151
 
105
- # :call-seq:
106
- # force_download() => boolean
107
- # force_download(value) => value
108
- # force.download(value) { ... }
109
- #
110
- # In the first form, returns the value of the force download flag. This flag is set
111
- # to force downloading of artifacts, even if those artifacts already exist in the local
112
- # repository. (Used by the artifacts task).
113
- #
114
- # In the second form sets the value of the force download flag. In the third form, sets
115
- # the value of the flag, yields to the block, and resets the flag to its previous value.
116
- def force_download(value = @force_download)
117
- if block_given?
118
- begin
119
- old_value, @force_download = @force_download, value
120
- yield
121
- ensure
122
- @force_download = old_value
123
- end
124
- else
125
- @force_download = value
126
- end
127
- end
128
-
129
152
  # :call-seq:
130
153
  # lookup(spec) => Artifact
131
154
  #
@@ -135,6 +158,14 @@ module Buildr
135
158
  @artifacts[to_spec(spec)]
136
159
  end
137
160
 
161
+ # :call-seq:
162
+ # list() => specs
163
+ #
164
+ # Returns an array of specs for all the registered artifacts. (Anything created from artifact, or package).
165
+ def list()
166
+ @artifacts.keys
167
+ end
168
+
138
169
  # :call-seq:
139
170
  # register(artifacts) => artifacts
140
171
  #
@@ -210,43 +241,61 @@ module Buildr
210
241
  def initialize(*args) #:nodoc:
211
242
  super
212
243
  enhance do |task|
213
- # Default behavior: download the artifact from one of the remote
214
- # repositories if the file does not exist. But this default behavior
215
- # is counter useful if the artifact knows how to build itself
216
- # (e.g. download from a different location), so don't perform it
217
- # if the task found a different way to create the artifact.
218
- # For that, we need to be the last piece of code run by the task.
219
- if @actions.size == 1
220
- task.enhance do
221
- begin
222
- puts "Downloading #{to_spec}" if verbose
223
- Buildr.repositories.download(to_spec)
224
- rescue Exception=>error
225
- if File.exist?(name)
226
- puts error
227
- else
228
- raise
229
- end
230
- end
244
+ # Default behavior: download the artifact from one of the remote repositories
245
+ # if the file does not exist. But this default behavior is counter productive
246
+ # if the artifact knows how to build itself (e.g. download from a different location),
247
+ # so don't perform it if the task found a different way to create the artifact.
248
+ task.enhance do
249
+ unless File.exist?(name)
250
+ puts "Downloading #{to_spec}" if verbose
251
+ download
252
+ pom.invoke rescue nil if pom && pom != self
231
253
  end
232
254
  end
233
255
  end
234
256
  end
235
257
 
236
- def needed?()
237
- Artifact.force_download || super
258
+ protected
259
+
260
+ # :call-seq:
261
+ # download()
262
+ #
263
+ # Downloads an artifact from one of the remote repositories, and stores it in the local
264
+ # repository. Accepts a String or Hash artifact specification, and returns a path to the
265
+ # artifact in the local repository. Raises an exception if the artifact is not found.
266
+ #
267
+ # This method attempts to download the artifact from each repository in the order in
268
+ # which they are returned from #remote, until successful. It always downloads the POM first.
269
+ def download()
270
+ puts "Downloading #{to_spec}" if Rake.application.options.trace
271
+ remote = Buildr.repositories.remote
272
+ remote.find do |repo_url|
273
+ repo_url = URI.parse(repo_url) unless URI === repo_url
274
+ repo_url.path += "/" unless repo_url.path[-1] == "/"
275
+ begin
276
+ path = group.gsub(".", "/") + "/#{id}/#{version}/#{File.basename(name)}"
277
+ mkpath File.dirname(name), :verbose=>false
278
+ URI.download repo_url + path, name, :proxy=>Buildr.options.proxy
279
+ true
280
+ rescue URI::NotFoundError
281
+ false
282
+ rescue Exception=>error
283
+ puts error if verbose
284
+ puts error.backtrace.join("\n") if Rake.application.options.trace
285
+ false
286
+ end
287
+ end or fail "Failed to download #{to_spec}, tried the following repositories:\n#{remote.join("\n")}"
238
288
  end
239
289
 
240
290
  end
241
291
 
242
292
 
243
- # Holds the path to the local repository, URLs for remote repositories, and
244
- # settings for the deployment repository.
293
+ # Holds the path to the local repository, URLs for remote repositories, and settings for release server.
245
294
  #
246
295
  # You can access this object from the #repositories method. For example:
247
296
  # puts repositories.local
248
297
  # repositories.remote << "http://example.com/repo"
249
- # repositories.deploy_to = "sftp://example.com/var/www/public/repo"
298
+ # repositories.release_to = "sftp://example.com/var/www/public/repo"
250
299
  class Repositories
251
300
  include Singleton
252
301
 
@@ -319,77 +368,38 @@ module Buildr
319
368
  end
320
369
  end
321
370
 
322
- # :call-seq:
323
- # proxy() => Hash
324
- #
325
- # Returns the proxy settings used when downloading from remote repositories.
371
+ # *Deprecated* Please use options.proxy.http instead of repositories.proxy.
326
372
  def proxy()
327
- @proxy ||= {}
373
+ warn_deprecated "Please use options.proxy.http instead of repositories.proxy"
374
+ Buildr.options.proxy.http
328
375
  end
329
376
 
330
- # :call-seq:
331
- # proxy = Hash
332
- # proxy = String
333
- # proxy = URI
334
- # proxy = nil
335
- #
336
- # Sets the proxy settings used when downloading from remote repositories.
337
- # You can specify proxy settings using a Hash with values for :host, :port,
338
- # :user and :password.
339
- #
340
- # You can also pass a URL as a string or URI object. The settings are converted
341
- # to a hash.
342
- #
343
- # For example:
344
- # repositories.proxy = { :host=>"proxy.acme.com", :port=>8080 }
345
- # repositories.proxy = "proxy.acme.com:8080"
377
+ # *Deprecated* Please use options.proxy.http = <url> instead of repositories.proxy.
346
378
  def proxy=(proxy)
347
- case proxy
348
- when Hash, nil
349
- @proxy = proxy || {}
350
- when String
351
- proxy = "http://#{proxy}" unless proxy =~ /^http(s?)/i
352
- proxy = URI.parse(proxy)
353
- @proxy = { :host=>proxy.host, :port=>proxy.port, :user=>proxy.user, :password=>proxy.password }
354
- when URI
355
- @proxy = { :host=>proxy.host, :port=>proxy.port, :user=>proxy.user, :password=>proxy.password }
356
- else
357
- fail "Expecting a Hash, String or URI."
358
- end
379
+ warn_deprecated "Please use options.proxy.http = <url> instead of repositories.proxy"
380
+ Buildr.options.proxy.http = proxy
359
381
  end
360
-
361
- # :call-seq:
362
- # download(spec) => boolean
363
- #
364
- # Downloads an artifact from one of the remote repositories, and stores it in the local
365
- # repository. Accepts a String or Hash artifact specification, and returns a path to the
366
- # artifact in the local repository. Raises an exception if the artifact is not found.
367
- #
368
- # This method attempts to download the artifact from each repository in the order in
369
- # which they are returned from #remote, until successful. If you want to download an
370
- # artifact only if not already installed in the local repository, create an #artifact
371
- # task and invoke it directly.
382
+
383
+ # *Deprecated* Just create an artifact and invoke it.
372
384
  def download(spec)
385
+ warn_deprecated "Just create and artifact and invoke it."
373
386
  spec = Artifact.to_hash(spec) unless Hash === spec
374
- path = locate(spec)
387
+ filename = locate(spec)
375
388
 
376
389
  puts "Downloading #{Artifact.to_spec(spec)}" if Rake.application.options.trace
377
- return path if remote.any? do |repo_url|
390
+ return filename if remote.any? do |repo_url|
391
+ repo_url = URI.parse(repo_url) unless URI === repo_url
392
+ repo_url.path += "/" unless repo_url.path[-1] == "/"
378
393
  begin
379
- rel_path = spec[:group].gsub(".", "/") +
394
+ path = spec[:group].gsub(".", "/") +
380
395
  "/#{spec[:id]}/#{spec[:version]}/#{Artifact.hash_to_file_name(spec)}"
381
- Transports.perform URI.parse(repo_url.to_s), :proxy=>proxy do |http|
382
- mkpath File.dirname(path), :verbose=>false
383
- http.download(rel_path, path)
384
- end
385
- Transports.perform URI.parse(repo_url.to_s), :proxy=>proxy do |http|
386
- begin
387
- http.download(rel_path.ext("pom"), path.ext("pom"))
388
- rescue Transports::NotFound
389
- end
390
- end
396
+ mkpath File.dirname(filename), :verbose=>false
397
+ # We absolutely need the POM, so make sure we download it before the artifact
398
+ # (unless the artifact is a POM).
399
+ URI.download repo_url + path.ext("pom"), name.ext("pom"), :proxy=>Buildr.options.proxy unless type == :pom
400
+ URI.download repo_url + path, filename, :proxy=>Buildr.options.proxy
391
401
  true
392
- rescue Transports::NotFound
402
+ rescue URI::NotFoundError
393
403
  false
394
404
  rescue Exception=>error
395
405
  puts error if verbose
@@ -401,39 +411,48 @@ module Buildr
401
411
  end
402
412
 
403
413
  # :call-seq:
404
- # deploy_to = url
405
- # deploy_to = hash
414
+ # release_to = url
415
+ # release_to = hash
406
416
  #
407
- # Specifies the deployment repository. Accepts a Hash with different repository settings
417
+ # Specifies the release server. Accepts a Hash with different repository settings
408
418
  # (e.g. url, username, password), or a String to only set the repository URL.
409
419
  #
410
- # Besides the URL, all other settings depend on the transport protocol in use. See #Transports
411
- # for more details. Common settings include username and password.
420
+ # Besides the URL, all other settings depend on the transport protocol in use.
412
421
  #
413
422
  # For example:
414
- # repositories.deploy_to = { :url=>"sftp://example.com/var/www/repo/",
415
- # :username="john", :password=>"secret" }
416
- # or:
417
- # repositories.deploy_to = "sftp://john:secret@example.com/var/www/repo/"
418
- def deploy_to=(options)
423
+ # repositories.release_to = "sftp://john:secret@example.com/var/www/repo/"
424
+ # repositories.release_to = { :url=>"sftp://example.com/var/www/repo/",
425
+ # :username="john", :password=>"secret" }
426
+ def release_to=(options)
419
427
  options = { :url=>options } unless Hash === options
420
- @deploy_to = options
428
+ @release_to = options
421
429
  end
422
430
 
423
431
  # :call-seq:
424
- # deploy_to() => hash
432
+ # release_to() => hash
425
433
  #
426
- # Returns the current deployment repository setting as a Hash. This is a more convenient
427
- # way to specify the deployment repository, as it allows you to specify the settings
428
- # progressively.
434
+ # Returns the current release server setting as a Hash. This is a more convenient way to
435
+ # configure the settings, as it allows you to specify the settings progressively.
429
436
  #
430
- # For example, the Rakefile will contain the repository URL used by all developers:
431
- # repositories.deploy_to[:url] ||= "sftp://example.com/var/www/repo"
437
+ # For example, the Buildfile will contain the repository URL used by all developers:
438
+ # repositories.release_to[:url] ||= "sftp://example.com/var/www/repo"
432
439
  # Your private buildr.rb will contain your credentials:
433
- # repositories.deploy_to[:username] = "john"
434
- # repositories.deploy_to[:password] = "secret"
440
+ # repositories.release_to[:username] = "john"
441
+ # repositories.release_to[:password] = "secret"
442
+ def release_to()
443
+ @release_to ||= {}
444
+ end
445
+
446
+ # *Deprecated* See release_to.
447
+ def deploy_to=(options)
448
+ warn_deprecated "Please use release_to instead."
449
+ self.release_to = options
450
+ end
451
+
452
+ # *Deprecated* See release_to.
435
453
  def deploy_to()
436
- @deploy_to ||= {}
454
+ warn_deprecated "Please use release_to instead."
455
+ self.release_to
437
456
  end
438
457
 
439
458
  end
@@ -442,7 +461,7 @@ module Buildr
442
461
  # repositories() => Repositories
443
462
  #
444
463
  # Returns an object you can use for setting the local repository path, remote repositories
445
- # URL and deployment repository settings.
464
+ # URL and release server settings.
446
465
  #
447
466
  # See Repositories.
448
467
  def repositories()
@@ -478,7 +497,6 @@ module Buildr
478
497
  task = Artifact.define_task(repositories.locate(spec))
479
498
  task.send :apply_spec, spec
480
499
  Rake::Task["rake:artifacts"].enhance [task]
481
- Rake::Task["rake:artifacts:refresh"].enhance { Artifact.force_download(true) { task.invoke } }
482
500
  Artifact.register(task)
483
501
  end
484
502
  task.enhance &block
@@ -495,7 +513,7 @@ module Buildr
495
513
  # * An artifact of any other task. Returns the task as is.
496
514
  # * A project. Returns all artifacts created (packaged) by that project.
497
515
  # * A string. Returns that string, assumed to be a file name.
498
- # * An array of artifacts. Calls #artifacts on the array, flattens the result.
516
+ # * An array of artifacts or a Struct.
499
517
  #
500
518
  # For example, handling a collection of artifacts:
501
519
  # xml = [ xerces, xalan, jaxp ]
@@ -519,6 +537,8 @@ module Buildr
519
537
  set |= artifacts(spec.packages)
520
538
  when Rake::Task
521
539
  set |= [spec]
540
+ when Struct
541
+ set |= artifacts(spec.values)
522
542
  else
523
543
  fail "Invalid artifact specification in: #{specs.to_s}"
524
544
  end
@@ -542,43 +562,35 @@ module Buildr
542
562
  args.flatten.map { |id| artifact :group=>hash[:under], :version=>hash[:version], :id=>id }
543
563
  end
544
564
 
545
- # :call-seq:
546
- # deploy(*files)
547
- # deploy(*files, deploy_options)
548
- #
549
- # Deploys all the specified artifacts/files. If the last argument is a Hash, it is used to
550
- # specify the deployment repository. Otherwise, obtains the deployment repository by calling
551
- # Repositories#deploy_to.
552
- #
553
- # When deploying files, you can specify a path relative to the deployment URL. Artifacts are
554
- # always deployed to a path that combined the group identifier, artifact identifier and
555
- # version number.
556
- #
557
- # For example:
558
- # deploy(foo.packages, :url=>"sftp://example.com/var/www/repo")
559
- # deploy(file("LICENSE"), :path=>group.tr(".", "/"))
565
+ # *Deprecated* For artifact, call it's upload method; for anything else, use URI.upload.
560
566
  def deploy(*args)
567
+ warn_deprecated "If it's an artifact, call it's upload method directly. Otherwise, use URI.upload."
561
568
  # Where do we release to?
562
569
  options = Hash === args.last ? args.pop : {}
563
- deploy_to = options[:url] ? options : repositories.deploy_to
570
+ deploy_to = options[:url] ? options : repositories.release_to
564
571
  fail "Don't know where to deploy, perhaps you forgot to set repositories.deploy_to" if deploy_to[:url].blank?
565
572
 
566
573
  args.flatten.each { |arg| arg.invoke if arg.respond_to?(:invoke) }
567
- # Strip :url and :path, in case the transport checks for valid options.
568
- Transports.perform deploy_to[:url], deploy_to.reject{ |k,v| k == :url || k == :path } do |session|
569
- args.flatten.each do |artifact|
570
- if artifact.respond_to?(:to_spec)
571
- # Upload artifact relative to base URL, need to create path before uploading.
572
- puts "Deploying #{artifact.to_spec}" if verbose
573
- spec = artifact.to_spec_hash
574
- path = spec[:group].gsub(".", "/") + "/#{spec[:id]}/#{spec[:version]}/"
575
- session.mkpath path
576
- session.upload artifact.to_s, path + Artifact.hash_to_file_name(spec)
577
- else
578
- # Upload artifact to URL.
579
- puts "Deploying #{artifact}" if verbose
580
- session.upload artifact.to_s, File.join(*(options[:path].to_a + [File.basename(artifact.to_s)]).compact)
581
- end
574
+ # Set the upload URI, including mandatory slash (we expect it to be the base directory).
575
+ # Username/password may be part of URI, or separate entities.
576
+ uri = URI.parse(deploy_to[:url].clone)
577
+ uri.path = uri.path + "/" unless uri.path[-1] == "/"
578
+ uri.user = deploy_to[:username] if deploy_to[:username]
579
+ uri.password = deploy_to[:password] if deploy_to[:password]
580
+
581
+ args.each do |arg|
582
+ if arg.respond_to?(:to_spec)
583
+ # Upload artifact relative to base URL, need to create path before uploading.
584
+ puts "Deploying #{arg.to_spec}" if verbose
585
+ spec = arg.to_spec_hash
586
+ path = spec[:group].gsub(".", "/") + "/#{spec[:id]}/#{spec[:version]}/" + Artifact.hash_to_file_name(spec)
587
+ URI.upload uri + path, arg.to_s, :proxy=>Buildr.options.proxy, :permissions=>deploy_to[:permissions]
588
+ else
589
+ # Upload file to URL.
590
+ puts "Deploying #{arg}" if verbose
591
+ path = File.basename(args.to_s)
592
+ path = File.join(options[:path], path) if options[:path]
593
+ URI.upload uri + path, arg.to_s, :proxy=>Buildr.options.proxy, :permissions=>deploy_to[:permissions]
582
594
  end
583
595
  end
584
596
  end