buildr 1.2.10 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/CHANGELOG +566 -268
  2. data/DISCLAIMER +7 -1
  3. data/KEYS +151 -0
  4. data/NOTICE +23 -8
  5. data/README +122 -22
  6. data/Rakefile +49 -229
  7. data/{lib → addon}/buildr/antlr.rb +23 -10
  8. data/addon/buildr/cobertura.rb +232 -0
  9. data/{lib → addon}/buildr/hibernate.rb +20 -4
  10. data/{lib → addon}/buildr/javacc.rb +27 -12
  11. data/addon/buildr/jdepend.rb +60 -0
  12. data/{lib → addon}/buildr/jetty.rb +34 -18
  13. data/addon/buildr/nailgun.rb +892 -0
  14. data/{lib → addon}/buildr/openjpa.rb +23 -6
  15. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  16. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  17. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  18. data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
  19. data/{lib → addon}/buildr/xmlbeans.rb +39 -14
  20. data/bin/buildr +21 -7
  21. data/buildr.gemspec +50 -0
  22. data/doc/css/default.css +225 -0
  23. data/doc/css/print.css +95 -0
  24. data/doc/css/syntax.css +43 -0
  25. data/doc/images/apache-incubator-logo.png +0 -0
  26. data/doc/images/buildr-hires.png +0 -0
  27. data/doc/images/buildr.png +0 -0
  28. data/doc/images/note.png +0 -0
  29. data/doc/images/tip.png +0 -0
  30. data/doc/images/zbuildr.tif +0 -0
  31. data/doc/pages/artifacts.textile +317 -0
  32. data/doc/pages/building.textile +501 -0
  33. data/doc/pages/contributing.textile +178 -0
  34. data/doc/pages/download.textile +25 -0
  35. data/doc/pages/extending.textile +229 -0
  36. data/doc/pages/getting_started.textile +337 -0
  37. data/doc/pages/index.textile +63 -0
  38. data/doc/pages/mailing_lists.textile +17 -0
  39. data/doc/pages/more_stuff.textile +367 -0
  40. data/doc/pages/packaging.textile +592 -0
  41. data/doc/pages/projects.textile +449 -0
  42. data/doc/pages/recipes.textile +127 -0
  43. data/doc/pages/settings_profiles.textile +339 -0
  44. data/doc/pages/testing.textile +475 -0
  45. data/doc/pages/troubleshooting.textile +121 -0
  46. data/doc/pages/whats_new.textile +389 -0
  47. data/doc/print.haml +52 -0
  48. data/doc/print.toc.yaml +28 -0
  49. data/doc/scripts/buildr-git.rb +411 -0
  50. data/doc/scripts/install-jruby.sh +44 -0
  51. data/doc/scripts/install-linux.sh +64 -0
  52. data/doc/scripts/install-osx.sh +52 -0
  53. data/doc/site.haml +55 -0
  54. data/doc/site.toc.yaml +44 -0
  55. data/lib/buildr.rb +28 -45
  56. data/lib/buildr/core.rb +27 -0
  57. data/lib/buildr/core/application.rb +373 -0
  58. data/lib/buildr/core/application_cli.rb +134 -0
  59. data/lib/{core → buildr/core}/build.rb +91 -77
  60. data/lib/{core → buildr/core}/checks.rb +116 -95
  61. data/lib/buildr/core/common.rb +155 -0
  62. data/lib/buildr/core/compile.rb +594 -0
  63. data/lib/buildr/core/environment.rb +120 -0
  64. data/lib/buildr/core/filter.rb +258 -0
  65. data/lib/{core → buildr/core}/generate.rb +22 -5
  66. data/lib/buildr/core/help.rb +118 -0
  67. data/lib/buildr/core/progressbar.rb +156 -0
  68. data/lib/{core → buildr/core}/project.rb +468 -213
  69. data/lib/buildr/core/test.rb +690 -0
  70. data/lib/{core → buildr/core}/transports.rb +107 -127
  71. data/lib/buildr/core/util.rb +235 -0
  72. data/lib/buildr/ide.rb +19 -0
  73. data/lib/{java → buildr/ide}/eclipse.rb +86 -60
  74. data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
  75. data/lib/buildr/ide/idea.rb +194 -0
  76. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  77. data/lib/buildr/ide/idea7x.rb +210 -0
  78. data/lib/buildr/java.rb +26 -0
  79. data/lib/buildr/java/ant.rb +71 -0
  80. data/lib/buildr/java/bdd_frameworks.rb +267 -0
  81. data/lib/buildr/java/commands.rb +210 -0
  82. data/lib/buildr/java/compilers.rb +432 -0
  83. data/lib/buildr/java/deprecated.rb +141 -0
  84. data/lib/buildr/java/groovyc.rb +137 -0
  85. data/lib/buildr/java/jruby.rb +99 -0
  86. data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
  87. data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
  88. data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
  89. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  90. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
  91. data/lib/buildr/java/packaging.rb +706 -0
  92. data/lib/{java → buildr/java}/pom.rb +20 -4
  93. data/lib/buildr/java/rjb.rb +142 -0
  94. data/lib/buildr/java/test_frameworks.rb +290 -0
  95. data/lib/buildr/java/version_requirement.rb +172 -0
  96. data/lib/buildr/packaging.rb +21 -0
  97. data/lib/{java → buildr/packaging}/artifact.rb +170 -179
  98. data/lib/buildr/packaging/artifact_namespace.rb +957 -0
  99. data/lib/buildr/packaging/artifact_search.rb +140 -0
  100. data/lib/buildr/packaging/gems.rb +102 -0
  101. data/lib/buildr/packaging/package.rb +233 -0
  102. data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
  103. data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
  104. data/rakelib/apache.rake +126 -0
  105. data/rakelib/changelog.rake +56 -0
  106. data/rakelib/doc.rake +103 -0
  107. data/rakelib/package.rake +44 -0
  108. data/rakelib/release.rake +53 -0
  109. data/rakelib/rspec.rake +81 -0
  110. data/rakelib/rubyforge.rake +45 -0
  111. data/rakelib/scm.rake +49 -0
  112. data/rakelib/setup.rake +59 -0
  113. data/rakelib/stage.rake +45 -0
  114. data/spec/application_spec.rb +316 -0
  115. data/spec/archive_spec.rb +494 -0
  116. data/spec/artifact_namespace_spec.rb +635 -0
  117. data/spec/artifact_spec.rb +738 -0
  118. data/spec/build_spec.rb +193 -0
  119. data/spec/checks_spec.rb +537 -0
  120. data/spec/common_spec.rb +579 -0
  121. data/spec/compile_spec.rb +561 -0
  122. data/spec/groovy_compilers_spec.rb +239 -0
  123. data/spec/java_bdd_frameworks_spec.rb +238 -0
  124. data/spec/java_compilers_spec.rb +446 -0
  125. data/spec/java_packaging_spec.rb +1042 -0
  126. data/spec/java_test_frameworks_spec.rb +414 -0
  127. data/spec/packaging_helper.rb +63 -0
  128. data/spec/packaging_spec.rb +589 -0
  129. data/spec/project_spec.rb +739 -0
  130. data/spec/sandbox.rb +116 -0
  131. data/spec/scala_compilers_spec.rb +239 -0
  132. data/spec/spec.opts +6 -0
  133. data/spec/spec_helpers.rb +283 -0
  134. data/spec/test_spec.rb +871 -0
  135. data/spec/transport_spec.rb +300 -0
  136. data/spec/version_requirement_spec.rb +115 -0
  137. metadata +188 -77
  138. data/lib/buildr/cobertura.rb +0 -89
  139. data/lib/buildr/jdepend.rb +0 -40
  140. data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
  141. data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
  142. data/lib/buildr/jetty/JettyWrapper.class +0 -0
  143. data/lib/buildr/scala.rb +0 -368
  144. data/lib/core/application.rb +0 -188
  145. data/lib/core/common.rb +0 -562
  146. data/lib/core/help.rb +0 -72
  147. data/lib/core/rake_ext.rb +0 -81
  148. data/lib/java/ant.rb +0 -71
  149. data/lib/java/compile.rb +0 -589
  150. data/lib/java/idea.rb +0 -159
  151. data/lib/java/java.rb +0 -432
  152. data/lib/java/packaging.rb +0 -581
  153. data/lib/java/test.rb +0 -795
  154. data/lib/tasks/concat.rb +0 -35
@@ -1,188 +0,0 @@
1
- module Buildr
2
-
3
- # When running from +rake+, we already have an Application setup and must plug into it,
4
- # since the top-level tasks come from there. When running from +buildr+, we get to load
5
- # Rake and set everything up, and we use our own Application full of cool Buildr features.
6
- if defined?(Rake)
7
- Rake.application.top_level_tasks.unshift task("buildr:initialize")
8
- else
9
-
10
- require "rake"
11
-
12
- class Application < Rake::Application #:nodoc:
13
-
14
- DEFAULT_BUILDFILES = ["buildfile", "Buildfile"] + DEFAULT_RAKEFILES
15
-
16
- OPTIONS = [ # :nodoc:
17
- ['--help', '-H', GetoptLong::NO_ARGUMENT,
18
- "Display this help message."],
19
- ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
20
- "Do not search parent directories for the buildfile."],
21
- ['--quiet', '-q', GetoptLong::NO_ARGUMENT,
22
- "Do not log messages to standard output."],
23
- ['--buildfile', '-f', GetoptLong::REQUIRED_ARGUMENT,
24
- "Use FILE as the buildfile."],
25
- ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
26
- "Require MODULE before executing buildfile."],
27
- ['--trace', '-t', GetoptLong::NO_ARGUMENT,
28
- "Turn on invoke/execute tracing, enable full backtrace."],
29
- ['--version', '-V', GetoptLong::NO_ARGUMENT,
30
- "Display the program version."],
31
- ['--environment', '-e', GetoptLong::REQUIRED_ARGUMENT,
32
- "Environment name (e.g. development, test, production)."],
33
- ['--freeze', "-F", GetoptLong::NO_ARGUMENT,
34
- "Freezes the Buildfile so it always uses Buildr version #{Buildr::VERSION}"],
35
- ['--unfreeze', "-U", GetoptLong::NO_ARGUMENT,
36
- "Unfreezes the Buildfile to use the latest version of Buildr"]
37
- ]
38
-
39
- def initialize()
40
- super
41
- @rakefiles = DEFAULT_BUILDFILES
42
- @name = "Buildr"
43
- @requires = []
44
- opts = GetoptLong.new(*command_line_options)
45
- opts.each { |opt, value| do_option(opt, value) }
46
- collect_tasks
47
- top_level_tasks.unshift "buildr:initialize"
48
- end
49
-
50
- def run()
51
- standard_exception_handling do
52
- find_buildfile
53
- load_buildfile
54
- top_level
55
- end
56
- end
57
-
58
- def do_option(opt, value)
59
- case opt
60
- when '--help'
61
- help
62
- exit
63
- when "--buildfile"
64
- @rakefiles.clear
65
- @rakefiles << value
66
- when '--version'
67
- puts "Buildr, version #{Buildr::VERSION}"
68
- exit
69
- when '--environment'
70
- ENV['BUILDR_ENV'] = value
71
- when "--freeze"
72
- find_buildfile
73
- puts "Freezing the Buildfile so it always uses Buildr version #{Buildr::VERSION}"
74
- original = File.read(rakefile)
75
- if original =~ /gem\s*(["'])buildr\1/
76
- modified = original.sub(/gem\s*(["'])buildr\1\s*,\s*(["']).*\2/, %{gem "buildr", "#{Buildr::VERSION}"})
77
- else
78
- modified = %{gem "buildr", "#{Buildr::VERSION}"\n} + original
79
- end
80
- File.open(rakefile, "w") { |file| file.write modified }
81
- exit
82
- when "--unfreeze"
83
- find_buildfile
84
- puts "Unfreezing the Buildfile to use the latest version of Buildr from your Gems repository."
85
- modified = File.read(rakefile).sub(/^\s*gem\s*(["'])buildr\1.*\n/, "")
86
- File.open(rakefile, "w") { |file| file.write modified }
87
- exit
88
- when "--require"
89
- @requires << value
90
- when "--nosearch", "--quiet", "--trace"
91
- super
92
- end
93
- end
94
-
95
- def find_buildfile()
96
- here = Dir.pwd
97
- while ! have_rakefile
98
- Dir.chdir("..")
99
- if Dir.pwd == here || options.nosearch
100
- error = "No Buildfile found (looking for: #{@rakefiles.join(', ')})"
101
- if STDIN.isatty
102
- chdir(original_dir) { task("generate").invoke }
103
- exit 1
104
- else
105
- raise error
106
- end
107
- end
108
- here = Dir.pwd
109
- end
110
- end
111
-
112
- def load_buildfile()
113
- @requires.each { |name| require name }
114
- puts Buildr.environment ? "(in #{Dir.pwd}, #{Buildr.environment})" : "(in #{Dir.pwd})"
115
- load File.expand_path(@rakefile) if @rakefile != ''
116
- load_imports
117
- end
118
-
119
- def usage()
120
- puts "Buildr #{Buildr::VERSION}"
121
- puts
122
- puts "Usage:"
123
- puts " buildr [-f buildfile] {options} targets..."
124
- end
125
-
126
- def help()
127
- usage
128
- puts
129
- puts "Options:"
130
- OPTIONS.sort.each do |long, short, mode, desc|
131
- if mode == GetoptLong::REQUIRED_ARGUMENT
132
- if desc =~ /\b([A-Z]{2,})\b/
133
- long = long + "=#{$1}"
134
- end
135
- end
136
- printf " %-20s (%s)\n", long, short
137
- printf " %s\n", desc
138
- end
139
- puts
140
- puts "For help with your buildfile:"
141
- puts " buildr help"
142
- end
143
-
144
- def command_line_options
145
- OPTIONS.collect { |lst| lst[0..-2] }
146
- end
147
- end
148
-
149
- Rake.application = Buildr::Application.new
150
- end
151
-
152
-
153
- class << self
154
-
155
- # Loads buildr.rake files from users home directory and project directory.
156
- # Loads custom tasks from .rake files in tasks directory.
157
- def load_tasks_and_local_files() #:nodoc:
158
- return false if @build_files
159
- # Load the settings files.
160
- @build_files = [ File.expand_path("buildr.rb", Gem::user_home), "buildr.rb" ].select { |file| File.exist?(file) }
161
- @build_files += [ File.expand_path("buildr.rake", Gem::user_home), File.expand_path("buildr.rake") ].
162
- select { |file| File.exist?(file) }.each { |file| warn "Please use '#{file.ext('rb')}' instead of '#{file}'" }
163
- #Load local tasks that can be used in the Buildfile.
164
- @build_files += Dir["#{Dir.pwd}/tasks/*.rake"]
165
- @build_files.each do |file|
166
- unless $LOADED_FEATURES.include?(file)
167
- load file
168
- $LOADED_FEATURES << file
169
- end
170
- end
171
- true
172
- end
173
-
174
- # :call-seq:
175
- # build_files() => files
176
- #
177
- # Returns a list of build files. These are files used by the build,
178
- def build_files()
179
- [Rake.application.rakefile].compact + @build_files
180
- end
181
-
182
- task "buildr:initialize" do
183
- Buildr.load_tasks_and_local_files
184
- end
185
-
186
- end
187
-
188
- end
@@ -1,562 +0,0 @@
1
- require "tempfile"
2
- require "pathname"
3
- require "core/transports"
4
- require "open-uri"
5
- require "uri/open-sftp"
6
-
7
-
8
- class Hash
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
- map { |line| line.split("=") }.
23
- inject({}) { |hash, (name, value)| hash.merge(name=>value) }
24
- end
25
-
26
- end
27
-
28
- # :call-seq:
29
- # only(keys*) => hash
30
- #
31
- # Returns a new hash with only the specified keys.
32
- #
33
- # For example:
34
- # { :a=>1, :b=>2, :c=>3, :d=>4 }.only(:a, :c)
35
- # => { :a=>1, :c=>3 }
36
- def only(*keys)
37
- keys.inject({}) { |hash, key| has_key?(key) ? hash.merge(key=>self[key]) : hash }
38
- end
39
-
40
-
41
- # :call-seq:
42
- # except(keys*) => hash
43
- #
44
- # Returns a new hash without the specified keys.
45
- #
46
- # For example:
47
- # { :a=>1, :b=>2, :c=>3, :d=>4 }.except(:a, :c)
48
- # => { :b=>2, :d=>4 }
49
- def except(*keys)
50
- (self.keys - keys).inject({}) { |hash, key| hash.merge(key=>self[key]) }
51
- end
52
-
53
- # :call-seq:
54
- # to_java_properties() => string
55
- #
56
- # Convert hash to string format used for Java properties file. For example:
57
- # { "foo"=>"bar", "baz"=>"fab" }.to_properties
58
- # => foo=bar
59
- # baz=fab
60
- def to_java_properties()
61
- keys.sort.map { |key|
62
- value = self[key].gsub(/[\t\r\n\f\\]/) { |escape| "\\" + {"\t"=>"t", "\r"=>"r", "\n"=>"n", "\f"=>"f", "\\"=>"\\"}[escape] }
63
- "#{key}=#{value}"
64
- }.join("\n")
65
- end
66
-
67
- end
68
-
69
-
70
- module Buildr
71
-
72
- # Collection of options for controlling Buildr. For example for running builds without running
73
- # test cases, using a proxy server, JVM arguments, etc. You access this object by calling options,
74
- # for example:
75
- # options.proxy.http = "http://proxy.acme.com:8080"
76
- # options.java_args = "-Xmx512M"
77
- class Options
78
-
79
- # We use this to present environment variable as arrays.
80
- class EnvArray < Array #:nodoc:
81
-
82
- def initialize(name)
83
- @name = name.upcase
84
- replace((ENV[@name] || ENV[@name.downcase] || "").split(/\s*,\s*/).reject(&:empty?))
85
- end
86
-
87
- (Array.instance_methods - Object.instance_methods - Enumerable.instance_methods).sort.each do |method|
88
- class_eval %{def #{method}(*args, &block) ; result = super ; write ; result ; end}
89
- end
90
-
91
- private
92
-
93
- def write()
94
- ENV[@name.downcase] = nil
95
- ENV[@name] = map(&:to_s).join(",")
96
- end
97
-
98
- end
99
-
100
- # Wraps around the proxy environment variables:
101
- # * :http -- HTTP_PROXY
102
- # * :exclude -- NO_PROXY
103
- class Proxies
104
-
105
- # Returns the HTTP_PROXY URL.
106
- def http()
107
- ENV["HTTP_PROXY"] || ENV["http_proxy"]
108
- end
109
-
110
- # Sets the HTTP_PROXY URL.
111
- def http=(url)
112
- ENV["http_proxy"] = nil
113
- ENV["HTTP_PROXY"] = url
114
- end
115
-
116
- # Returns list of hosts to exclude from proxying (NO_PROXY).
117
- def exclude()
118
- @exclude ||= EnvArray.new("NO_PROXY")
119
- end
120
-
121
- # Sets list of hosts to exclude from proxy (NO_PROXY). Accepts host name, array of names,
122
- # or nil to clear the list.
123
- def exclude=(url)
124
- exclude.clear
125
- exclude.concat [url].flatten if url
126
- exclude
127
- end
128
-
129
- end
130
-
131
- # :call-seq:
132
- # proxy() => options
133
- #
134
- # Returns the proxy options. Currently supported options are:
135
- # * :http -- HTTP proxy for use when downloading.
136
- # * :exclude -- Do not use proxy for these hosts/domains.
137
- #
138
- # For example:
139
- # options.proxy.http = "http://proxy.acme.com:8080"
140
- # You can also set it using the environment variable HTTP_PROXY.
141
- #
142
- # You can exclude individual hosts from being proxied, or entire domains, for example:
143
- # options.proxy.exclude = "optimus"
144
- # options.proxy.exclude = ["optimus", "prime"]
145
- # options.proxy.exclude << "*.internal"
146
- def proxy()
147
- @proxy ||= Proxies.new
148
- end
149
-
150
- end
151
-
152
- class << self
153
-
154
- # :call-seq:
155
- # options() => Options
156
- #
157
- # Returns the Buildr options. See Options.
158
- def options()
159
- @options ||= Options.new
160
- end
161
-
162
- end
163
-
164
- # :call-seq:
165
- # options() => Options
166
- #
167
- # Returns the Buildr options. See Options.
168
- def options()
169
- Buildr.options
170
- end
171
-
172
- # :call-seq:
173
- # environment() => string or nil
174
- #
175
- # Returns the environment name. Use this when your build depends on the environment,
176
- # for example, development, production, etc. The value comes from the BUILDR_ENV environment variable.
177
- #
178
- # For example:
179
- # buildr -e production
180
- def environment()
181
- ENV['BUILDR_ENV']
182
- end
183
-
184
- # :call-seq:
185
- # environment(env)
186
- #
187
- # Sets the environment name.
188
- def environment=(env)
189
- ENV['BUILDR_ENV'] = env
190
- end
191
-
192
- # :call-seq:
193
- # struct(hash) => Struct
194
- #
195
- # Convenience method for creating an anonymous Struct.
196
- #
197
- # For example:
198
- # COMMONS = struct(
199
- # :collections =>"commons-collections:commons-collections:jar:3.1",
200
- # :lang =>"commons-lang:commons-lang:jar:2.1",
201
- # :logging =>"commons-logging:commons-logging:jar:1.0.3",
202
- # )
203
- #
204
- # compile.with COMMONS.logging
205
- def struct(hash)
206
- Struct.new(nil, *hash.keys).new(*hash.values)
207
- end
208
-
209
- # :call-seq:
210
- # write(name, content)
211
- # write(name) { ... }
212
- #
213
- # Write the contents into a file. The second form calls the block and writes the result.
214
- #
215
- # For example:
216
- # write "TIMESTAMP", Time.now
217
- # write("TIMESTAMP") { Time.now }
218
- #
219
- # Yields to the block before writing the file, so you can chain read and write together.
220
- # For example:
221
- # write("README") { read("README").sub("${build}", Time.now) }
222
- def write(name, content = nil)
223
- mkpath File.dirname(name), :verbose=>false
224
- content = yield if block_given?
225
- File.open(name.to_s, "wb") { |file| file.write content.to_s }
226
- content.to_s
227
- end
228
-
229
- # :call-seq:
230
- # read(name) => string
231
- # read(name) { |string| ... } => result
232
- #
233
- # Reads and returns the contents of a file. The second form yields to the block and returns
234
- # the result of the block.
235
- #
236
- # For example:
237
- # puts read("README")
238
- # read("README") { |text| puts text }
239
- def read(name)
240
- contents = File.open(name.to_s) { |f| f.read }
241
- if block_given?
242
- yield contents
243
- else
244
- contents
245
- end
246
- end
247
-
248
- # :call-seq:
249
- # download(url_or_uri) => task
250
- # download(path=>url_or_uri) =>task
251
- #
252
- # Create a task that will download a file from a URL.
253
- #
254
- # Takes a single argument, a hash with one pair. The key is the file being
255
- # created, the value if the URL to download. The task executes only if the
256
- # file does not exist; the URL is not checked for updates.
257
- #
258
- # The task will show download progress on the console; if there are MD5/SHA1
259
- # checksums on the server it will verify the download before saving it.
260
- #
261
- # For example:
262
- # download "image.jpg"=>"http://example.com/theme/image.jpg"
263
- def download(args)
264
- args = URI.parse(args) if String === args
265
- if URI === args
266
- # Given only a download URL, download into a temporary file.
267
- # You can infer the file from task name.
268
- temp = Tempfile.open(File.basename(args.to_s))
269
- file(temp.path).tap do |task|
270
- # Since temporary file exists, force a download.
271
- class << task ; def needed?() ; true ; end ; end
272
- task.sources << args
273
- task.enhance { args.download temp }
274
- end
275
- else
276
- # Download to a file created by the task.
277
- fail unless args.keys.size == 1
278
- uri = URI.parse(args.values.first.to_s)
279
- file_create(args.keys.first).tap do |task|
280
- task.sources << uri
281
- task.enhance { uri.download task.name }
282
- end
283
- end
284
-
285
- end
286
-
287
-
288
- # A filter knows how to copy files from one directory to another, applying mappings to the
289
- # contents of these files.
290
- #
291
- # You can specify the mapping using a Hash, and it will map ${key} fields found in each source
292
- # file into the appropriate value in the target file. For example:
293
- # filter.using "version"=>"1.2", "build"=>Time.now
294
- # will replace all occurrences of <tt>${version}</tt> with <tt>1.2</tt>, and <tt>${build}</tt>
295
- # with the current date/time.
296
- #
297
- # You can also specify the mapping by passing a proc or a method, that will be called for
298
- # each source file, with the file name and content, returning the modified content.
299
- #
300
- # Without any mapping, the filter simply copies files from the source directory into the target
301
- # directory.
302
- #
303
- # A filter has one target directory, but you can specify any number of source directories,
304
- # either when creating the filter or calling #from. Include/exclude patterns are specified
305
- # relative to the source directories, so:
306
- # filter.include "*.png"
307
- # will only include PNG files from any of the source directories.
308
- #
309
- # See Buildr#filter.
310
- class Filter
311
-
312
- def initialize() #:nodoc:
313
- @include = []
314
- @exclude = []
315
- @sources = []
316
- end
317
-
318
- # Returns the list of source directories (each being a file task).
319
- attr_reader :sources
320
-
321
- # *Deprecated* Use #sources instead.
322
- def source()
323
- warn_deprecated "Please use sources instead."
324
- @sources.first
325
- end
326
-
327
- # *Deprecated* Use #from instead.
328
- def source=(dir)
329
- warn_deprecated "Please use from instead."
330
- from(dir)
331
- end
332
-
333
- # :call-seq:
334
- # from(*sources) => self
335
- #
336
- # Adds additional directories from which to copy resources.
337
- #
338
- # For example:
339
- # filter.from("src").into("target").using("build"=>Time.now)
340
- def from(*sources)
341
- @sources |= sources.flatten.map { |dir| file(File.expand_path(dir.to_s)) }
342
- self
343
- end
344
-
345
- # The target directory as a file task.
346
- attr_reader :target
347
-
348
- # :call-seq:
349
- # into(dir) => self
350
- #
351
- # Sets the target directory into which files are copied and returns self.
352
- #
353
- # For example:
354
- # filter.from("src").into("target").using("build"=>Time.now)
355
- def into(dir)
356
- @target = file(File.expand_path(dir.to_s)) { |task| run if target == task && !sources.empty? }
357
- self
358
- end
359
-
360
- # :call-seq:
361
- # include(*files) => self
362
- #
363
- # Specifies files to include and returns self. See FileList#include.
364
- #
365
- # By default all files are included. You can use this method to only include specific
366
- # files form the source directory.
367
- def include(*files)
368
- @include += files
369
- self
370
- end
371
- alias :add :include
372
-
373
- # :call-seq:
374
- # exclude(*files) => self
375
- #
376
- # Specifies files to exclude and returns self. See FileList#exclude.
377
- def exclude(*files)
378
- @exclude += files
379
- self
380
- end
381
-
382
- # The mapping. See #using.
383
- attr_accessor :mapping
384
-
385
- # The mapper to use. See #using.
386
- attr_accessor :mapper
387
-
388
- # :call-seq:
389
- # using(mapping) => self
390
- # using() { |file_name, contents| ... } => self
391
- #
392
- # Specifies the mapping to use and returns self.
393
- #
394
- # The most typical mapping uses a Hash, and the default mapping uses the Maven style, so
395
- # <code>${key}</code> are mapped to the values. You can change that by passing a different
396
- # format as the first argument. Currently supports:
397
- # * :ant -- Map <code>@key@</code>.
398
- # * :maven -- Map <code>${key}</code> (default).
399
- # * :ruby -- Map <code>#{key}</code>.
400
- # * Regexp -- Maps the matched data (e.g. <code>/=(.*?)=/</code>
401
- #
402
- # For example:
403
- # filter.using "version"=>"1.2"
404
- # Is the same as:
405
- # filter.using :maven, "version"=>"1.2"
406
- #
407
- # You can also pass a proc or method. It will be called with the file name and content,
408
- # to return the mapped content.
409
- #
410
- # Without any mapping, all files are copied as is.
411
- def using(*args, &block)
412
- case args.first
413
- when Hash # Maven hash mapping
414
- using :maven, *args
415
- when Symbol # Mapping from a method
416
- raise ArgumentError, "Expected mapper type followed by mapping hash" unless args.size == 2 && Hash === args[1]
417
- @mapper, @mapping = *args
418
- when Regexp # Mapping using a regular expression
419
- raise ArgumentError, "Expected regular expression followed by mapping hash" unless args.size == 2 && Hash === args[1]
420
- @mapper, @mapping = *args
421
- else
422
- raise ArgumentError, "Expected proc, method or a block" if args.size > 1 || (args.first && block)
423
- @mapping = args.first || block
424
- end
425
- self
426
- end
427
-
428
- # :call-seq:
429
- # run() => boolean
430
- #
431
- # Runs the filter.
432
- def run()
433
- raise "No source directory specified, where am I going to find the files to filter?" if sources.empty?
434
- sources.each { |source| raise "Source directory #{source} doesn't exist" unless File.exist?(source.to_s) }
435
- raise "No target directory specified, where am I going to copy the files to?" if target.nil?
436
-
437
- copy_map = sources.flatten.map(&:to_s).inject({}) do |map, source|
438
- base = Pathname.new(source)
439
- files = FileList.recursive(source).
440
- map { |file| Pathname.new(file).relative_path_from(base).to_s }.
441
- select { |file| @include.empty? || @include.any? { |pattern| File.fnmatch(pattern, file) } }.
442
- reject { |file| @exclude.any? { |pattern| File.fnmatch(pattern, file) } }
443
- files.each do |file|
444
- src, dest = File.expand_path(file, source), File.expand_path(file, target.to_s)
445
- map[file] = src if !File.exist?(dest) || File.stat(src).mtime > File.stat(dest).mtime
446
- end
447
- map
448
- end
449
-
450
- return false if copy_map.empty?
451
-
452
- verbose(Rake.application.options.trace || false) do
453
- mkpath target.to_s
454
- copy_map.each do |path, source|
455
- dest = File.expand_path(path, target.to_s)
456
- if File.directory?(source)
457
- mkpath dest
458
- else
459
- mkpath File.dirname(dest)
460
- case mapping
461
- when Proc, Method # Call on input, accept output.
462
- mapped = mapping.call(path, File.open(source, "rb") { |file| file.read })
463
- File.open(dest, "wb") { |file| file.write mapped }
464
- when Hash # Map ${key} to value
465
- content = File.open(source, "rb") { |file| file.read }
466
- if Symbol === @mapper
467
- mapped = send("#{@mapper}_mapper", content) { |key| mapping[key] }
468
- else
469
- mapped = regexp_mapper(content) { |key| mapping[key] }
470
- end
471
- #gsub(/\$\{[^}]*\}/) { |str| mapping[str[2..-2]] || str }
472
- File.open(dest, "wb") { |file| file.write mapped }
473
- when nil # No mapping.
474
- cp source, dest
475
- File.chmod(0664, dest)
476
- else
477
- fail "Filter can be a hash (key=>value), or a proc/method; I don't understand #{mapping}"
478
- end
479
- end
480
- end
481
- touch target.to_s
482
- end
483
- true
484
- end
485
-
486
- # Returns the target directory.
487
- def to_s()
488
- @target.to_s
489
- end
490
-
491
- private
492
-
493
- def maven_mapper(content)
494
- content.gsub(/\$\{.*?\}/) { |str| yield(str[2..-2]) || str }
495
- end
496
-
497
- def ant_mapper(content)
498
- content.gsub(/@.*?@/) { |str| yield(str[1..-2]) || str }
499
- end
500
-
501
- def ruby_mapper(content)
502
- content.gsub(/#\{.*?\}/) { |str| yield(str[2..-2]) || str }
503
- end
504
-
505
- def regexp_mapper(content)
506
- content.gsub(@mapper) { |str| yield(str.scan(@mapper).join) || str }
507
- end
508
-
509
- end
510
-
511
- # :call-seq:
512
- # filter(*source) => Filter
513
- #
514
- # Creates a filter that will copy files from the source directory(ies) into the target directory.
515
- # You can extend the filter to modify files by mapping <tt>${key}</tt> into values in each
516
- # of the copied files, and by including or excluding specific files.
517
- #
518
- # A filter is not a task, you must call the Filter#run method to execute it.
519
- #
520
- # For example, to copy all files from one directory to another:
521
- # filter("src/files").into("target/classes").run
522
- # To include only the text files, and replace each instance of <tt>${build}</tt> with the current
523
- # date/time:
524
- # filter("src/files").into("target/classes").include("*.txt").using("build"=>Time.now).run
525
- def filter(*sources)
526
- Filter.new.from(*sources)
527
- end
528
-
529
- end
530
-
531
-
532
- # Add a touch of colors (red) to warnings.
533
- HighLine.use_color = PLATFORM !~ /win32/
534
- module Kernel #:nodoc:
535
-
536
- def warn_with_color(message)
537
- warn_without_color $terminal.color(message.to_s, :red)
538
- end
539
- alias_method_chain :warn, :color
540
-
541
- # :call-seq:
542
- # warn_deprecated(message)
543
- #
544
- # Use with deprecated methods and classes. This method automatically adds the file name and line number,
545
- # and the text "Deprecated" before the message, and eliminated duplicate warnings. It only warns when
546
- # running in verbose mode.
547
- #
548
- # For example:
549
- # warn_deprecated "Please use new_foo instead of foo."
550
- def warn_deprecated(message) #:nodoc:
551
- return unless verbose
552
- "#{caller[1]}: Deprecated: #{message}".tap do |message|
553
- @deprecated ||= {}
554
- unless @deprecated[message]
555
- @deprecated[message] = true
556
- warn message
557
- end
558
- end
559
- end
560
-
561
- end
562
-