buildr 1.3.5-x86-mswin32
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 +998 -0
- data/LICENSE +176 -0
- data/NOTICE +26 -0
- data/README.rdoc +134 -0
- data/Rakefile +45 -0
- data/_buildr +29 -0
- data/_jbuildr +29 -0
- data/addon/buildr/antlr.rb +65 -0
- data/addon/buildr/cobertura.rb +22 -0
- data/addon/buildr/drb.rb +281 -0
- data/addon/buildr/emma.rb +22 -0
- data/addon/buildr/hibernate.rb +142 -0
- data/addon/buildr/javacc.rb +85 -0
- data/addon/buildr/jdepend.rb +60 -0
- data/addon/buildr/jetty.rb +248 -0
- data/addon/buildr/jibx.rb +86 -0
- data/addon/buildr/nailgun.rb +221 -0
- data/addon/buildr/openjpa.rb +90 -0
- data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
- data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
- data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
- data/addon/buildr/xmlbeans.rb +93 -0
- data/bin/buildr +19 -0
- data/buildr.buildfile +58 -0
- data/buildr.gemspec +65 -0
- data/doc/_config.yml +1 -0
- data/doc/_layouts/default.html +88 -0
- data/doc/_layouts/preface.html +22 -0
- data/doc/artifacts.textile +211 -0
- data/doc/building.textile +244 -0
- data/doc/contributing.textile +252 -0
- data/doc/css/default.css +236 -0
- data/doc/css/print.css +101 -0
- data/doc/css/syntax.css +23 -0
- data/doc/download.textile +79 -0
- data/doc/extending.textile +186 -0
- data/doc/images/1442160941-frontcover.jpg +0 -0
- data/doc/images/asf-logo.gif +0 -0
- data/doc/images/asf-logo.png +0 -0
- data/doc/images/buildr-hires.png +0 -0
- data/doc/images/buildr.png +0 -0
- data/doc/images/favicon.png +0 -0
- data/doc/images/growl-icon.tiff +0 -0
- data/doc/images/note.png +0 -0
- data/doc/images/project-structure.png +0 -0
- data/doc/images/tip.png +0 -0
- data/doc/images/zbuildr.png +0 -0
- data/doc/images/zbuildr.tif +0 -0
- data/doc/index.textile +69 -0
- data/doc/installing.textile +266 -0
- data/doc/languages.textile +459 -0
- data/doc/mailing_lists.textile +25 -0
- data/doc/more_stuff.textile +457 -0
- data/doc/packaging.textile +430 -0
- data/doc/preface.textile +54 -0
- data/doc/projects.textile +271 -0
- data/doc/quick_start.textile +210 -0
- data/doc/scripts/buildr-git.rb +512 -0
- data/doc/scripts/gitflow.rb +296 -0
- data/doc/scripts/install-jruby.sh +44 -0
- data/doc/scripts/install-linux.sh +72 -0
- data/doc/scripts/install-osx.sh +52 -0
- data/doc/settings_profiles.textile +280 -0
- data/doc/testing.textile +222 -0
- data/etc/KEYS +151 -0
- data/lib/buildr.rb +36 -0
- data/lib/buildr/core.rb +35 -0
- data/lib/buildr/core/application.rb +656 -0
- data/lib/buildr/core/build.rb +452 -0
- data/lib/buildr/core/checks.rb +254 -0
- data/lib/buildr/core/common.rb +150 -0
- data/lib/buildr/core/compile.rb +608 -0
- data/lib/buildr/core/environment.rb +129 -0
- data/lib/buildr/core/filter.rb +362 -0
- data/lib/buildr/core/generate.rb +195 -0
- data/lib/buildr/core/help.rb +119 -0
- data/lib/buildr/core/osx.rb +46 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/buildr/core/project.rb +866 -0
- data/lib/buildr/core/shell.rb +198 -0
- data/lib/buildr/core/test.rb +723 -0
- data/lib/buildr/core/transports.rb +559 -0
- data/lib/buildr/core/util.rb +449 -0
- data/lib/buildr/groovy.rb +19 -0
- data/lib/buildr/groovy/bdd.rb +106 -0
- data/lib/buildr/groovy/compiler.rb +138 -0
- data/lib/buildr/groovy/shell.rb +48 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/buildr/ide/eclipse.rb +334 -0
- data/lib/buildr/ide/eclipse/java.rb +53 -0
- data/lib/buildr/ide/eclipse/plugin.rb +68 -0
- data/lib/buildr/ide/eclipse/scala.rb +66 -0
- data/lib/buildr/ide/idea.ipr.template +300 -0
- data/lib/buildr/ide/idea.rb +190 -0
- data/lib/buildr/ide/idea7x.ipr.template +290 -0
- data/lib/buildr/ide/idea7x.rb +212 -0
- data/lib/buildr/java.rb +23 -0
- data/lib/buildr/java/ant.rb +94 -0
- data/lib/buildr/java/bdd.rb +459 -0
- data/lib/buildr/java/cobertura.rb +274 -0
- data/lib/buildr/java/commands.rb +213 -0
- data/lib/buildr/java/compiler.rb +349 -0
- data/lib/buildr/java/deprecated.rb +141 -0
- data/lib/buildr/java/emma.rb +244 -0
- data/lib/buildr/java/jruby.rb +117 -0
- data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +137 -0
- data/lib/buildr/java/packaging.rb +716 -0
- data/lib/buildr/java/pom.rb +174 -0
- data/lib/buildr/java/rjb.rb +155 -0
- data/lib/buildr/java/test_result.rb +353 -0
- data/lib/buildr/java/tests.rb +333 -0
- data/lib/buildr/java/version_requirement.rb +172 -0
- data/lib/buildr/packaging.rb +24 -0
- data/lib/buildr/packaging/archive.rb +488 -0
- data/lib/buildr/packaging/artifact.rb +749 -0
- data/lib/buildr/packaging/artifact_namespace.rb +972 -0
- data/lib/buildr/packaging/artifact_search.rb +140 -0
- data/lib/buildr/packaging/gems.rb +102 -0
- data/lib/buildr/packaging/package.rb +238 -0
- data/lib/buildr/packaging/tar.rb +186 -0
- data/lib/buildr/packaging/version_requirement.rb +172 -0
- data/lib/buildr/packaging/zip.rb +73 -0
- data/lib/buildr/packaging/ziptask.rb +316 -0
- data/lib/buildr/resources/buildr.icns +0 -0
- data/lib/buildr/scala.rb +25 -0
- data/lib/buildr/scala/bdd.rb +109 -0
- data/lib/buildr/scala/compiler.rb +195 -0
- data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner$.class +0 -0
- data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
- data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.scala +35 -0
- data/lib/buildr/scala/shell.rb +55 -0
- data/lib/buildr/scala/tests.rb +157 -0
- data/lib/buildr/shell.rb +180 -0
- data/rakelib/checks.rake +57 -0
- data/rakelib/doc.rake +92 -0
- data/rakelib/jekylltask.rb +120 -0
- data/rakelib/package.rake +73 -0
- data/rakelib/release.rake +149 -0
- data/rakelib/rspec.rake +73 -0
- data/rakelib/setup.rake +54 -0
- data/rakelib/stage.rake +213 -0
- data/rakelib/stage.rake~ +213 -0
- data/spec/addon/drb_spec.rb +328 -0
- data/spec/core/application_spec.rb +502 -0
- data/spec/core/build_spec.rb +677 -0
- data/spec/core/checks_spec.rb +519 -0
- data/spec/core/common_spec.rb +670 -0
- data/spec/core/compile_spec.rb +583 -0
- data/spec/core/extension_spec.rb +93 -0
- data/spec/core/generate_spec.rb +33 -0
- data/spec/core/project_spec.rb +762 -0
- data/spec/core/test_spec.rb +1098 -0
- data/spec/core/transport_spec.rb +537 -0
- data/spec/core/util_spec.rb +67 -0
- data/spec/groovy/bdd_spec.rb +80 -0
- data/spec/groovy/compiler_spec.rb +240 -0
- data/spec/ide/eclipse_spec.rb +501 -0
- data/spec/ide/idea7x_spec.rb +84 -0
- data/spec/java/ant_spec.rb +33 -0
- data/spec/java/bdd_spec.rb +382 -0
- data/spec/java/cobertura_spec.rb +85 -0
- data/spec/java/compiler_spec.rb +446 -0
- data/spec/java/emma_spec.rb +119 -0
- data/spec/java/java_spec.rb +124 -0
- data/spec/java/packaging_spec.rb +1134 -0
- data/spec/java/test_coverage_helper.rb +257 -0
- data/spec/java/tests_spec.rb +493 -0
- data/spec/packaging/archive_spec.rb +527 -0
- data/spec/packaging/artifact_namespace_spec.rb +654 -0
- data/spec/packaging/artifact_spec.rb +795 -0
- data/spec/packaging/packaging_helper.rb +63 -0
- data/spec/packaging/packaging_spec.rb +684 -0
- data/spec/sandbox.rb +142 -0
- data/spec/scala/bdd_spec.rb +119 -0
- data/spec/scala/compiler_spec.rb +284 -0
- data/spec/scala/scala.rb +38 -0
- data/spec/scala/tests_spec.rb +261 -0
- data/spec/spec_helpers.rb +340 -0
- data/spec/version_requirement_spec.rb +129 -0
- metadata +383 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with this
|
3
|
+
# work for additional information regarding copyright ownership. The ASF
|
4
|
+
# licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations under
|
14
|
+
# the License.
|
15
|
+
|
16
|
+
|
17
|
+
require 'rake'
|
18
|
+
require 'buildr/core/util'
|
19
|
+
|
20
|
+
|
21
|
+
module Buildr
|
22
|
+
|
23
|
+
# :call-seq:
|
24
|
+
# struct(hash) => Struct
|
25
|
+
#
|
26
|
+
# Convenience method for creating an anonymous Struct.
|
27
|
+
#
|
28
|
+
# For example:
|
29
|
+
# COMMONS = struct(
|
30
|
+
# :collections =>'commons-collections:commons-collections:jar:3.1',
|
31
|
+
# :lang =>'commons-lang:commons-lang:jar:2.1',
|
32
|
+
# :logging =>'commons-logging:commons-logging:jar:1.0.3',
|
33
|
+
# )
|
34
|
+
#
|
35
|
+
# compile.with COMMONS.logging
|
36
|
+
def struct(hash)
|
37
|
+
Struct.new(nil, *hash.keys).new(*hash.values)
|
38
|
+
end
|
39
|
+
|
40
|
+
# :call-seq:
|
41
|
+
# write(name, content)
|
42
|
+
# write(name) { ... }
|
43
|
+
#
|
44
|
+
# Write the contents into a file. The second form calls the block and writes the result.
|
45
|
+
#
|
46
|
+
# For example:
|
47
|
+
# write 'TIMESTAMP', Time.now
|
48
|
+
# write('TIMESTAMP') { Time.now }
|
49
|
+
#
|
50
|
+
# Yields to the block before writing the file, so you can chain read and write together.
|
51
|
+
# For example:
|
52
|
+
# write('README') { read('README').sub("${build}", Time.now) }
|
53
|
+
def write(name, content = nil)
|
54
|
+
mkpath File.dirname(name)
|
55
|
+
content = yield if block_given?
|
56
|
+
File.open(name.to_s, 'wb') { |file| file.write content.to_s }
|
57
|
+
content.to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
# :call-seq:
|
61
|
+
# read(name) => string
|
62
|
+
# read(name) { |string| ... } => result
|
63
|
+
#
|
64
|
+
# Reads and returns the contents of a file. The second form yields to the block and returns
|
65
|
+
# the result of the block.
|
66
|
+
#
|
67
|
+
# For example:
|
68
|
+
# puts read('README')
|
69
|
+
# read('README') { |text| puts text }
|
70
|
+
def read(name)
|
71
|
+
contents = File.open(name.to_s) { |f| f.read }
|
72
|
+
if block_given?
|
73
|
+
yield contents
|
74
|
+
else
|
75
|
+
contents
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# :call-seq:
|
80
|
+
# download(url_or_uri) => task
|
81
|
+
# download(path=>url_or_uri) =>task
|
82
|
+
#
|
83
|
+
# Create a task that will download a file from a URL.
|
84
|
+
#
|
85
|
+
# Takes a single argument, a hash with one pair. The key is the file being
|
86
|
+
# created, the value if the URL to download. The task executes only if the
|
87
|
+
# file does not exist; the URL is not checked for updates.
|
88
|
+
#
|
89
|
+
# The task will show download progress on the console; if there are MD5/SHA1
|
90
|
+
# checksums on the server it will verify the download before saving it.
|
91
|
+
#
|
92
|
+
# For example:
|
93
|
+
# download 'image.jpg'=>'http://example.com/theme/image.jpg'
|
94
|
+
def download(args)
|
95
|
+
args = URI.parse(args) if String === args
|
96
|
+
if URI === args
|
97
|
+
# Given only a download URL, download into a temporary file.
|
98
|
+
# You can infer the file from task name.
|
99
|
+
temp = Tempfile.open(File.basename(args.to_s))
|
100
|
+
file(temp.path).tap do |task|
|
101
|
+
# Since temporary file exists, force a download.
|
102
|
+
class << task ; def needed? ; true ; end ; end
|
103
|
+
task.sources << args
|
104
|
+
task.enhance { args.download temp }
|
105
|
+
end
|
106
|
+
else
|
107
|
+
# Download to a file created by the task.
|
108
|
+
fail unless args.keys.size == 1
|
109
|
+
uri = URI.parse(args.values.first.to_s)
|
110
|
+
file(args.keys.first.to_s).tap do |task|
|
111
|
+
task.sources << uri
|
112
|
+
task.enhance { uri.download task.name }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
# A file task that concatenates all its prerequisites to create a new file.
|
119
|
+
#
|
120
|
+
# For example:
|
121
|
+
# concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
|
122
|
+
#
|
123
|
+
# See also Buildr#concat.
|
124
|
+
class ConcatTask < Rake::FileTask
|
125
|
+
def initialize(*args) #:nodoc:
|
126
|
+
super
|
127
|
+
enhance do |task|
|
128
|
+
content = prerequisites.inject("") do |content, prereq|
|
129
|
+
content << File.read(prereq.to_s) if File.exists?(prereq) && !File.directory?(prereq)
|
130
|
+
content
|
131
|
+
end
|
132
|
+
File.open(task.name, "wb") { |file| file.write content }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# :call-seq:
|
138
|
+
# concat(target=>files) => task
|
139
|
+
#
|
140
|
+
# Creates and returns a file task that concatenates all its prerequisites to create
|
141
|
+
# a new file. See #ConcatTask.
|
142
|
+
#
|
143
|
+
# For example:
|
144
|
+
# concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
|
145
|
+
def concat(args)
|
146
|
+
file, arg_names, deps = Buildr.application.resolve_args([args])
|
147
|
+
ConcatTask.define_task(File.expand_path(file)=>deps)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
@@ -0,0 +1,608 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with this
|
3
|
+
# work for additional information regarding copyright ownership. The ASF
|
4
|
+
# licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations under
|
14
|
+
# the License.
|
15
|
+
|
16
|
+
|
17
|
+
require 'buildr/core/common'
|
18
|
+
|
19
|
+
|
20
|
+
module Buildr
|
21
|
+
|
22
|
+
# The underlying compiler used by CompileTask.
|
23
|
+
# To add a new compiler, extend Compiler::Base and add your compiler using:
|
24
|
+
# Buildr::Compiler.add MyCompiler
|
25
|
+
module Compiler
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
# Returns true if the specified compiler exists.
|
30
|
+
def has?(name)
|
31
|
+
compilers.any? { |compiler| compiler.to_sym == name.to_sym }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Select a compiler by its name.
|
35
|
+
def select(name)
|
36
|
+
compilers.detect { |compiler| compiler.to_sym == name.to_sym }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Adds a compiler to the list of supported compiler.
|
40
|
+
#
|
41
|
+
# For example:
|
42
|
+
# Buildr::Compiler << Buildr::Javac
|
43
|
+
def add(compiler)
|
44
|
+
@compilers ||= []
|
45
|
+
@compilers |= [compiler]
|
46
|
+
end
|
47
|
+
alias :<< :add
|
48
|
+
|
49
|
+
# Returns a list of available compilers.
|
50
|
+
def compilers
|
51
|
+
@compilers ||= []
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
# Base class for all compilers, with common functionality. Extend and over-ride as you see fit
|
57
|
+
# (see Javac as an example).
|
58
|
+
class Base #:nodoc:
|
59
|
+
|
60
|
+
class << self
|
61
|
+
|
62
|
+
# The compiler's identifier (e.g. :javac). Inferred from the class name.
|
63
|
+
def to_sym
|
64
|
+
@symbol ||= name.split('::').last.downcase.to_sym
|
65
|
+
end
|
66
|
+
|
67
|
+
# The compiled language (e.g. :java).
|
68
|
+
attr_reader :language
|
69
|
+
# Source directories to use if none were specified (e.g. 'java'). Defaults to #language.
|
70
|
+
attr_reader :sources
|
71
|
+
# Extension for source files (e.g. 'java'). Defaults to language.
|
72
|
+
attr_reader :source_ext
|
73
|
+
# The target path (e.g. 'classes')
|
74
|
+
attr_reader :target
|
75
|
+
# Extension for target files (e.g. 'class').
|
76
|
+
attr_reader :target_ext
|
77
|
+
# The default packaging type (e.g. :jar).
|
78
|
+
attr_reader :packaging
|
79
|
+
|
80
|
+
# Returns true if this compiler applies to any source code found in the listed source
|
81
|
+
# directories. For example, Javac returns true if any of the source directories contains
|
82
|
+
# a .java file. The default implementation looks to see if there are any files in the
|
83
|
+
# specified path with the extension #source_ext.
|
84
|
+
def applies_to?(project, task)
|
85
|
+
paths = task.sources + [sources].flatten.map { |src| Array(project.path_to(:source, task.usage, src.to_sym)) }
|
86
|
+
paths.flatten!
|
87
|
+
ext_glob = Array(source_ext).join(',')
|
88
|
+
paths.any? { |path| !Dir["#{path}/**/*.{#{ext_glob}}"].empty? }
|
89
|
+
end
|
90
|
+
|
91
|
+
# Implementations can use this method to specify various compiler attributes.
|
92
|
+
# For example:
|
93
|
+
# specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
|
94
|
+
def specify(attrs)
|
95
|
+
attrs[:sources] ||= attrs[:language].to_s
|
96
|
+
attrs[:source_ext] ||= attrs[:language].to_s
|
97
|
+
attrs.each { |name, value| instance_variable_set("@#{name}", value) }
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns additional dependencies required by this language. For example, since the
|
101
|
+
# test framework picks on these, you can use the JUnit framework with Scala.
|
102
|
+
# Defaults to obtaining a list of artifact specifications from the REQUIRES constant.
|
103
|
+
def dependencies
|
104
|
+
[]
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
# Construct a new compiler with the specified options. Note that options may
|
110
|
+
# change before the compiler is run.
|
111
|
+
def initialize(project, options)
|
112
|
+
@project = project
|
113
|
+
@options = options
|
114
|
+
end
|
115
|
+
|
116
|
+
# Options for this compiler.
|
117
|
+
attr_reader :options
|
118
|
+
|
119
|
+
# Determines if the compiler needs to run by checking if the target files exist,
|
120
|
+
# and if any source files or dependencies are newer than corresponding target files.
|
121
|
+
def needed?(sources, target, dependencies)
|
122
|
+
map = compile_map(sources, target)
|
123
|
+
return false if map.empty?
|
124
|
+
return true unless File.exist?(target.to_s)
|
125
|
+
source_files_not_yet_compiled = map.select { |source, target| !File.exist?(target) }.to_a
|
126
|
+
trace "Compile needed because source file #{source_files_not_yet_compiled[0][0]} has no corresponding #{source_files_not_yet_compiled[0][1]}" unless source_files_not_yet_compiled.empty?
|
127
|
+
return true if map.any? { |source, target| !File.exist?(target) || File.stat(source).mtime > File.stat(target).mtime }
|
128
|
+
oldest = map.map { |source, target| File.stat(target).mtime }.min
|
129
|
+
return dependencies.any? { |path| file(path).timestamp > oldest }
|
130
|
+
end
|
131
|
+
|
132
|
+
# Compile all files lists in sources (files and directories) into target using the
|
133
|
+
# specified dependencies.
|
134
|
+
def compile(sources, target, dependencies)
|
135
|
+
raise 'Not implemented'
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns additional dependencies required by this language. For example, since the
|
139
|
+
# test framework picks on these, you can use the JUnit framework with Scala.
|
140
|
+
def dependencies
|
141
|
+
self.class.dependencies
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
# Use this to complain about CompileTask options not supported by this compiler.
|
147
|
+
#
|
148
|
+
# For example:
|
149
|
+
# def compile(files, task)
|
150
|
+
# check_options task, OPTIONS
|
151
|
+
# . . .
|
152
|
+
# end
|
153
|
+
def check_options(options, *supported)
|
154
|
+
unsupported = options.to_hash.keys - supported.flatten
|
155
|
+
raise ArgumentError, "No such option: #{unsupported.join(' ')}" unless unsupported.empty?
|
156
|
+
end
|
157
|
+
|
158
|
+
# Expands a list of source directories/files into a list of files that have the #source_ext extension.
|
159
|
+
def files_from_sources(sources)
|
160
|
+
ext_glob = Array(self.class.source_ext).join(',')
|
161
|
+
sources.flatten.map { |source| File.directory?(source) ? FileList["#{source}/**/*.{#{ext_glob}}"] : source }.
|
162
|
+
flatten.reject { |file| File.directory?(file) }.map { |file| File.expand_path(file) }.uniq
|
163
|
+
end
|
164
|
+
|
165
|
+
# The compile map is a hash that associates source files with target files based
|
166
|
+
# on a list of source directories and target directory. The compile task uses this
|
167
|
+
# to determine if there are source files to compile, and which source files to compile.
|
168
|
+
# The default method maps all files in the source directories with #source_ext into
|
169
|
+
# paths in the target directory with #target_ext (e.g. 'source/foo.java'=>'target/foo.class').
|
170
|
+
def compile_map(sources, target)
|
171
|
+
target_ext = self.class.target_ext
|
172
|
+
ext_glob = Array(self.class.source_ext).join(',')
|
173
|
+
sources.flatten.map{|f| File.expand_path(f)}.inject({}) do |map, source|
|
174
|
+
if File.directory?(source)
|
175
|
+
FileList["#{source}/**/*.{#{ext_glob}}"].reject { |file| File.directory?(file) }.
|
176
|
+
each { |file| map[file] = File.join(target, Util.relative_path(file, source).ext(target_ext)) }
|
177
|
+
else
|
178
|
+
# try to extract package name from .java or .scala files
|
179
|
+
if ['.java', '.scala', '.groovy'].include? File.extname(source)
|
180
|
+
package = findFirst(source, /^\s*package\s+(\S+)\s*;?\s*$/)
|
181
|
+
map[source] = package ? File.join(target, package[1].gsub('.', '/'), File.basename(source).ext(target_ext)) : target
|
182
|
+
elsif
|
183
|
+
map[source] = target
|
184
|
+
end
|
185
|
+
end
|
186
|
+
map
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def findFirst(file, pattern)
|
193
|
+
match = nil
|
194
|
+
File.open(file, "r") do |infile|
|
195
|
+
while (line = infile.gets)
|
196
|
+
match = line.match(pattern)
|
197
|
+
break if match
|
198
|
+
end
|
199
|
+
end
|
200
|
+
match
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
# Compile task.
|
208
|
+
#
|
209
|
+
# Attempts to determine which compiler to use based on the project layout, for example,
|
210
|
+
# uses the Javac compiler if it finds any .java files in src/main/java. You can also
|
211
|
+
# select the compiler explicitly:
|
212
|
+
# compile.using(:scalac)
|
213
|
+
#
|
214
|
+
# Accepts multiple source directories that are invoked as prerequisites before compilation.
|
215
|
+
# You can pass a task as a source directory:
|
216
|
+
# compile.from(apt)
|
217
|
+
#
|
218
|
+
# Likewise, dependencies are invoked before compiling. All dependencies are evaluated as
|
219
|
+
# #artifacts, so you can pass artifact specifications and even projects:
|
220
|
+
# compile.with('module1.jar', 'log4j:log4j:jar:1.0', project('foo'))
|
221
|
+
#
|
222
|
+
# Creates a file task for the target directory, so executing that task as a dependency will
|
223
|
+
# execute the compile task first.
|
224
|
+
#
|
225
|
+
# Compiler options are inherited form a parent task, e.g. the foo:bar:compile task inherits
|
226
|
+
# its options from the foo:compile task. Even if foo is an empty project that does not compile
|
227
|
+
# any classes itself, you can use it to set compile options for all its sub-projects.
|
228
|
+
#
|
229
|
+
# Normally, the project will take care of setting the source and target directory, and you
|
230
|
+
# only need to set options and dependencies. See Project#compile.
|
231
|
+
class CompileTask < Rake::Task
|
232
|
+
|
233
|
+
def initialize(*args) #:nodoc:
|
234
|
+
super
|
235
|
+
parent_task = Project.parent_task(name)
|
236
|
+
inherit = lambda { |hash, key| parent_task.options[key] } if parent_task.respond_to?(:options)
|
237
|
+
@options = OpenObject.new &inherit
|
238
|
+
@sources = FileList[]
|
239
|
+
@dependencies = FileList[]
|
240
|
+
|
241
|
+
enhance do |task|
|
242
|
+
unless sources.empty?
|
243
|
+
raise 'No compiler selected and can\'t determine which compiler to use' unless compiler
|
244
|
+
raise 'No target directory specified' unless target
|
245
|
+
mkpath target.to_s
|
246
|
+
info "Compiling #{task.name.gsub(/:[^:]*$/, '')} into #{target.to_s}"
|
247
|
+
@compiler.compile(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
|
248
|
+
# By touching the target we let other tasks know we did something,
|
249
|
+
# and also prevent recompiling again for dependencies.
|
250
|
+
touch target.to_s
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Source directories.
|
256
|
+
attr_accessor :sources
|
257
|
+
|
258
|
+
# :call-seq:
|
259
|
+
# from(*sources) => self
|
260
|
+
#
|
261
|
+
# Adds source directories and files to compile, and returns self.
|
262
|
+
#
|
263
|
+
# For example:
|
264
|
+
# compile.from('src/java').into('classes').with('module1.jar')
|
265
|
+
def from(*sources)
|
266
|
+
@sources |= sources.flatten
|
267
|
+
guess_compiler if @compiler.nil? && sources.flatten.any? { |source| File.exist?(source) }
|
268
|
+
self
|
269
|
+
end
|
270
|
+
|
271
|
+
# *Deprecated*: Use dependencies instead.
|
272
|
+
def classpath
|
273
|
+
Buildr.application.deprecated 'Use dependencies instead.'
|
274
|
+
dependencies
|
275
|
+
end
|
276
|
+
|
277
|
+
# *Deprecated*: Use dependencies= instead.
|
278
|
+
def classpath=(artifacts)
|
279
|
+
Buildr.application.deprecated 'Use dependencies= instead.'
|
280
|
+
self.dependencies = artifacts
|
281
|
+
end
|
282
|
+
|
283
|
+
# Compilation dependencies.
|
284
|
+
attr_accessor :dependencies
|
285
|
+
|
286
|
+
# :call-seq:
|
287
|
+
# with(*artifacts) => self
|
288
|
+
#
|
289
|
+
# Adds files and artifacts as dependencies, and returns self.
|
290
|
+
#
|
291
|
+
# Calls #artifacts on the arguments, so you can pass artifact specifications,
|
292
|
+
# tasks, projects, etc. Use this rather than setting the dependencies array directly.
|
293
|
+
#
|
294
|
+
# For example:
|
295
|
+
# compile.with('module1.jar', 'log4j:log4j:jar:1.0', project('foo'))
|
296
|
+
def with(*specs)
|
297
|
+
@dependencies |= Buildr.artifacts(specs.flatten).uniq
|
298
|
+
self
|
299
|
+
end
|
300
|
+
|
301
|
+
# The target directory for the compiled code.
|
302
|
+
attr_reader :target
|
303
|
+
|
304
|
+
# :call-seq:
|
305
|
+
# into(path) => self
|
306
|
+
#
|
307
|
+
# Sets the target directory and returns self. This will also set the compile task
|
308
|
+
# as a prerequisite to a file task on the target directory.
|
309
|
+
#
|
310
|
+
# For example:
|
311
|
+
# compile(src_dir).into(target_dir).with(artifacts)
|
312
|
+
# Both compile.invoke and file(target_dir).invoke will compile the source files.
|
313
|
+
def into(path)
|
314
|
+
@target = file(path.to_s).enhance([self]) unless @target.to_s == path.to_s
|
315
|
+
self
|
316
|
+
end
|
317
|
+
|
318
|
+
# Returns the compiler options.
|
319
|
+
attr_reader :options
|
320
|
+
|
321
|
+
# :call-seq:
|
322
|
+
# using(options) => self
|
323
|
+
#
|
324
|
+
# Sets the compiler options from a hash and returns self. Can also be used to
|
325
|
+
# select the compiler.
|
326
|
+
#
|
327
|
+
# For example:
|
328
|
+
# compile.using(:warnings=>true, :source=>'1.5')
|
329
|
+
# compile.using(:scala)
|
330
|
+
def using(*args)
|
331
|
+
args.pop.each { |key, value| options.send "#{key}=", value } if Hash === args.last
|
332
|
+
self.compiler = args.pop until args.empty?
|
333
|
+
self
|
334
|
+
end
|
335
|
+
|
336
|
+
# Returns the compiler if known. The compiler is either automatically selected
|
337
|
+
# based on existing source directories (e.g. src/main/java), or by requesting
|
338
|
+
# a specific compiler (see #using).
|
339
|
+
def compiler
|
340
|
+
guess_compiler unless @compiler
|
341
|
+
@compiler && @compiler.class.to_sym
|
342
|
+
end
|
343
|
+
|
344
|
+
# Returns the compiled language, if known. See also #compiler.
|
345
|
+
def language
|
346
|
+
compiler && @compiler.class.language
|
347
|
+
end
|
348
|
+
|
349
|
+
# Returns the default packaging type for this compiler, if known.
|
350
|
+
def packaging
|
351
|
+
compiler && @compiler.class.packaging
|
352
|
+
end
|
353
|
+
|
354
|
+
def timestamp #:nodoc:
|
355
|
+
# If we compiled successfully, then the target directory reflects that.
|
356
|
+
# If we didn't, see needed?
|
357
|
+
target ? target.timestamp : Rake::EARLY
|
358
|
+
end
|
359
|
+
|
360
|
+
# The project this task belongs to.
|
361
|
+
attr_reader :project
|
362
|
+
|
363
|
+
# The usage, one of :main or :test.
|
364
|
+
attr_reader :usage
|
365
|
+
|
366
|
+
protected
|
367
|
+
|
368
|
+
# Selects which compiler to use.
|
369
|
+
def compiler=(name) #:nodoc:
|
370
|
+
cls = Compiler.select(name) or raise ArgumentError, "No #{name} compiler available. Did you install it?"
|
371
|
+
return self if cls === @compiler
|
372
|
+
raise "#{compiler} compiler already selected for this project" if @compiler
|
373
|
+
@compiler = cls.new(project, options)
|
374
|
+
from Array(cls.sources).map { |path| project.path_to(:source, usage, path) }.
|
375
|
+
select { |path| File.exist?(path) } if sources.empty?
|
376
|
+
into project.path_to(:target, usage, cls.target) unless target
|
377
|
+
with Array(@compiler.dependencies)
|
378
|
+
self
|
379
|
+
end
|
380
|
+
|
381
|
+
# Associates this task with project and particular usage (:main, :test).
|
382
|
+
def associate_with(project, usage) #:nodoc:
|
383
|
+
@project, @usage = project, usage
|
384
|
+
guess_compiler
|
385
|
+
end
|
386
|
+
|
387
|
+
# Try to guess if we have a compiler to match source files.
|
388
|
+
def guess_compiler #:nodoc:
|
389
|
+
candidate = Compiler.compilers.detect { |cls| cls.applies_to?(project, self) }
|
390
|
+
self.compiler = candidate if candidate
|
391
|
+
end
|
392
|
+
|
393
|
+
private
|
394
|
+
|
395
|
+
def needed? #:nodoc:
|
396
|
+
return false if sources.empty?
|
397
|
+
# Fail during invoke.
|
398
|
+
return true unless @compiler && target
|
399
|
+
return @compiler.needed?(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
|
400
|
+
end
|
401
|
+
|
402
|
+
def invoke_prerequisites(args, chain) #:nodoc:
|
403
|
+
@sources = Array(@sources).map(&:to_s).uniq
|
404
|
+
@dependencies = FileList[@dependencies.uniq]
|
405
|
+
@prerequisites |= @dependencies + @sources
|
406
|
+
super
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
|
412
|
+
# The resources task is executed by the compile task to copy resource files over
|
413
|
+
# to the target directory. You can enhance this task in the normal way, but mostly
|
414
|
+
# you will use the task's filter.
|
415
|
+
#
|
416
|
+
# For example:
|
417
|
+
# resources.filter.using 'Copyright'=>'Acme Inc, 2007'
|
418
|
+
class ResourcesTask < Rake::Task
|
419
|
+
|
420
|
+
# Returns the filter used to copy resources over. See Buildr::Filter.
|
421
|
+
attr_reader :filter
|
422
|
+
|
423
|
+
def initialize(*args) #:nodoc:
|
424
|
+
super
|
425
|
+
@filter = Buildr::Filter.new
|
426
|
+
@filter.using Buildr.settings.profile['filter'] if Hash === Buildr.settings.profile['filter']
|
427
|
+
enhance do
|
428
|
+
target.invoke if target
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
# :call-seq:
|
433
|
+
# include(*files) => self
|
434
|
+
#
|
435
|
+
# Includes the specified files in the filter and returns self.
|
436
|
+
def include(*files)
|
437
|
+
filter.include *files
|
438
|
+
self
|
439
|
+
end
|
440
|
+
|
441
|
+
# :call-seq:
|
442
|
+
# exclude(*files) => self
|
443
|
+
#
|
444
|
+
# Excludes the specified files in the filter and returns self.
|
445
|
+
def exclude(*files)
|
446
|
+
filter.exclude *files
|
447
|
+
self
|
448
|
+
end
|
449
|
+
|
450
|
+
# :call-seq:
|
451
|
+
# from(*sources) => self
|
452
|
+
#
|
453
|
+
# Adds additional directories from which to copy resources.
|
454
|
+
#
|
455
|
+
# For example:
|
456
|
+
# resources.from _('src/etc')
|
457
|
+
def from(*sources)
|
458
|
+
filter.from *sources
|
459
|
+
self
|
460
|
+
end
|
461
|
+
|
462
|
+
# Returns the list of source directories (each being a file task).
|
463
|
+
def sources
|
464
|
+
filter.sources
|
465
|
+
end
|
466
|
+
|
467
|
+
# :call-seq:
|
468
|
+
# target => task
|
469
|
+
#
|
470
|
+
# Returns the filter's target directory as a file task.
|
471
|
+
def target
|
472
|
+
filter.into @project.path_to(:target, @usage, :resources) unless filter.target || sources.empty?
|
473
|
+
filter.target
|
474
|
+
end
|
475
|
+
|
476
|
+
def prerequisites #:nodoc:
|
477
|
+
super + filter.sources.flatten
|
478
|
+
end
|
479
|
+
|
480
|
+
protected
|
481
|
+
|
482
|
+
# Associates this task with project and particular usage (:main, :test).
|
483
|
+
def associate_with(project, usage) #:nodoc:
|
484
|
+
@project, @usage = project, usage
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|
488
|
+
|
489
|
+
|
490
|
+
# Methods added to Project for compiling, handling of resources and generating source documentation.
|
491
|
+
module Compile
|
492
|
+
|
493
|
+
include Extension
|
494
|
+
|
495
|
+
first_time do
|
496
|
+
desc 'Compile all projects'
|
497
|
+
Project.local_task('compile') { |name| "Compiling #{name}" }
|
498
|
+
end
|
499
|
+
|
500
|
+
before_define do |project|
|
501
|
+
resources = ResourcesTask.define_task('resources')
|
502
|
+
resources.send :associate_with, project, :main
|
503
|
+
project.path_to(:source, :main, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
|
504
|
+
|
505
|
+
compile = CompileTask.define_task('compile'=>resources)
|
506
|
+
compile.send :associate_with, project, :main
|
507
|
+
project.recursive_task('compile')
|
508
|
+
end
|
509
|
+
|
510
|
+
after_define do |project|
|
511
|
+
if project.compile.target
|
512
|
+
# This comes last because the target path is set inside the project definition.
|
513
|
+
project.build project.compile.target
|
514
|
+
project.clean do
|
515
|
+
rm_rf project.compile.target.to_s, :verbose=>false
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
|
521
|
+
# :call-seq:
|
522
|
+
# compile(*sources) => CompileTask
|
523
|
+
# compile(*sources) { |task| .. } => CompileTask
|
524
|
+
#
|
525
|
+
# The compile task does what its name suggests. This method returns the project's
|
526
|
+
# CompileTask. It also accepts a list of source directories and files to compile
|
527
|
+
# (equivalent to calling CompileTask#from on the task), and a block for any
|
528
|
+
# post-compilation work.
|
529
|
+
#
|
530
|
+
# The compile task attempts to guess which compiler to use. For example, if it finds
|
531
|
+
# any Java files in the src/main/java directory, it will use the Java compiler and
|
532
|
+
# create class files in the target/classes directory.
|
533
|
+
#
|
534
|
+
# You can also configure it yourself by telling it which compiler to use, pointing
|
535
|
+
# it as source directories and chooing a different target directory.
|
536
|
+
#
|
537
|
+
# For example:
|
538
|
+
# # Include Log4J and the api sub-project artifacts.
|
539
|
+
# compile.with 'log4j:log4j:jar:1.2', project('api')
|
540
|
+
# # Include Apt-generated source files.
|
541
|
+
# compile.from apt
|
542
|
+
# # For JavaC, force target compatibility.
|
543
|
+
# compile.options.source = '1.6'
|
544
|
+
# # Run the OpenJPA bytecode enhancer after compilation.
|
545
|
+
# compile { open_jpa_enhance }
|
546
|
+
# # Pick a given compiler.
|
547
|
+
# compile.using(:scalac).from('src/scala')
|
548
|
+
#
|
549
|
+
# For more information, see CompileTask.
|
550
|
+
def compile(*sources, &block)
|
551
|
+
task('compile').from(sources).enhance &block
|
552
|
+
end
|
553
|
+
|
554
|
+
# :call-seq:
|
555
|
+
# resources(*prereqs) => ResourcesTask
|
556
|
+
# resources(*prereqs) { |task| .. } => ResourcesTask
|
557
|
+
#
|
558
|
+
# The resources task is executed by the compile task to copy resources files
|
559
|
+
# from the resource directory into the target directory. By default the resources
|
560
|
+
# task copies files from the src/main/resources into the target/resources directory.
|
561
|
+
#
|
562
|
+
# This method returns the project's resources task. It also accepts a list of
|
563
|
+
# prerequisites and a block, used to enhance the resources task.
|
564
|
+
#
|
565
|
+
# Resources files are copied and filtered (see Buildr::Filter for more information).
|
566
|
+
# The default filter uses the profile properties for the current environment.
|
567
|
+
#
|
568
|
+
# For example:
|
569
|
+
# resources.from _('src/etc')
|
570
|
+
# resources.filter.using 'Copyright'=>'Acme Inc, 2007'
|
571
|
+
#
|
572
|
+
# Or in your profiles.yaml file:
|
573
|
+
# common:
|
574
|
+
# Copyright: Acme Inc, 2007
|
575
|
+
def resources(*prereqs, &block)
|
576
|
+
task('resources').enhance prereqs, &block
|
577
|
+
end
|
578
|
+
|
579
|
+
end
|
580
|
+
|
581
|
+
|
582
|
+
class Options
|
583
|
+
|
584
|
+
# Returns the debug option (environment variable DEBUG).
|
585
|
+
def debug
|
586
|
+
(ENV['DEBUG'] || ENV['debug']) !~ /(no|off|false)/
|
587
|
+
end
|
588
|
+
|
589
|
+
# Sets the debug option (environment variable DEBUG).
|
590
|
+
#
|
591
|
+
# You can turn this option off directly, or by setting the environment variable
|
592
|
+
# DEBUG to +no+. For example:
|
593
|
+
# buildr build DEBUG=no
|
594
|
+
#
|
595
|
+
# The release tasks runs a build with <tt>DEBUG=no</tt>.
|
596
|
+
def debug=(flag)
|
597
|
+
ENV['debug'] = nil
|
598
|
+
ENV['DEBUG'] = flag.to_s
|
599
|
+
end
|
600
|
+
|
601
|
+
end
|
602
|
+
|
603
|
+
end
|
604
|
+
|
605
|
+
|
606
|
+
class Buildr::Project
|
607
|
+
include Buildr::Compile
|
608
|
+
end
|