buildr 1.2.0 → 1.2.1

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 CHANGED
@@ -1,4 +1,16 @@
1
- 1.2 (6/6/2007)
1
+ 1.2.1 (7/12/2007)
2
+ * Added: Proxy exclusion, use environment variable NO_PROXY, or options.proxy.exclude = <url> || [<url>] (http://groups.google.com/group/buildr-talk/t/9f1e988e0dbeea9f).
3
+ * Added: You can now copy resources from multiple source directories, using resources.from (http://groups.google.com/group/buildr-talk/browse_thread/thread/4f2867a6dbbc19d4).
4
+ * Added: Hash.from_java_properties(string) and hash.to_java_properties.
5
+ * Changed: Buildr.options now wrap various environment variables instead of duplicating them (HTTP_PROXY, NO_PROXY, TEST, DEBUG).
6
+ * Changed: No longer passing proxies to transports, instead they obtain them from environment variables.
7
+ * Changed: Buildr now uses XJavaDoc 1.1 instead of 1.1-j5. If you need the 1.1-j5 fix, see here http://groups.google.com/group/buildr-talk/browse_thread/thread/49f3226810466c94/1f0d25d002433fe2.
8
+ * Fixed: One RubyForge release for all packages, instead of one per package (Anatol Pomozov).
9
+ * Fixed: buildr command does not recognize project tasks (foo:compile) or default task (http://groups.google.com/group/buildr-talk/t/660061a0bc81989a).
10
+ * Fixed: Upload fails on SFTP permissions.
11
+ * Fixed: Hibernate.schema_export not passing Ant task when yielding.
12
+
13
+ 1.2.0 (6/6/2007)
2
14
  * Added: Artifact.list returns specs for all registered artifacts (those created with artifact or package).
3
15
  * Added: Buildr.option.java_args are used when creating the RJB JVM, when running a Java process (unless you override directly), and when running JUnit tests (again, unless override).
4
16
  * Added: TestNG support (test.using :testng).
data/Rakefile CHANGED
@@ -141,10 +141,12 @@ end
141
141
 
142
142
  namespace :upload do
143
143
  task :docs=>"rake:docs" do |task|
144
- `rsync -r --del --progress html/* rubyforge.org:/var/www/gforge-projects/#{spec.rubyforge_project.downcase}`
144
+ sh "rsync -r --del --progress html/* rubyforge.org:/var/www/gforge-projects/#{spec.rubyforge_project.downcase}"
145
145
  end
146
146
 
147
147
  task :packages=>["rake:docs", "rake:package"] do |task|
148
+ require 'rubyforge'
149
+
148
150
  # Read the changes for this release.
149
151
  pattern = /(^(\d+\.\d+(?:\.\d+)?)\s+\(\d+\/\d+\/\d+\)\s*((:?^[^\n]+\n)*))/
150
152
  changelog = File.read(__FILE__.pathmap("%d/CHANGELOG"))
@@ -156,12 +158,13 @@ namespace :upload do
156
158
  fail "No changeset found for version #{spec.version}" unless current
157
159
 
158
160
  puts "Uploading #{spec.name} #{spec.version}"
159
- files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{spec.name}-#{spec.version}.#{ext}" }
160
- system "rubyforge", "login"
161
- files.each do |file|
162
- system "rubyforge", "add_release", spec.rubyforge_project.downcase, spec.name.downcase,
163
- spec.version.to_s, file, "-a", current
164
- end
161
+ files = %w( gem tgz zip ).map { |ext| "pkg/#{spec.name}-#{spec.version}.#{ext}" }
162
+ rubyforge = RubyForge.new
163
+ rubyforge.login
164
+ File.open(".changes", 'w'){|f| f.write(current)}
165
+ rubyforge.userconfig.merge!("release_changes" => ".changes", "preformatted" => true)
166
+ rubyforge.add_release spec.rubyforge_project.downcase, spec.name.downcase, spec.version, *files
167
+ rm ".changes"
165
168
  puts "Release #{spec.version} uploaded"
166
169
  end
167
170
  end
@@ -19,10 +19,11 @@ require "facet/string/starts_with"
19
19
  require "facet/openobject"
20
20
  require "facets/core/kernel/tap"
21
21
  # A different kind of buildr, one we use to create XML.
22
+ require "builder"
22
23
 
23
24
 
24
25
  module Buildr
25
- VERSION = "1.2.0".freeze
26
+ VERSION = "1.2.1".freeze
26
27
  end
27
28
 
28
29
 
@@ -32,141 +33,143 @@ end
32
33
  unless defined?(Rake)
33
34
  require "rake"
34
35
 
35
- class Application < Rake::Application #:nodoc:
36
-
37
- DEFAULT_BUILDFILES = ["buildfile", "Buildfile"] + DEFAULT_RAKEFILES
38
-
39
- OPTIONS = [ # :nodoc:
40
- ['--help', '-H', GetoptLong::NO_ARGUMENT,
41
- "Display this help message."],
42
- ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
43
- "Do not search parent directories for the buildfile."],
44
- ['--quiet', '-q', GetoptLong::NO_ARGUMENT,
45
- "Do not log messages to standard output."],
46
- ['--buildfile', '-f', GetoptLong::OPTIONAL_ARGUMENT,
47
- "Use FILE as the buildfile."],
48
- ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
49
- "Require MODULE before executing buildfile."],
50
- ['--trace', '-t', GetoptLong::NO_ARGUMENT,
51
- "Turn on invoke/execute tracing, enable full backtrace."],
52
- ['--verbose', '-v', GetoptLong::NO_ARGUMENT,
53
- "Log message to standard output (default)."],
54
- ['--version', '-V', GetoptLong::NO_ARGUMENT,
55
- "Display the program version."],
56
- ['--freeze', "-F", GetoptLong::NO_ARGUMENT,
57
- "Freezes the Buildfile so it always uses Buildr version #{Buildr::VERSION}"],
58
- ['--unfreeze', "-U", GetoptLong::NO_ARGUMENT,
59
- "Unfreezes the Buildfile to use the latest version of Buildr"]
60
- ]
61
-
62
- def initialize()
63
- super
64
- @rakefiles = DEFAULT_BUILDFILES
65
- end
66
-
67
- def run()
68
- standard_exception_handling do
36
+ module Buildr
37
+ class Application < Rake::Application #:nodoc:
38
+
39
+ DEFAULT_BUILDFILES = ["buildfile", "Buildfile"] + DEFAULT_RAKEFILES
40
+
41
+ OPTIONS = [ # :nodoc:
42
+ ['--help', '-H', GetoptLong::NO_ARGUMENT,
43
+ "Display this help message."],
44
+ ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
45
+ "Do not search parent directories for the buildfile."],
46
+ ['--quiet', '-q', GetoptLong::NO_ARGUMENT,
47
+ "Do not log messages to standard output."],
48
+ ['--buildfile', '-f', GetoptLong::OPTIONAL_ARGUMENT,
49
+ "Use FILE as the buildfile."],
50
+ ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
51
+ "Require MODULE before executing buildfile."],
52
+ ['--trace', '-t', GetoptLong::NO_ARGUMENT,
53
+ "Turn on invoke/execute tracing, enable full backtrace."],
54
+ ['--verbose', '-v', GetoptLong::NO_ARGUMENT,
55
+ "Log message to standard output (default)."],
56
+ ['--version', '-V', GetoptLong::NO_ARGUMENT,
57
+ "Display the program version."],
58
+ ['--freeze', "-F", GetoptLong::NO_ARGUMENT,
59
+ "Freezes the Buildfile so it always uses Buildr version #{Buildr::VERSION}"],
60
+ ['--unfreeze', "-U", GetoptLong::NO_ARGUMENT,
61
+ "Unfreezes the Buildfile to use the latest version of Buildr"]
62
+ ]
63
+
64
+ def initialize()
65
+ super
66
+ @rakefiles = DEFAULT_BUILDFILES
69
67
  @name = "Buildr"
70
68
  opts = GetoptLong.new(*command_line_options)
71
69
  opts.each { |opt, value| do_option(opt, value) }
72
70
  collect_tasks
73
- load_buildfile
74
- top_level
75
71
  end
76
- end
77
72
 
78
- def do_option(opt, value)
79
- case opt
80
- when '--help'
81
- help
82
- exit
83
- when "--buildfile"
84
- @rakefiles.clear
85
- @rakefiles << value
86
- when '--version'
87
- puts "Buildr, version #{Buildr::VERSION}"
88
- exit
89
- when "--freeze"
90
- find_buildfile
91
- puts "Freezing the Buildfile so it always uses Buildr version #{Buildr::VERSION}"
92
- gem =
93
- original = File.read(rakefile)
94
- if original =~ /gem\s*(["'])buildr\1/
95
- modified = original.sub(/gem\s*(["'])buildr\1\s*,\s*(["']).*\2/, %{gem "buildr", "#{Buildr::VERSION}"})
96
- else
97
- modified = %{gem "buildr", "#{Buildr::VERSION}"\n} + original
73
+ def run()
74
+ standard_exception_handling do
75
+ load_buildfile
76
+ top_level
98
77
  end
99
- File.open(rakefile, "w") { |file| file.write modified }
100
- exit
101
- when "--unfreeze"
102
- find_buildfile
103
- puts "Unfreezing the Buildfile to use the latest version of Buildr from your Gems repository."
104
- modified = File.read(rakefile).sub(/^\s*gem\s*(["'])buildr\1.*\n/, "")
105
- File.open(rakefile, "w") { |file| file.write modified }
106
- exit
107
- when '--require', "--nosearch", "--quiet", "--trace", "--verbose"
108
- super
109
78
  end
110
- end
111
79
 
112
- def find_buildfile()
113
- here = Dir.pwd
114
- while ! have_rakefile
115
- Dir.chdir("..")
116
- if Dir.pwd == here || options.nosearch
117
- error = "No Buildfile found (looking for: #{@rakefiles.join(', ')})"
118
- if STDIN.isatty
119
- if $terminal.agree("To use Buildr you need a buildfile. Do you want me to create one? (yes/no)")
120
- chdir(original_dir) { task("generate").invoke }
121
- end
122
- exit 1
80
+ def do_option(opt, value)
81
+ case opt
82
+ when '--help'
83
+ help
84
+ exit
85
+ when "--buildfile"
86
+ @rakefiles.clear
87
+ @rakefiles << value
88
+ when '--version'
89
+ puts "Buildr, version #{Buildr::VERSION}"
90
+ exit
91
+ when "--freeze"
92
+ find_buildfile
93
+ puts "Freezing the Buildfile so it always uses Buildr version #{Buildr::VERSION}"
94
+ gem =
95
+ original = File.read(rakefile)
96
+ if original =~ /gem\s*(["'])buildr\1/
97
+ modified = original.sub(/gem\s*(["'])buildr\1\s*,\s*(["']).*\2/, %{gem "buildr", "#{Buildr::VERSION}"})
123
98
  else
124
- raise error
99
+ modified = %{gem "buildr", "#{Buildr::VERSION}"\n} + original
125
100
  end
101
+ File.open(rakefile, "w") { |file| file.write modified }
102
+ exit
103
+ when "--unfreeze"
104
+ find_buildfile
105
+ puts "Unfreezing the Buildfile to use the latest version of Buildr from your Gems repository."
106
+ modified = File.read(rakefile).sub(/^\s*gem\s*(["'])buildr\1.*\n/, "")
107
+ File.open(rakefile, "w") { |file| file.write modified }
108
+ exit
109
+ when '--require', "--nosearch", "--quiet", "--trace", "--verbose"
110
+ super
126
111
  end
112
+ end
113
+
114
+ def find_buildfile()
127
115
  here = Dir.pwd
116
+ while ! have_rakefile
117
+ Dir.chdir("..")
118
+ if Dir.pwd == here || options.nosearch
119
+ error = "No Buildfile found (looking for: #{@rakefiles.join(', ')})"
120
+ if STDIN.isatty
121
+ if $terminal.agree("To use Buildr you need a buildfile. Do you want me to create one? (yes/no)")
122
+ chdir(original_dir) { task("generate").invoke }
123
+ end
124
+ exit 1
125
+ else
126
+ raise error
127
+ end
128
+ end
129
+ here = Dir.pwd
130
+ end
128
131
  end
129
- end
130
132
 
131
- def load_buildfile()
132
- find_buildfile
133
- puts "(in #{Dir.pwd})"
134
- load File.expand_path(@rakefile) if @rakefile != ''
135
- load_imports
136
- end
133
+ def load_buildfile()
134
+ find_buildfile
135
+ puts "(in #{Dir.pwd})"
136
+ load File.expand_path(@rakefile) if @rakefile != ''
137
+ load_imports
138
+ end
137
139
 
138
- def usage()
139
- puts "Buildr #{Buildr::VERSION}"
140
- puts
141
- puts "Usage:"
142
- puts " buildr [-f buildfile] {options} targets..."
143
- end
140
+ def usage()
141
+ puts "Buildr #{Buildr::VERSION}"
142
+ puts
143
+ puts "Usage:"
144
+ puts " buildr [-f buildfile] {options} targets..."
145
+ end
144
146
 
145
- def help()
146
- usage
147
- puts
148
- puts "Options:"
149
- OPTIONS.sort.each do |long, short, mode, desc|
150
- if mode == GetoptLong::REQUIRED_ARGUMENT
151
- if desc =~ /\b([A-Z]{2,})\b/
152
- long = long + "=#{$1}"
147
+ def help()
148
+ usage
149
+ puts
150
+ puts "Options:"
151
+ OPTIONS.sort.each do |long, short, mode, desc|
152
+ if mode == GetoptLong::REQUIRED_ARGUMENT
153
+ if desc =~ /\b([A-Z]{2,})\b/
154
+ long = long + "=#{$1}"
155
+ end
153
156
  end
157
+ printf " %-20s (%s)\n", long, short
158
+ printf " %s\n", desc
154
159
  end
155
- printf " %-20s (%s)\n", long, short
156
- printf " %s\n", desc
160
+ puts
161
+ puts "For help with your buildfile:"
162
+ puts " buildr help"
163
+ end
164
+
165
+ def command_line_options
166
+ OPTIONS.collect { |lst| lst[0..-2] }
157
167
  end
158
- puts
159
- puts "For help with your buildfile:"
160
- puts " buildr help"
161
- end
162
168
 
163
- def command_line_options
164
- OPTIONS.collect { |lst| lst[0..-2] }
165
169
  end
166
170
 
171
+ Rake.application = Application.new
167
172
  end
168
-
169
- Rake.application = Application.new
170
173
  end
171
174
 
172
175
 
@@ -12,7 +12,8 @@ module Buildr
12
12
  :dom4j => "dom4j:dom4j:jar:1.6.1",
13
13
  :hibernate => "org.hibernate:hibernate:jar:3.1.2",
14
14
  :xdoclet => Buildr.group("xdoclet", "xdoclet-xdoclet-module", "xdoclet-hibernate-module",
15
- :under=>"xdoclet", :version=>"1.2.3") + ["xdoclet:xjavadoc:jar:1.1-j5"]
15
+ # :under=>"xdoclet", :version=>"1.2.3") + ["xdoclet:xjavadoc:jar:1.1-j5"]
16
+ :under=>"xdoclet", :version=>"1.2.3") + ["xdoclet:xjavadoc:jar:1.1"]
16
17
  )
17
18
 
18
19
  class << self
@@ -50,10 +51,10 @@ module Buildr
50
51
  # :drop=>"no", :create=>"yes", :output=>target) do
51
52
  # fileset :dir=>source.to_s, :includes=>"**/*.hbm.xml"
52
53
  # end
53
- def schemaexport(options = nil, &block)
54
+ def schemaexport(options = nil)
54
55
  ant "schemaexport" do |ant|
55
56
  ant.taskdef :name=>"schemaexport", :classname=>"org.hibernate.tool.hbm2ddl.SchemaExportTask", :classpath=>requires
56
- ant.schemaexport options, &block if options
57
+ ant.schemaexport(options) { yield ant if block_given? } if options
57
58
  end
58
59
  end
59
60
 
@@ -7,6 +7,23 @@ require "uri/open-sftp"
7
7
 
8
8
  class Hash
9
9
 
10
+ class << self
11
+
12
+ # :call-seq:
13
+ # Hash.from_java_properties(string)
14
+ #
15
+ # Returns a hash from a string in the Java properties file format. For example:
16
+ # str = "foo=bar\nbaz=fab"
17
+ # Hash.from_properties(str)
18
+ # => { "foo"=>"bar", "baz"=>"fab" }.to_properties
19
+ def from_java_properties(string)
20
+ string.gsub(/\\\n/, "").split("\n").select { |line| line =~ /^[^#].*=.*/ }.
21
+ map { |line| line.gsub(/\\[trnf\\]/) { |escaped| {?t=>"\t", ?r=>"\r", ?n=>"\n", ?f=>"\f", ?\\=>"\\"}[escaped[1]] } }.
22
+ inject({}) { |hash, line| name, value = line.split("=") ; hash[name] = value ; hash }
23
+ end
24
+
25
+ end
26
+
10
27
  # :call-seq:
11
28
  # only(keys*) => hash
12
29
  #
@@ -32,6 +49,20 @@ class Hash
32
49
  self.inject({}) { |hash, pair| hash[pair[0]] = pair[1] unless keys.include?(pair[0]) ; hash }
33
50
  end
34
51
 
52
+ # :call-seq:
53
+ # to_java_properties() => string
54
+ #
55
+ # Convert hash to string format used for Java properties file. For example:
56
+ # { "foo"=>"bar", "baz"=>"fab" }.to_properties
57
+ # => foo=bar
58
+ # baz=fab
59
+ def to_java_properties()
60
+ keys.sort.map { |key|
61
+ value = self[key].gsub(/[\t\r\n\f\\]/) { |escape| "\\" + {"\t"=>"t", "\r"=>"r", "\n"=>"n", "\f"=>"f", "\\"=>"\\"}[escape] }
62
+ "#{key}=#{value}"
63
+ }.join("\n")
64
+ end
65
+
35
66
  end
36
67
 
37
68
 
@@ -44,17 +75,75 @@ module Buildr
44
75
  # options.java_args = "-Xmx512M"
45
76
  class Options
46
77
 
78
+ # We use this to present environment variable as arrays.
79
+ class EnvArray < Array #:nodoc:
80
+
81
+ def initialize(name)
82
+ @name = name.upcase
83
+ replace((ENV[@name] || ENV[@name.downcase] || "").split(/\s*,\s*/).reject(&:empty?))
84
+ end
85
+
86
+ (Array.instance_methods - Object.instance_methods - Enumerable.instance_methods).sort.each do |method|
87
+ class_eval %{def #{method}(*args, &block) ; result = super ; write ; result ; end}
88
+ end
89
+
90
+ private
91
+
92
+ def write()
93
+ ENV[@name.downcase] = nil
94
+ ENV[@name] = map(&:to_s).join(",")
95
+ end
96
+
97
+ end
98
+
99
+ # Wraps around the proxy environment variables:
100
+ # * :http -- HTTP_PROXY
101
+ # * :exclude -- NO_PROXY
102
+ class Proxies
103
+
104
+ # Returns the HTTP_PROXY URL.
105
+ def http()
106
+ ENV["HTTP_PROXY"] || ENV["http_proxy"]
107
+ end
108
+
109
+ # Sets the HTTP_PROXY URL.
110
+ def http=(url)
111
+ ENV["http_proxy"] = nil
112
+ ENV["HTTP_PROXY"] = url
113
+ end
114
+
115
+ # Returns list of hosts to exclude from proxying (NO_PROXY).
116
+ def exclude()
117
+ @exclude ||= EnvArray.new("NO_PROXY")
118
+ end
119
+
120
+ # Sets list of hosts to exclude from proxy (NO_PROXY). Accepts host name, array of names,
121
+ # or nil to clear the list.
122
+ def exclude=(url)
123
+ exclude.clear
124
+ exclude.concat [url].flatten if url
125
+ exclude
126
+ end
127
+
128
+ end
129
+
47
130
  # :call-seq:
48
131
  # proxy() => options
49
132
  #
50
133
  # Returns the proxy options. Currently supported options are:
51
134
  # * :http -- HTTP proxy for use when downloading.
135
+ # * :exclude -- Do not use proxy for these hosts/domains.
52
136
  #
53
137
  # For example:
54
138
  # options.proxy.http = "http://proxy.acme.com:8080"
55
139
  # You can also set it using the environment variable HTTP_PROXY.
140
+ #
141
+ # You can exclude individual hosts from being proxied, or entire domains, for example:
142
+ # options.proxy.exclude = "optimus"
143
+ # options.proxy.exclude = ["optimus", "prime"]
144
+ # options.proxy.exclude << "*.internal"
56
145
  def proxy()
57
- @proxy ||= Struct.new(:http).new(ENV['HTTP_PROXY'] || ENV['http_proxy'])
146
+ @proxy ||= Proxies.new
58
147
  end
59
148
 
60
149
  end
@@ -191,26 +280,45 @@ module Buildr
191
280
  # Without any mapping, the filter simply copies files from the source directory into the target
192
281
  # directory.
193
282
  #
283
+ # A filter has one target directory, but you can specify any number of source directories,
284
+ # either when creating the filter or calling #from. Include/exclude patterns are specified
285
+ # relative to the source directories, so:
286
+ # filter.include "*.png"
287
+ # will only include PNG files from any of the source directories.
288
+ #
194
289
  # See Buildr#filter.
195
290
  class Filter
196
291
 
197
292
  def initialize() #:nodoc:
198
293
  @include = []
199
294
  @exclude = []
295
+ @sources = []
200
296
  end
201
297
 
202
- # The source directory as a file task.
203
- attr_accessor :source
298
+ # Returns the list of source directories (each being a file task).
299
+ attr_reader :sources
300
+
301
+ # *Deprecated* Use #sources instead.
302
+ def source()
303
+ warn_deprecated "Please use sources instead."
304
+ @sources.first
305
+ end
204
306
 
307
+ # *Deprecated* Use #from instead.
308
+ def source=(dir)
309
+ warn_deprecated "Please use from instead."
310
+ from(dir)
311
+ end
312
+
205
313
  # :call-seq:
206
- # from(dir) => self
314
+ # from(*sources) => self
207
315
  #
208
- # Sets the source directory from which files are copied and returns self.
316
+ # Adds additional directories from which to copy resources.
209
317
  #
210
318
  # For example:
211
319
  # filter.from("src").into("target").using("build"=>Time.now)
212
- def from(dir)
213
- @source = file(File.expand_path(dir.to_s))
320
+ def from(*sources)
321
+ @sources |= sources.flatten.map { |dir| file(File.expand_path(dir.to_s)) }
214
322
  self
215
323
  end
216
324
 
@@ -277,35 +385,40 @@ module Buildr
277
385
  #
278
386
  # Runs the filter.
279
387
  def run()
280
- raise "No source directory specified, where am I going to find the files to filter?" if source.nil?
281
- raise "Source directory #{source} doesn't exist" unless File.exist?(source.to_s)
388
+ raise "No source directory specified, where am I going to find the files to filter?" if sources.empty?
389
+ sources.each { |source| raise "Source directory #{source} doesn't exist" unless File.exist?(source.to_s) }
282
390
  raise "No target directory specified, where am I going to copy the files to?" if target.nil?
283
391
 
284
- includes = @include.empty? ? ["*"] : @include
285
- src_base = Pathname.new(source.to_s)
286
- copy_map = Dir[File.join(source.to_s, "**/*")].reject { |file| File.directory?(file) }.
287
- map { |src| Pathname.new(src).relative_path_from(src_base).to_s }.
288
- select { |file| includes.any? { |pattern| File.fnmatch(pattern, file) } }.
289
- reject { |file| @exclude.any? { |pattern| File.fnmatch(pattern, file) } }.
290
- map { |file| [File.expand_path(file, target.to_s), File.expand_path(file, source.to_s)] }.
291
- select { |dest, src| !File.exist?(dest) || File.stat(src).mtime > File.stat(dest).mtime }
392
+ copy_map = sources.flatten.map(&:to_s).inject({}) do |map, source|
393
+ base = Pathname.new(source)
394
+ files = FileList[File.join(source, "**/*")].reject { |file| File.directory?(file) }.
395
+ map { |file| Pathname.new(file).relative_path_from(base).to_s }.
396
+ select { |file| @include.empty? || @include.any? { |pattern| File.fnmatch(pattern, file) } }.
397
+ reject { |file| @exclude.any? { |pattern| File.fnmatch(pattern, file) } }
398
+ files.each do |file|
399
+ src, dest = File.expand_path(file, source), File.expand_path(file, target.to_s)
400
+ map[file] = src if !File.exist?(dest) || File.stat(src).mtime > File.stat(dest).mtime
401
+ end
402
+ map
403
+ end
404
+
292
405
  return false if copy_map.empty?
293
406
 
294
407
  verbose(Rake.application.options.trace || false) do
295
408
  mkpath target.to_s
296
- copy_map.each do |dest, src|
409
+ copy_map.each do |path, source|
410
+ dest = File.expand_path(path, target.to_s)
297
411
  mkpath File.dirname(dest) rescue nil
298
412
  case mapping
299
413
  when Proc, Method # Call on input, accept output.
300
- relative = Pathname.new(src).relative_path_from(src_base).to_s
301
- mapped = mapping.call(relative, File.open(src, "rb") { |file| file.read })
414
+ mapped = mapping.call(path, File.open(source, "rb") { |file| file.read })
302
415
  File.open(dest, "wb") { |file| file.write mapped }
303
416
  when Hash # Map ${key} to value
304
- mapped = File.open(src, "rb") { |file| file.read }.
417
+ mapped = File.open(source, "rb") { |file| file.read }.
305
418
  gsub(/\$\{[^}]*\}/) { |str| mapping[str[2..-2]] || str }
306
419
  File.open(dest, "wb") { |file| file.write mapped }
307
420
  when nil # No mapping.
308
- cp src, dest
421
+ cp source, dest
309
422
  else
310
423
  fail "Filter can be a hash (key=>value), or a proc/method; I don't understand #{mapping}"
311
424
  end
@@ -323,9 +436,9 @@ module Buildr
323
436
  end
324
437
 
325
438
  # :call-seq:
326
- # filter(source) => Filter
439
+ # filter(*source) => Filter
327
440
  #
328
- # Creates a filter that will copy files from the source directory into the target directory.
441
+ # Creates a filter that will copy files from the source directory(ies) into the target directory.
329
442
  # You can extend the filter to modify files by mapping <tt>${key}</tt> into values in each
330
443
  # of the copied files, and by including or excluding specific files.
331
444
  #
@@ -336,8 +449,8 @@ module Buildr
336
449
  # To include only the text files, and replace each instance of <tt>${build}</tt> with the current
337
450
  # date/time:
338
451
  # filter("src/files").into("target/classes").include("*.txt").using("build"=>Time.now).run
339
- def filter(source)
340
- Filter.new.from(source)
452
+ def filter(*sources)
453
+ Filter.new.from(*sources)
341
454
  end
342
455
 
343
456
  end
@@ -56,7 +56,6 @@ module URI
56
56
  # File.open("image.jpg", "w") { |file| file.write URI.read("http://example.com/image.jpg") }
57
57
  #
58
58
  # Supported options:
59
- # * :proxy -- Collection of proxy settings, accessed by scheme.
60
59
  # * :modified -- Only download if file modified since this timestamp. Returns nil if not modified.
61
60
  # * :progress -- Show the progress bar while reading.
62
61
  def read(uri, options = nil, &block)
@@ -94,7 +93,6 @@ module URI
94
93
  # write "sftp://localhost/jars/killer-app.jar", File.read("killer-app.jar")
95
94
  #
96
95
  # Supported options:
97
- # * :proxy -- Collection of proxy settings, accessed by scheme.
98
96
  # * :progress -- Show the progress bar while reading.
99
97
  def write(uri, *args, &block)
100
98
  uri = URI.parse(uri.to_s) unless URI === uri
@@ -176,7 +174,19 @@ module URI
176
174
  #
177
175
  # For options, see URI::write.
178
176
  def write(*args, &block)
179
- fail "This protocol doesn't support writing (yet, how about helping by implementing it?)"
177
+ options = args.pop if Hash === args.last
178
+ options ||= {}
179
+ if String === args.first
180
+ ios = StringIO.new(args.first, "r")
181
+ write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
182
+ elsif args.first.respond_to?(:read)
183
+ size = args.first.size rescue nil
184
+ write({:size=>size}.merge(options)) { |bytes| args.first.read(bytes) }
185
+ elsif args.empty? && block
186
+ write_internal options, &block
187
+ else
188
+ raise ArgumentError, "Either give me the content, or pass me a block, otherwise what would I upload?"
189
+ end
180
190
  end
181
191
 
182
192
  # :call-seq:
@@ -274,8 +284,26 @@ module URI
274
284
  end
275
285
  end
276
286
 
287
+ # :call-seq:
288
+ # proxy_uri() => URI?
289
+ #
290
+ # Returns the proxy server to use. Obtains the proxy from the relevant environment variable (e.g. HTTP_PROXY).
291
+ # Supports exclusions based on host name and port number from environment variable NO_PROXY.
292
+ def proxy_uri()
293
+ proxy = ENV["#{scheme.upcase}_PROXY"]
294
+ proxy = URI.parse(proxy) if String === proxy
295
+ excludes = (ENV["NO_PROXY"] || "").split(/\s*,\s*/).compact
296
+ excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
297
+ return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
298
+ end
299
+
300
+ def write_internal(options, &block) #:nodoc:
301
+ fail "This protocol doesn't support writing (yet, how about helping by implementing it?)"
302
+ end
303
+
277
304
  end
278
305
 
306
+
279
307
  class HTTP #:nodoc:
280
308
 
281
309
  # See URI::Generic#read
@@ -322,8 +350,7 @@ module URI
322
350
  end
323
351
  end
324
352
 
325
- proxy = options[:proxy] && options[:proxy].http
326
- if proxy
353
+ if proxy = proxy_uri
327
354
  proxy = URI.parse(proxy) if String === proxy
328
355
  Net::HTTP.start(host, port, proxy.host, proxy.port, proxy.user, proxy.password) { |http| request[http] }
329
356
  else
@@ -334,6 +361,7 @@ module URI
334
361
 
335
362
  end
336
363
 
364
+
337
365
  class SFTP #:nodoc:
338
366
 
339
367
  class << self
@@ -343,65 +371,53 @@ module URI
343
371
  end
344
372
  end
345
373
 
346
- # See URI::Generic#write
347
- def write(*args, &block)
348
- options = args.pop if Hash === args.last
349
- options ||= {}
350
- if String === args.first
351
- ios = StringIO.new(args.first, "r")
352
- write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
353
- elsif args.first.respond_to?(:read)
354
- size = args.first.size rescue nil
355
- write({:size=>size}.merge(options)) { |bytes| args.first.read(bytes) }
356
- elsif args.empty? && block
374
+ protected
357
375
 
358
- # SSH options are based on the username/password from the URI.
359
- ssh_options = { :port=>port, :username=>user }.merge(options[:ssh_options] || {})
360
- ssh_options[:password] ||= SFTP.passwords[host]
361
- begin
362
- puts "Connecting to #{host}" if Rake.application.options.trace
363
- session = Net::SSH.start(host, ssh_options)
364
- SFTP.passwords[host] = ssh_options[:password]
365
- rescue Net::SSH::AuthenticationFailed=>ex
366
- # Only if running with console, prompt for password.
367
- if !ssh_options[:password] && $stdout.isatty
368
- password = HighLine.new.ask("Password for #{host}:") { |q| q.echo = "*" }
369
- ssh_options[:password] = password
370
- retry
371
- end
372
- raise
376
+ def write_internal(options, &block) #:nodoc:
377
+ # SSH options are based on the username/password from the URI.
378
+ ssh_options = { :port=>port, :username=>user }.merge(options[:ssh_options] || {})
379
+ ssh_options[:password] ||= SFTP.passwords[host]
380
+ begin
381
+ puts "Connecting to #{host}" if Rake.application.options.trace
382
+ session = Net::SSH.start(host, ssh_options)
383
+ SFTP.passwords[host] = ssh_options[:password]
384
+ rescue Net::SSH::AuthenticationFailed=>ex
385
+ # Only if running with console, prompt for password.
386
+ if !ssh_options[:password] && $stdout.isatty
387
+ password = HighLine.new.ask("Password for #{host}:") { |q| q.echo = "*" }
388
+ ssh_options[:password] = password
389
+ retry
373
390
  end
391
+ raise
392
+ end
374
393
 
375
- session.sftp.connect do |sftp|
376
- puts "connected" if Rake.application.options.trace
394
+ session.sftp.connect do |sftp|
395
+ puts "connected" if Rake.application.options.trace
377
396
 
378
- # To create a path, we need to create all its parent. We use realpath to determine if
379
- # the path already exists, otherwise mkdir fails.
380
- puts "Creating path #{@base_path}" if Rake.application.options.trace
381
- path.split("/").inject("") do |base, part|
382
- combined = base + part
383
- sftp.realpath combined rescue sftp.mkdir combined, {}
384
- "#{combined}/"
385
- end
397
+ # To create a path, we need to create all its parent. We use realpath to determine if
398
+ # the path already exists, otherwise mkdir fails.
399
+ puts "Creating path #{@base_path}" if Rake.application.options.trace
400
+ path.split("/").inject("") do |base, part|
401
+ combined = base + part
402
+ sftp.realpath combined rescue sftp.mkdir combined, {}
403
+ "#{combined}/"
404
+ end
386
405
 
387
- with_progress_bar options[:progress] && options[:size], path.split("/"), options[:size] || 0 do |progress|
388
- puts "Uploading to #{path}" if Rake.application.options.trace
389
- sftp.open_handle(path, "w") do |handle|
390
- # Writing in chunks gives us the benefit of a progress bar,
391
- # but also require that we maintain a position in the file,
392
- # since write() with two arguments always writes at position 0.
393
- pos = 0
394
- while chunk = yield(32 * 4096)
395
- sftp.write(handle, chunk, pos)
396
- pos += chunk.size
397
- progress << chunk
398
- end
399
- sftp.setstat(target_path, :permissions => options[:permissions]) if options[:permissions]
406
+ with_progress_bar options[:progress] && options[:size], path.split("/"), options[:size] || 0 do |progress|
407
+ puts "Uploading to #{path}" if Rake.application.options.trace
408
+ sftp.open_handle(path, "w") do |handle|
409
+ # Writing in chunks gives us the benefit of a progress bar,
410
+ # but also require that we maintain a position in the file,
411
+ # since write() with two arguments always writes at position 0.
412
+ pos = 0
413
+ while chunk = yield(32 * 4096)
414
+ sftp.write(handle, chunk, pos)
415
+ pos += chunk.size
416
+ progress << chunk
400
417
  end
418
+ sftp.setstat(path, :permissions => options[:permissions]) if options[:permissions]
401
419
  end
402
420
  end
403
- else
404
- raise ArgumentError, "Either give me the content, or pass me a block, otherwise what would I upload?"
405
421
  end
406
422
  end
407
423
 
@@ -452,38 +468,6 @@ module URI
452
468
  end
453
469
  end
454
470
 
455
- # See URI::Generic#write
456
- def write(*args, &block)
457
- options = args.pop if Hash === args.last
458
- options ||= {}
459
- 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>." unless host.blank?
460
-
461
- if String === args.first
462
- ios = StringIO.new(args.first, "r")
463
- write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
464
- elsif args.first.respond_to?(:read)
465
- size = args.first.size rescue nil
466
- write({:size=>size}.merge(options)) { |bytes| args.first.read(bytes) }
467
- elsif args.empty? && block
468
- temp = nil
469
- Tempfile.open File.basename(path) do |temp|
470
- temp.binmode
471
- with_progress_bar options[:progress] && options[:size], path.split("/"), options[:size] || 0 do |progress|
472
- while chunk = yield(32 * 4096)
473
- temp.write chunk
474
- progress << chunk
475
- end
476
- end
477
- end
478
- real_path.tap do |path|
479
- mkpath File.dirname(path)
480
- File.move temp.path, path
481
- end
482
- else
483
- raise ArgumentError, "Either give me the content, or pass me a block, otherwise what would I upload?"
484
- end
485
- end
486
-
487
471
  def to_s()
488
472
  "file://#{host}#{path}"
489
473
  end
@@ -495,6 +479,26 @@ module URI
495
479
  RUBY_PLATFORM =~ /win32/ && path =~ /^\/[a-zA-Z]:\// ? path[1..-1] : path
496
480
  end
497
481
 
482
+ protected
483
+
484
+ def write_internal(options, &block) #:nodoc:
485
+ 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>." unless host.blank?
486
+ temp = nil
487
+ Tempfile.open File.basename(path) do |temp|
488
+ temp.binmode
489
+ with_progress_bar options[:progress] && options[:size], path.split("/"), options[:size] || 0 do |progress|
490
+ while chunk = yield(32 * 4096)
491
+ temp.write chunk
492
+ progress << chunk
493
+ end
494
+ end
495
+ end
496
+ real_path.tap do |path|
497
+ mkpath File.dirname(path)
498
+ File.move temp.path, path
499
+ end
500
+ end
501
+
498
502
  @@schemes["FILE"] = FILE
499
503
 
500
504
  end
@@ -100,7 +100,7 @@ module Buildr
100
100
  # In the first form, uses the upload options specified by repositories.release_to.
101
101
  # In the second form, uses a URL that includes all the relevant information.
102
102
  # In the third form, uses a hash with the options :url, :username, :password,
103
- # :proxy and :permissions. All but :url are optional.
103
+ # and :permissions. All but :url are optional.
104
104
  def upload(upload_to = nil)
105
105
  # Where do we release to?
106
106
  upload_to ||= Buildr.repositories.release_to
@@ -117,7 +117,7 @@ module Buildr
117
117
  # Upload artifact relative to base URL, need to create path before uploading.
118
118
  puts "Deploying #{to_spec}" if verbose
119
119
  path = group.gsub(".", "/") + "/#{id}/#{version}/#{File.basename(name)}"
120
- URI.upload uri + path, name, :proxy=>Buildr.options.proxy, :permissions=>upload_to[:permissions]
120
+ URI.upload uri + path, name, :permissions=>upload_to[:permissions]
121
121
  end
122
122
 
123
123
  protected
@@ -275,7 +275,7 @@ module Buildr
275
275
  begin
276
276
  path = group.gsub(".", "/") + "/#{id}/#{version}/#{File.basename(name)}"
277
277
  mkpath File.dirname(name), :verbose=>false
278
- URI.download repo_url + path, name, :proxy=>Buildr.options.proxy
278
+ URI.download repo_url + path, name
279
279
  true
280
280
  rescue URI::NotFoundError
281
281
  false
@@ -396,8 +396,8 @@ module Buildr
396
396
  mkpath File.dirname(filename), :verbose=>false
397
397
  # We absolutely need the POM, so make sure we download it before the artifact
398
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
399
+ URI.download repo_url + path.ext("pom"), filename.ext("pom") unless type == :pom
400
+ URI.download repo_url + path, filename
401
401
  true
402
402
  rescue URI::NotFoundError
403
403
  false
@@ -584,13 +584,13 @@ module Buildr
584
584
  puts "Deploying #{arg.to_spec}" if verbose
585
585
  spec = arg.to_spec_hash
586
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]
587
+ URI.upload uri + path, arg.to_s, :permissions=>deploy_to[:permissions]
588
588
  else
589
589
  # Upload file to URL.
590
590
  puts "Deploying #{arg}" if verbose
591
591
  path = File.basename(args.to_s)
592
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]
593
+ URI.upload uri + path, arg.to_s, :permissions=>deploy_to[:permissions]
594
594
  end
595
595
  end
596
596
  end
@@ -255,7 +255,7 @@ module Buildr
255
255
  def initialize(*args) #:nodoc:
256
256
  super
257
257
  @filter = Buildr::Filter.new
258
- enhance { filter.run if filter.source && filter.target }
258
+ enhance { filter.run unless filter.sources.empty? }
259
259
  end
260
260
 
261
261
  # :call-seq:
@@ -277,13 +277,28 @@ module Buildr
277
277
  end
278
278
 
279
279
  # :call-seq:
280
- # source() => task
280
+ # from(*sources) => self
281
+ #
282
+ # Adds additional directories from which to copy resources.
281
283
  #
282
- # Returns the filter's source directory as a file task.
284
+ # For example:
285
+ # resources.from _("src/etc")
286
+ def from(*sources)
287
+ filter.from *sources
288
+ self
289
+ end
290
+
291
+ # *Deprecated* Use #sources instead.
283
292
  def source()
293
+ warn_deprecated "Please use sources instead."
284
294
  filter.source
285
295
  end
286
296
 
297
+ # Returns the list of source directories (each being a file task).
298
+ def sources()
299
+ filter.sources
300
+ end
301
+
287
302
  # :call-seq:
288
303
  # target() => task
289
304
  #
@@ -293,7 +308,7 @@ module Buildr
293
308
  end
294
309
 
295
310
  def prerequisites() #:nodoc:
296
- super + [filter.source].compact
311
+ super + filter.sources.flatten
297
312
  end
298
313
 
299
314
  end
@@ -499,7 +514,7 @@ module Buildr
499
514
  # can access by calling resources.filter (see Buildr::Filter).
500
515
  #
501
516
  # For example:
502
- # resources.filter.include "config.xml"
517
+ # resources.from _("src/etc")
503
518
  # resources.filter.using "Copyright"=>"Acme Inc, 2007"
504
519
  def resources(*prereqs, &block)
505
520
  task("resources").enhance prereqs, &block
@@ -528,7 +543,7 @@ module Buildr
528
543
  prepare = task("prepare")
529
544
  # Resources task is a filter.
530
545
  resources = Java::ResourcesTask.define_task("resources")
531
- project.path_to("src/main/resources").tap { |dir| resources.filter.from dir if File.exist?(dir) }
546
+ project.path_to("src/main/resources").tap { |dir| resources.from dir if File.exist?(dir) }
532
547
  # Compile task requires prepare and performs resources, if anything compiled.
533
548
  compile = Java::CompileTask.define_task("compile"=>[prepare, resources])
534
549
  project.path_to("src/main/java").tap { |dir| compile.from dir if File.exist?(dir) }
@@ -552,18 +567,21 @@ module Buildr
552
567
 
553
568
  class Options
554
569
 
555
- # Runs the compile in debugging mode when true (default).
570
+ # Returns the debug option (environment variable DEBUG).
571
+ def debug()
572
+ (ENV["DEBUG"] || ENV["debug"]) !~ /(no|off|false)/
573
+ end
574
+
575
+ # Sets the debug option (environment variable DEBUG).
556
576
  #
557
577
  # You can turn this option off directly, or by setting the environment variable
558
578
  # DEBUG to "no". For example:
559
579
  # buildr build DEBUG=no
560
580
  #
561
581
  # The release tasks runs a build with <tt>DEBUG=no</tt>.
562
- attr_accessor :debug
563
-
564
- def debug() #:nodoc:
565
- @debug = (ENV["DEBUG"] || ENV["debug"]) !~ /(no|off|false)/ if @debug.nil?
566
- @debug
582
+ def debug=(flag)
583
+ ENV["debug"] = nil
584
+ ENV["DEBUG"] = flag.to_s
567
585
  end
568
586
 
569
587
  end
@@ -36,7 +36,7 @@ module Buildr
36
36
  excludes = [ '**/.svn/', '**/CVS/' ].join('|')
37
37
 
38
38
  # Only for projects that are packageable.
39
- task_name = project.path_to("#{project.name.sub(':', '-')}.iml")
39
+ task_name = project.path_to("#{project.name.gsub(':', '-')}.iml")
40
40
  idea.enhance [ file(task_name) ]
41
41
 
42
42
  # The only thing we need to look for is a change in the Buildfile.
@@ -123,7 +123,7 @@ module Buildr
123
123
 
124
124
  # Root project aggregates all the subprojects.
125
125
  if project.parent == nil
126
- task_name = project.path_to("#{project.name.sub(':', '-')}.ipr")
126
+ task_name = project.path_to("#{project.name.gsub(':', '-')}.ipr")
127
127
  idea.enhance [ file(task_name) ]
128
128
 
129
129
  file(task_name=>sources) do |task|
@@ -136,7 +136,8 @@ module Buildr
136
136
  xml.modules do
137
137
  project.projects.each do |subp|
138
138
  module_name = subp.name.gsub(":", "-")
139
- module_path = subp.name[/:(.*)/][1..-1]
139
+ module_path = subp.name.split(":"); module_path.shift
140
+ module_path = module_path.join("/")
140
141
  path = "#{module_path}/#{module_name}.iml"
141
142
  xml.module :fileurl=>"file://$PROJECT_DIR$/#{path}", :filepath=>"$PROJECT_DIR$/#{path}"
142
143
  end
@@ -586,7 +586,7 @@ module Buildr
586
586
  #project.recursive_task("test")
587
587
  # Similar to the regular resources task but using different paths.
588
588
  resources = Java::ResourcesTask.define_task("test:resources")
589
- project.path_to("src/test/resources").tap { |dir| resources.filter.from dir if File.exist?(dir) }
589
+ project.path_to("src/test/resources").tap { |dir| resources.from dir if File.exist?(dir) }
590
590
  # Similar to the regular compile task but using different paths.
591
591
  compile = Java::CompileTask.define_task("test:compile"=>[project.compile, task("test:prepare"), project.test.resources])
592
592
  project.path_to("src/test/java").tap { |dir| compile.from dir if File.exist?(dir) }
@@ -620,26 +620,37 @@ module Buildr
620
620
  # Set to false to not run any test cases. Set to :all to run all test cases, ignoring failures.
621
621
  #
622
622
  # This option is set from the environment variable "test", so you can also do:
623
- # buildr # With tests
624
- # buildr test=no # Without tests
625
- # buildr test=all # Ignore failures
626
- attr_accessor :test
627
-
628
- def test() #:nodoc:
629
- if @test.nil?
630
- case value = ENV["TEST"] || ENV["test"]
631
- when /^(no|off|false|skip)$/i
632
- @test = false
633
- when /^all$/i
634
- @test = :all
635
- when /^(yes|on|true)$/i, nil
636
- @test = true
637
- else
638
- warn "Expecting the environment variable test to be 'no' or 'all', not sure what to do with #{value}, so I'm just going to run all the test cases and stop at failure."
639
- @test = true
640
- end
623
+
624
+ # Returns the test option (environment variable TEST). Possible values are:
625
+ # * :false -- Do not run any test cases (also accepts "no" and "skip").
626
+ # * :true -- Run all test cases, stop on failure (default if not set).
627
+ # * :all -- Run all test cases, ignore failures.
628
+ def test()
629
+ case value = ENV["TEST"] || ENV["test"]
630
+ when /^(no|off|false|skip)$/i
631
+ false
632
+ when /^all$/i
633
+ :all
634
+ when /^(yes|on|true)$/i, nil
635
+ true
636
+ else
637
+ warn "Expecting the environment variable test to be 'no' or 'all', not sure what to do with #{value}, so I'm just going to run all the test cases and stop at failure."
638
+ true
641
639
  end
642
- @test
640
+ end
641
+
642
+ # Sets the test option (environment variable TEST). Possible values are true, false or :all.
643
+ #
644
+ # You can also set this from the environment variable, e.g.:
645
+ #
646
+ # buildr # With tests
647
+ # buildr test=no # Without tests
648
+ # buildr test=all # Ignore failures
649
+ # set TEST=no
650
+ # buildr # Without tests
651
+ def test=(flag)
652
+ ENV["test"] = nil
653
+ ENV["TEST"] = flag.to_s
643
654
  end
644
655
 
645
656
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: buildr
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.0
7
- date: 2007-07-06 00:00:00 -07:00
6
+ version: 1.2.1
7
+ date: 2007-07-12 00:00:00 -07:00
8
8
  summary: A build system that doesn't suck
9
9
  require_paths:
10
10
  - lib