buildr 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +566 -268
- data/DISCLAIMER +7 -1
- data/KEYS +151 -0
- data/NOTICE +23 -8
- data/README +122 -22
- data/Rakefile +49 -229
- data/{lib → addon}/buildr/antlr.rb +23 -10
- data/addon/buildr/cobertura.rb +232 -0
- data/{lib → addon}/buildr/hibernate.rb +20 -4
- data/{lib → addon}/buildr/javacc.rb +27 -12
- data/addon/buildr/jdepend.rb +60 -0
- data/{lib → addon}/buildr/jetty.rb +34 -18
- data/addon/buildr/nailgun.rb +892 -0
- data/{lib → addon}/buildr/openjpa.rb +23 -6
- data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
- data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
- data/{lib → addon}/buildr/xmlbeans.rb +39 -14
- data/bin/buildr +21 -7
- data/buildr.gemspec +50 -0
- data/doc/css/default.css +225 -0
- data/doc/css/print.css +95 -0
- data/doc/css/syntax.css +43 -0
- data/doc/images/apache-incubator-logo.png +0 -0
- data/doc/images/buildr-hires.png +0 -0
- data/doc/images/buildr.png +0 -0
- data/doc/images/note.png +0 -0
- data/doc/images/tip.png +0 -0
- data/doc/images/zbuildr.tif +0 -0
- data/doc/pages/artifacts.textile +317 -0
- data/doc/pages/building.textile +501 -0
- data/doc/pages/contributing.textile +178 -0
- data/doc/pages/download.textile +25 -0
- data/doc/pages/extending.textile +229 -0
- data/doc/pages/getting_started.textile +337 -0
- data/doc/pages/index.textile +63 -0
- data/doc/pages/mailing_lists.textile +17 -0
- data/doc/pages/more_stuff.textile +367 -0
- data/doc/pages/packaging.textile +592 -0
- data/doc/pages/projects.textile +449 -0
- data/doc/pages/recipes.textile +127 -0
- data/doc/pages/settings_profiles.textile +339 -0
- data/doc/pages/testing.textile +475 -0
- data/doc/pages/troubleshooting.textile +121 -0
- data/doc/pages/whats_new.textile +389 -0
- data/doc/print.haml +52 -0
- data/doc/print.toc.yaml +28 -0
- data/doc/scripts/buildr-git.rb +411 -0
- data/doc/scripts/install-jruby.sh +44 -0
- data/doc/scripts/install-linux.sh +64 -0
- data/doc/scripts/install-osx.sh +52 -0
- data/doc/site.haml +55 -0
- data/doc/site.toc.yaml +44 -0
- data/lib/buildr.rb +28 -45
- data/lib/buildr/core.rb +27 -0
- data/lib/buildr/core/application.rb +373 -0
- data/lib/buildr/core/application_cli.rb +134 -0
- data/lib/{core → buildr/core}/build.rb +91 -77
- data/lib/{core → buildr/core}/checks.rb +116 -95
- data/lib/buildr/core/common.rb +155 -0
- data/lib/buildr/core/compile.rb +594 -0
- data/lib/buildr/core/environment.rb +120 -0
- data/lib/buildr/core/filter.rb +258 -0
- data/lib/{core → buildr/core}/generate.rb +22 -5
- data/lib/buildr/core/help.rb +118 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/{core → buildr/core}/project.rb +468 -213
- data/lib/buildr/core/test.rb +690 -0
- data/lib/{core → buildr/core}/transports.rb +107 -127
- data/lib/buildr/core/util.rb +235 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/{java → buildr/ide}/eclipse.rb +86 -60
- data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
- data/lib/buildr/ide/idea.rb +194 -0
- data/lib/buildr/ide/idea7x.ipr.template +290 -0
- data/lib/buildr/ide/idea7x.rb +210 -0
- data/lib/buildr/java.rb +26 -0
- data/lib/buildr/java/ant.rb +71 -0
- data/lib/buildr/java/bdd_frameworks.rb +267 -0
- data/lib/buildr/java/commands.rb +210 -0
- data/lib/buildr/java/compilers.rb +432 -0
- data/lib/buildr/java/deprecated.rb +141 -0
- data/lib/buildr/java/groovyc.rb +137 -0
- data/lib/buildr/java/jruby.rb +99 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
- data/lib/buildr/java/packaging.rb +706 -0
- data/lib/{java → buildr/java}/pom.rb +20 -4
- data/lib/buildr/java/rjb.rb +142 -0
- data/lib/buildr/java/test_frameworks.rb +290 -0
- data/lib/buildr/java/version_requirement.rb +172 -0
- data/lib/buildr/packaging.rb +21 -0
- data/lib/{java → buildr/packaging}/artifact.rb +170 -179
- data/lib/buildr/packaging/artifact_namespace.rb +957 -0
- data/lib/buildr/packaging/artifact_search.rb +140 -0
- data/lib/buildr/packaging/gems.rb +102 -0
- data/lib/buildr/packaging/package.rb +233 -0
- data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
- data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
- data/rakelib/apache.rake +126 -0
- data/rakelib/changelog.rake +56 -0
- data/rakelib/doc.rake +103 -0
- data/rakelib/package.rake +44 -0
- data/rakelib/release.rake +53 -0
- data/rakelib/rspec.rake +81 -0
- data/rakelib/rubyforge.rake +45 -0
- data/rakelib/scm.rake +49 -0
- data/rakelib/setup.rake +59 -0
- data/rakelib/stage.rake +45 -0
- data/spec/application_spec.rb +316 -0
- data/spec/archive_spec.rb +494 -0
- data/spec/artifact_namespace_spec.rb +635 -0
- data/spec/artifact_spec.rb +738 -0
- data/spec/build_spec.rb +193 -0
- data/spec/checks_spec.rb +537 -0
- data/spec/common_spec.rb +579 -0
- data/spec/compile_spec.rb +561 -0
- data/spec/groovy_compilers_spec.rb +239 -0
- data/spec/java_bdd_frameworks_spec.rb +238 -0
- data/spec/java_compilers_spec.rb +446 -0
- data/spec/java_packaging_spec.rb +1042 -0
- data/spec/java_test_frameworks_spec.rb +414 -0
- data/spec/packaging_helper.rb +63 -0
- data/spec/packaging_spec.rb +589 -0
- data/spec/project_spec.rb +739 -0
- data/spec/sandbox.rb +116 -0
- data/spec/scala_compilers_spec.rb +239 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helpers.rb +283 -0
- data/spec/test_spec.rb +871 -0
- data/spec/transport_spec.rb +300 -0
- data/spec/version_requirement_spec.rb +115 -0
- metadata +188 -77
- data/lib/buildr/cobertura.rb +0 -89
- data/lib/buildr/jdepend.rb +0 -40
- data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
- data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
- data/lib/buildr/jetty/JettyWrapper.class +0 -0
- data/lib/buildr/scala.rb +0 -368
- data/lib/core/application.rb +0 -188
- data/lib/core/common.rb +0 -562
- data/lib/core/help.rb +0 -72
- data/lib/core/rake_ext.rb +0 -81
- data/lib/java/ant.rb +0 -71
- data/lib/java/compile.rb +0 -589
- data/lib/java/idea.rb +0 -159
- data/lib/java/java.rb +0 -432
- data/lib/java/packaging.rb +0 -581
- data/lib/java/test.rb +0 -795
- data/lib/tasks/concat.rb +0 -35
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
class ProgressBar
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
|
|
21
|
+
def start(args, &block)
|
|
22
|
+
new(args).start &block
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def width
|
|
26
|
+
@width ||= $terminal.output_cols || 80
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def initialize(args = {})
|
|
32
|
+
@title = args[:title] || ''
|
|
33
|
+
@total = args[:total] || 0
|
|
34
|
+
@mark = args[:mark] || '.'
|
|
35
|
+
@format = args[:format] || default_format
|
|
36
|
+
@output = args[:output] || $stderr unless args[:hidden] || !$stdout.isatty
|
|
37
|
+
clear
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def start
|
|
41
|
+
@start = @last_time = Time.now
|
|
42
|
+
@count = 0
|
|
43
|
+
@finished = false
|
|
44
|
+
render
|
|
45
|
+
if block_given?
|
|
46
|
+
result = yield(self) if block_given?
|
|
47
|
+
finish
|
|
48
|
+
result
|
|
49
|
+
else
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def inc(count)
|
|
55
|
+
set @count + count
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def <<(bytes)
|
|
59
|
+
inc bytes.size
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def set(count)
|
|
63
|
+
@count = [count, 0].max
|
|
64
|
+
@count = [count, @total].min unless @total == 0
|
|
65
|
+
render if changed?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def title
|
|
69
|
+
@title.size > ProgressBar.width / 5 ? (@title[0, ProgressBar.width / 5 - 2] + '..') : @title
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def count
|
|
73
|
+
human(@count)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def total
|
|
77
|
+
human(@total)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def percentage
|
|
81
|
+
'%3d%%' % (@total == 0 ? 100 : (@count * 100 / @total))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def time
|
|
85
|
+
@finished ? elapsed : eta
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def eta
|
|
89
|
+
return 'ETA: --:--:--' if @count == 0
|
|
90
|
+
elapsed = Time.now - @start
|
|
91
|
+
eta = elapsed * @total / @count - elapsed
|
|
92
|
+
'ETA: %s' % duration(eta.ceil)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def elapsed
|
|
96
|
+
'Time: %s' % duration(Time.now - @start)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def rate
|
|
100
|
+
'%s/s' % human(@count / (Time.now - @start))
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def progress(width)
|
|
104
|
+
width -= 2
|
|
105
|
+
marks = @total == 0 ? width : (@count * width / @total)
|
|
106
|
+
"|%-#{width}s|" % (@mark * marks)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def human(bytes)
|
|
110
|
+
magnitude = (0..3).find { |i| bytes < (1024 << i * 10) } || 3
|
|
111
|
+
return '%dB' % bytes if magnitude == 0
|
|
112
|
+
return '%.1f%s' % [ bytes.to_f / (1 << magnitude * 10), [nil, 'KB', 'MB', 'GB'][magnitude] ]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def duration(seconds)
|
|
116
|
+
'%02d:%02d:%02d' % [seconds / 3600, (seconds / 60) % 60, seconds % 60]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def finish
|
|
120
|
+
unless @finished
|
|
121
|
+
@finished = true
|
|
122
|
+
render
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
protected
|
|
127
|
+
|
|
128
|
+
def clear
|
|
129
|
+
return unless @output
|
|
130
|
+
@output.print "\r", " " * (ProgressBar.width - 1), "\r"
|
|
131
|
+
@output.flush
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def render
|
|
135
|
+
return unless @output
|
|
136
|
+
format, *args = @format
|
|
137
|
+
line = format % args.map { |arg| send(arg) }
|
|
138
|
+
@output.print line.sub('|--|') { progress(ProgressBar.width - line.size + 3) }
|
|
139
|
+
@output.print @finished ? "\n" : "\r"
|
|
140
|
+
@output.flush
|
|
141
|
+
@previous = @count
|
|
142
|
+
@last_time = Time.now
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def changed?
|
|
146
|
+
return false unless @output
|
|
147
|
+
return human(@count) != human(@previous) if @total == 0
|
|
148
|
+
return true if (@count - @previous) >= @total / 100
|
|
149
|
+
return Time.now - @last_time > 1
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def default_format
|
|
153
|
+
@total == 0 ? ['%s %8s %s', :title, :count, :elapsed] : ['%s: %s |--| %8s/%s %s', :title, :percentage, :count, :total, :time]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
@@ -1,46 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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/util'
|
|
18
|
+
|
|
3
19
|
|
|
4
20
|
module Buildr
|
|
5
21
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
|
|
22
|
+
# Symbolic mapping for directory layout. Used for both the default and custom layouts.
|
|
23
|
+
#
|
|
24
|
+
# For example, the default layout maps [:source, :main, :java] to 'src/main/java', and
|
|
25
|
+
# [:target, :main, :classes] to 'target/classes'. You can use this to change the layout
|
|
26
|
+
# of your projects.
|
|
27
|
+
#
|
|
28
|
+
# To map [:source, :main] into the 'sources' directory:
|
|
29
|
+
# my_layout = Layout.new
|
|
30
|
+
# my_layout[:source, :main] = 'sources'
|
|
31
|
+
#
|
|
32
|
+
# define 'foo', :layout=>my_layout do
|
|
33
|
+
# ...
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# To map [:source, :main, :java] to 'java/main':
|
|
37
|
+
# class MainLast < Layout
|
|
38
|
+
# def expand(*args)
|
|
39
|
+
# if args[0..1] == [:source, :main]
|
|
40
|
+
# super args[2], :main, *args[3,]
|
|
41
|
+
# else
|
|
42
|
+
# super
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# define 'foo', :layout=>MainLast do
|
|
48
|
+
# ...
|
|
49
|
+
# end
|
|
50
|
+
class Layout
|
|
11
51
|
|
|
12
52
|
class << self
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
53
|
+
|
|
54
|
+
# Default layout used by new projects.
|
|
55
|
+
attr_accessor :default
|
|
56
|
+
|
|
17
57
|
end
|
|
18
58
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
def initialize #:nodoc:
|
|
60
|
+
@mapping = {}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Expands list of symbols and path names into a full path, for example:
|
|
64
|
+
# puts default.expand(:source, :main, :java)
|
|
65
|
+
# => "src/main/java"
|
|
66
|
+
def expand(*args)
|
|
67
|
+
return '' if args.empty?
|
|
68
|
+
@mapping[args] ||= File.join(*[expand(*args[0..-2]), args.last.to_s].reject(&:empty?)) if args.size > 1
|
|
69
|
+
return @mapping[args] || args.first.to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Resolves a list of symbols into a path.
|
|
73
|
+
def [](*args)
|
|
74
|
+
@mapping[args.map(&:to_sym)]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Specifies the path resolved from a list of symbols.
|
|
78
|
+
def []=(*args)
|
|
79
|
+
@mapping[args[0...-1].map(&:to_sym)] = args.last
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def initialize_copy(copy)
|
|
83
|
+
copy.instance_variable_set :@mapping, @mapping.clone
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Default layout has the following properties:
|
|
87
|
+
# * :source maps to the 'src' directory.
|
|
88
|
+
# * Anything under :source maps verbatim (e.g. :source, :main becomes 'src/main')
|
|
89
|
+
# * :target maps to the 'target' directory.
|
|
90
|
+
# * :target, :main maps to the 'target' directory as well.
|
|
91
|
+
# * Anything under :target, :main maps verbatim (e.g. :target, :main, :classes becomes 'target/classes')
|
|
92
|
+
# * Anything else under :target also maps verbatim (e.g. :target, :test becomes 'target/test')
|
|
93
|
+
class Default < Layout
|
|
94
|
+
|
|
95
|
+
def initialize
|
|
96
|
+
super
|
|
97
|
+
self[:source] = 'src'
|
|
98
|
+
self[:target, :main] = 'target'
|
|
41
99
|
end
|
|
42
|
-
|
|
100
|
+
|
|
43
101
|
end
|
|
102
|
+
|
|
103
|
+
self.default = Default.new
|
|
104
|
+
|
|
44
105
|
end
|
|
45
106
|
|
|
46
107
|
|
|
@@ -89,34 +150,39 @@ module Buildr
|
|
|
89
150
|
# | |__resources <-- Resources to copy (tests)
|
|
90
151
|
# |__target <-- Packages created here
|
|
91
152
|
# | |__classes <-- Generated when compiling
|
|
92
|
-
# | |
|
|
153
|
+
# | |__resources <-- Copied (and filtered) from resources
|
|
154
|
+
# | |__test/classes <-- Generated when compiling tests
|
|
155
|
+
# | |__test/resources <-- Copied (and filtered) from resources
|
|
156
|
+
# |__reports <-- Test, coverage and other reports
|
|
157
|
+
#
|
|
158
|
+
# You can change the project layout by passing a new Layout to the project definition.
|
|
93
159
|
#
|
|
94
160
|
# You can only define a project once using #define. Afterwards, you can obtain the project
|
|
95
161
|
# definition using #project. The order in which you define projects is not important,
|
|
96
162
|
# project definitions are evaluated when you ask for them. Circular dependencies will not
|
|
97
163
|
# work. Rake tasks are only created after the project is evaluated, so if you need to access
|
|
98
|
-
# a task (e.g. compile) use <code>project(
|
|
164
|
+
# a task (e.g. compile) use <code>project('foo').compile</code> instead of <code>task('foo:compile')</code>.
|
|
99
165
|
#
|
|
100
166
|
# For example:
|
|
101
|
-
# define
|
|
167
|
+
# define 'myapp', :version=>'1.1' do
|
|
102
168
|
#
|
|
103
|
-
# define
|
|
104
|
-
# compile.with project(
|
|
169
|
+
# define 'wepapp' do
|
|
170
|
+
# compile.with project('myapp:beans')
|
|
105
171
|
# package :war
|
|
106
172
|
# end
|
|
107
173
|
#
|
|
108
|
-
# define
|
|
174
|
+
# define 'beans' do
|
|
109
175
|
# compile.with DEPENDS
|
|
110
176
|
# package :jar
|
|
111
177
|
# end
|
|
112
178
|
# end
|
|
113
179
|
#
|
|
114
180
|
# puts projects.map(&:name)
|
|
115
|
-
# => [
|
|
116
|
-
# puts project(
|
|
117
|
-
# =>
|
|
118
|
-
# puts project(
|
|
119
|
-
# =>
|
|
181
|
+
# => [ 'myapp', 'myapp:beans', 'myapp:webapp' ]
|
|
182
|
+
# puts project('myapp:webapp').parent.name
|
|
183
|
+
# => 'myapp'
|
|
184
|
+
# puts project('myapp:webapp').compile.classpath.map(&:to_spec)
|
|
185
|
+
# => 'myapp:myapp-beans:jar:1.1'
|
|
120
186
|
class Project < Rake::Task
|
|
121
187
|
|
|
122
188
|
class << self
|
|
@@ -129,16 +195,28 @@ module Buildr
|
|
|
129
195
|
# Make sure a sub-project is only defined within the parent project,
|
|
130
196
|
# to prevent silly mistakes that lead to inconsistencies (e.g.
|
|
131
197
|
# namespaces will be all out of whack).
|
|
132
|
-
|
|
198
|
+
Buildr.application.current_scope == name.split(':')[0...-1] or
|
|
133
199
|
raise "You can only define a sub project (#{name}) within the definition of its parent project"
|
|
134
200
|
|
|
135
201
|
@projects ||= {}
|
|
136
202
|
raise "You cannot define the same project (#{name}) more than once" if @projects[name]
|
|
203
|
+
# Projects with names like: compile, test, build are invalid, so we have
|
|
204
|
+
# to make sure the project has not the name of an already defined task
|
|
205
|
+
raise "Invalid project name: #{name.inspect} is already used for a task" if Buildr.application.lookup(name)
|
|
206
|
+
|
|
137
207
|
Project.define_task(name).tap do |project|
|
|
138
208
|
# Define the project to prevent duplicate definition.
|
|
139
209
|
@projects[name] = project
|
|
140
210
|
# Set the project properties first, actions may use them.
|
|
141
211
|
properties.each { |name, value| project.send "#{name}=", value } if properties
|
|
212
|
+
# Instantiate callbacks for this project, and setup to call before/after define.
|
|
213
|
+
# Don't cache list of callbacks, since project may add new callbacks.
|
|
214
|
+
project.enhance do |project|
|
|
215
|
+
project.send :call_callbacks, :before_define
|
|
216
|
+
project.enhance do |project|
|
|
217
|
+
project.send :call_callbacks, :after_define
|
|
218
|
+
end
|
|
219
|
+
end
|
|
142
220
|
project.enhance do |project|
|
|
143
221
|
@on_define.each { |callback| callback[project] }
|
|
144
222
|
end if @on_define
|
|
@@ -146,7 +224,7 @@ module Buildr
|
|
|
146
224
|
project.enhance { project.instance_eval &block } if block
|
|
147
225
|
|
|
148
226
|
# Top-level project? Invoke the project definition. Sub-project? We don't invoke
|
|
149
|
-
# the project definiton yet (allow project
|
|
227
|
+
# the project definiton yet (allow project calls to establish order of evaluation),
|
|
150
228
|
# but must do so before the parent project's definition is done.
|
|
151
229
|
project.parent.enhance { project.invoke } if project.parent
|
|
152
230
|
end
|
|
@@ -159,18 +237,18 @@ module Buildr
|
|
|
159
237
|
def project(*args) #:nodoc:
|
|
160
238
|
options = args.pop if Hash === args.last
|
|
161
239
|
rake_check_options options, :scope if options
|
|
162
|
-
raise ArgumentError,
|
|
240
|
+
raise ArgumentError, 'Only one project name at a time' unless args.size == 1
|
|
163
241
|
@projects ||= {}
|
|
164
242
|
name = args.first
|
|
165
243
|
if options && options[:scope]
|
|
166
244
|
# We assume parent project is evaluated.
|
|
167
|
-
project = options[:scope].split(
|
|
168
|
-
map { |scope| @projects[(scope + [name]).join(
|
|
245
|
+
project = options[:scope].split(':').inject([[]]) { |scopes, scope| scopes << (scopes.last + [scope]) }.
|
|
246
|
+
map { |scope| @projects[(scope + [name]).join(':')] }.
|
|
169
247
|
select { |project| project }.last
|
|
170
248
|
end
|
|
171
249
|
unless project
|
|
172
250
|
# Parent project not evaluated.
|
|
173
|
-
name.split(
|
|
251
|
+
name.split(':').tap { |parts| @projects[parts.first].invoke if parts.size > 1 }
|
|
174
252
|
project = @projects[name]
|
|
175
253
|
end
|
|
176
254
|
raise "No such project #{name}" unless project
|
|
@@ -202,16 +280,16 @@ module Buildr
|
|
|
202
280
|
@projects.keys.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
|
|
203
281
|
else
|
|
204
282
|
# Parent project(s) not evaluated, for the sub-projects we may need to find.
|
|
205
|
-
names.map { |name| name.split(
|
|
283
|
+
names.map { |name| name.split(':') }.select { |name| name.size > 1 }.map(&:first).uniq.each { |name| project(name) }
|
|
206
284
|
names.uniq.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
|
|
207
285
|
end
|
|
208
286
|
end
|
|
209
287
|
|
|
210
288
|
# :call-seq:
|
|
211
|
-
# clear
|
|
289
|
+
# clear
|
|
212
290
|
#
|
|
213
291
|
# Discard all project definitions.
|
|
214
|
-
def clear
|
|
292
|
+
def clear
|
|
215
293
|
@projects.clear if @projects
|
|
216
294
|
end
|
|
217
295
|
|
|
@@ -246,21 +324,9 @@ module Buildr
|
|
|
246
324
|
end
|
|
247
325
|
end
|
|
248
326
|
|
|
249
|
-
#
|
|
250
|
-
# on_define() { |project| ... }
|
|
251
|
-
#
|
|
252
|
-
# The Project class defines minimal behavior, only what is documented here.
|
|
253
|
-
# To extend its definition, other modules use Project#on_define to incorporate
|
|
254
|
-
# code called during a new project's definition.
|
|
255
|
-
#
|
|
256
|
-
# For example:
|
|
257
|
-
# # Set the default version of each project to "1.0".
|
|
258
|
-
# Project.on_define { |project| project.version ||= "1.0" }
|
|
259
|
-
#
|
|
260
|
-
# Since each project definition is essentially a task, if you need to do work
|
|
261
|
-
# at the end of the project definition (after the block is executed), you can
|
|
262
|
-
# enhance it from within #on_define.
|
|
327
|
+
# *Deprecated* Check the Extension module to see how extensions are handled.
|
|
263
328
|
def on_define(&block)
|
|
329
|
+
Buildr.application.deprecated 'This method is deprecated, see Extension'
|
|
264
330
|
(@on_define ||= []) << block if block
|
|
265
331
|
end
|
|
266
332
|
|
|
@@ -269,13 +335,13 @@ module Buildr
|
|
|
269
335
|
end
|
|
270
336
|
|
|
271
337
|
def local_projects(dir = nil, &block) #:nodoc:
|
|
272
|
-
dir = File.expand_path(dir ||
|
|
338
|
+
dir = File.expand_path(dir || Buildr.application.original_dir)
|
|
273
339
|
projects = Project.projects.select { |project| project.base_dir == dir }
|
|
274
340
|
if projects.empty? && dir != Dir.pwd && File.dirname(dir) != dir
|
|
275
341
|
local_projects(File.dirname(dir), &block)
|
|
276
342
|
elsif block
|
|
277
343
|
if projects.empty?
|
|
278
|
-
warn "No projects defined for directory #{
|
|
344
|
+
warn "No projects defined for directory #{Buildr.application.original_dir}" if verbose
|
|
279
345
|
else
|
|
280
346
|
projects.each { |project| block[project] }
|
|
281
347
|
end
|
|
@@ -285,23 +351,38 @@ module Buildr
|
|
|
285
351
|
end
|
|
286
352
|
|
|
287
353
|
# :call-seq:
|
|
288
|
-
#
|
|
354
|
+
# parent_task(task_name) => task_name or nil
|
|
289
355
|
#
|
|
290
|
-
#
|
|
291
|
-
#
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
namespace = task_name.split(":")
|
|
356
|
+
# Returns a parent task, basically a task in a higher namespace. For example, the parent
|
|
357
|
+
# of 'foo:test:compile' is 'foo:compile' and the parent of 'foo:compile' is 'compile'.
|
|
358
|
+
def parent_task(task_name) #:nodoc:
|
|
359
|
+
namespace = task_name.split(':')
|
|
295
360
|
last_name = namespace.pop
|
|
296
361
|
namespace.pop
|
|
297
|
-
|
|
362
|
+
Buildr.application.lookup((namespace + [last_name]).join(':'), []) unless namespace.empty?
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# :call-seq:
|
|
366
|
+
# project_from_task(task) => project
|
|
367
|
+
#
|
|
368
|
+
# Figure out project associated to this task and return it.
|
|
369
|
+
def project_from_task(task) #:nodoc:
|
|
370
|
+
project = Buildr.application.lookup('rake:' + task.to_s.gsub(/:[^:]*$/, ''))
|
|
371
|
+
project if Project === project
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# Callback classes.
|
|
375
|
+
def callbacks #:nodoc:
|
|
376
|
+
@callbacks ||= []
|
|
298
377
|
end
|
|
299
378
|
|
|
300
379
|
end
|
|
301
380
|
|
|
302
|
-
include InheritedAttributes
|
|
303
381
|
|
|
304
|
-
#
|
|
382
|
+
# Project has visibility to everything in the Buildr namespace.
|
|
383
|
+
include Buildr
|
|
384
|
+
|
|
385
|
+
# The project name. For example, 'foo' for the top-level project, and 'foo:bar'
|
|
305
386
|
# for its sub-project.
|
|
306
387
|
attr_reader :name
|
|
307
388
|
|
|
@@ -310,17 +391,22 @@ module Buildr
|
|
|
310
391
|
|
|
311
392
|
def initialize(*args) #:nodoc:
|
|
312
393
|
super
|
|
313
|
-
split = name.split(
|
|
394
|
+
split = name.split(':')
|
|
314
395
|
if split.size > 1
|
|
315
396
|
# Get parent project, but do not invoke it's definition to prevent circular
|
|
316
|
-
# dependencies (it's being invoked right now, so calling project
|
|
317
|
-
@parent = task(split[0...-1].join(
|
|
318
|
-
raise "No parent project #{split[0...-1].join(
|
|
397
|
+
# dependencies (it's being invoked right now, so calling project will fail).
|
|
398
|
+
@parent = task(split[0...-1].join(':'))
|
|
399
|
+
raise "No parent project #{split[0...-1].join(':')}" unless @parent && Project === parent
|
|
400
|
+
end
|
|
401
|
+
callbacks = Project.callbacks.uniq.map(&:new)
|
|
402
|
+
@callbacks = [:before_define, :after_define].inject({}) do |hash, state|
|
|
403
|
+
methods = callbacks.select { |callback| callback.respond_to?(state) }.map { |callback| callback.method(state) }
|
|
404
|
+
hash.update(state=>methods)
|
|
319
405
|
end
|
|
320
406
|
end
|
|
321
407
|
|
|
322
408
|
# :call-seq:
|
|
323
|
-
# base_dir
|
|
409
|
+
# base_dir => path
|
|
324
410
|
#
|
|
325
411
|
# Returns the project's base directory.
|
|
326
412
|
#
|
|
@@ -329,15 +415,15 @@ module Buildr
|
|
|
329
415
|
# a base directory that is one level down, with the same name as the sub-project.
|
|
330
416
|
#
|
|
331
417
|
# For example:
|
|
332
|
-
# /home/foo/ <-- base_directory of project
|
|
333
|
-
# /home/foo/Buildfile <-- builds
|
|
334
|
-
# /home/foo/bar <-- sub-project
|
|
335
|
-
def base_dir
|
|
418
|
+
# /home/foo/ <-- base_directory of project 'foo'
|
|
419
|
+
# /home/foo/Buildfile <-- builds 'foo'
|
|
420
|
+
# /home/foo/bar <-- sub-project 'foo:bar'
|
|
421
|
+
def base_dir
|
|
336
422
|
if @base_dir.nil?
|
|
337
423
|
if parent
|
|
338
424
|
# For sub-project, a good default is a directory in the parent's base_dir,
|
|
339
425
|
# using the same name as the project.
|
|
340
|
-
@base_dir = File.
|
|
426
|
+
@base_dir = File.expand_path(name.split(':').last, parent.base_dir)
|
|
341
427
|
else
|
|
342
428
|
# For top-level project, a good default is the directory where we found the Buildfile.
|
|
343
429
|
@base_dir = Dir.pwd
|
|
@@ -346,20 +432,9 @@ module Buildr
|
|
|
346
432
|
@base_dir
|
|
347
433
|
end
|
|
348
434
|
|
|
349
|
-
#
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
# Sets the project's base directory. Allows you to specify a base directory by calling
|
|
353
|
-
# this accessor, or with the :base_dir property when calling #define.
|
|
354
|
-
#
|
|
355
|
-
# You can only set the base directory once for a given project, and only before accessing
|
|
356
|
-
# the base directory (for example, by calling #file or #path_to).
|
|
357
|
-
# Set the base directory. Note: you can only do this once for a project,
|
|
358
|
-
# and only before accessing the base directory. If you try reading the
|
|
359
|
-
# value with #base_dir, the base directory cannot be set again.
|
|
360
|
-
def base_dir=(dir)
|
|
361
|
-
raise "Cannot set base directory twice, or after reading its value" if @base_dir
|
|
362
|
-
@base_dir = File.expand_path(dir)
|
|
435
|
+
# Returns the layout associated with this project.
|
|
436
|
+
def layout
|
|
437
|
+
@layout ||= (parent ? parent.layout : Layout.default).clone
|
|
363
438
|
end
|
|
364
439
|
|
|
365
440
|
# :call-seq:
|
|
@@ -367,29 +442,102 @@ module Buildr
|
|
|
367
442
|
#
|
|
368
443
|
# Returns a path from a combination of name, relative to the project's base directory.
|
|
369
444
|
# Essentially, joins all the supplied names and expands the path relative to #base_dir.
|
|
370
|
-
# Symbol arguments are converted to paths
|
|
445
|
+
# Symbol arguments are converted to paths based on the layout, so whenever possible stick
|
|
446
|
+
# to these. For example:
|
|
447
|
+
# path_to(:source, :main, :java)
|
|
448
|
+
# => 'src/main/java'
|
|
371
449
|
#
|
|
372
450
|
# Keep in mind that all tasks are defined and executed relative to the Buildfile directory,
|
|
373
451
|
# so you want to use #path_to to get the actual path within the project as a matter of practice.
|
|
374
452
|
#
|
|
375
453
|
# For example:
|
|
376
|
-
# path_to(
|
|
377
|
-
# =>
|
|
378
|
-
# path_to(
|
|
454
|
+
# path_to('foo', 'bar')
|
|
455
|
+
# => foo/bar
|
|
456
|
+
# path_to('/tmp')
|
|
379
457
|
# => /tmp
|
|
380
|
-
# path_to(:base_dir,
|
|
458
|
+
# path_to(:base_dir, 'foo') # same as path_to('foo")
|
|
381
459
|
# => /home/project1/foo
|
|
382
460
|
def path_to(*names)
|
|
383
|
-
File.expand_path(
|
|
461
|
+
File.expand_path(layout.expand(*names), base_dir)
|
|
384
462
|
end
|
|
385
463
|
alias :_ :path_to
|
|
386
464
|
|
|
387
465
|
# :call-seq:
|
|
388
|
-
#
|
|
466
|
+
# file(path) => Task
|
|
467
|
+
# file(path=>prereqs) => Task
|
|
468
|
+
# file(path) { |task| ... } => Task
|
|
389
469
|
#
|
|
390
|
-
#
|
|
391
|
-
|
|
392
|
-
|
|
470
|
+
# Creates and returns a new file task in the project. Similar to calling Rake's
|
|
471
|
+
# file method, but the path is expanded relative to the project's base directory,
|
|
472
|
+
# and the task executes in the project's base directory.
|
|
473
|
+
#
|
|
474
|
+
# For example:
|
|
475
|
+
# define 'foo' do
|
|
476
|
+
# define 'bar' do
|
|
477
|
+
# file('src') { ... }
|
|
478
|
+
# end
|
|
479
|
+
# end
|
|
480
|
+
#
|
|
481
|
+
# puts project('foo:bar').file('src').to_s
|
|
482
|
+
# => '/home/foo/bar/src'
|
|
483
|
+
def file(*args, &block)
|
|
484
|
+
task_name, arg_names, deps = Buildr.application.resolve_args(args)
|
|
485
|
+
task = Rake::FileTask.define_task(path_to(task_name))
|
|
486
|
+
task.set_arg_names(arg_names) unless arg_names.empty?
|
|
487
|
+
task.enhance Array(deps), &block
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# :call-seq:
|
|
491
|
+
# task(name) => Task
|
|
492
|
+
# task(name=>prereqs) => Task
|
|
493
|
+
# task(name) { |task| ... } => Task
|
|
494
|
+
#
|
|
495
|
+
# Creates and returns a new task in the project. Similar to calling Rake's task
|
|
496
|
+
# method, but prefixes the task name with the project name and executes the task
|
|
497
|
+
# in the project's base directory.
|
|
498
|
+
#
|
|
499
|
+
# For example:
|
|
500
|
+
# define 'foo' do
|
|
501
|
+
# task 'doda'
|
|
502
|
+
# end
|
|
503
|
+
#
|
|
504
|
+
# puts project('foo').task('doda').name
|
|
505
|
+
# => 'foo:doda'
|
|
506
|
+
#
|
|
507
|
+
# When called from within the project definition, creates a new task if the task
|
|
508
|
+
# does not already exist. If called from outside the project definition, returns
|
|
509
|
+
# the named task and raises an exception if the task is not defined.
|
|
510
|
+
#
|
|
511
|
+
# As with Rake's task method, calling this method enhances the task with the
|
|
512
|
+
# prerequisites and optional block.
|
|
513
|
+
def task(*args, &block)
|
|
514
|
+
task_name, arg_names, deps = Buildr.application.resolve_args(args)
|
|
515
|
+
if task_name =~ /^:/
|
|
516
|
+
Buildr.application.switch_to_namespace [] do
|
|
517
|
+
task = Rake::Task.define_task(task_name[1..-1])
|
|
518
|
+
end
|
|
519
|
+
elsif Buildr.application.current_scope == name.split(':')
|
|
520
|
+
task = Rake::Task.define_task(task_name)
|
|
521
|
+
else
|
|
522
|
+
unless task = Buildr.application.lookup(task_name, name.split(':'))
|
|
523
|
+
raise "You cannot define a project task outside the project definition, and no task #{name}:#{task_name} defined in the project"
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
task.set_arg_names(arg_names) unless arg_names.empty?
|
|
527
|
+
task.enhance Array(deps), &block
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
# :call-seq:
|
|
531
|
+
# recursive_task(name=>prereqs) { |task| ... }
|
|
532
|
+
#
|
|
533
|
+
# Define a recursive task. A recursive task executes itself and the same task
|
|
534
|
+
# in all the sub-projects.
|
|
535
|
+
def recursive_task(*args, &block)
|
|
536
|
+
task_name, arg_names, deps = Buildr.application.resolve_args(args)
|
|
537
|
+
task = Buildr.options.parallel ? multitask(task_name) : task(task_name)
|
|
538
|
+
parent.task(task_name).enhance [task] if parent
|
|
539
|
+
task.set_arg_names(arg_names) unless arg_names.empty?
|
|
540
|
+
task.enhance Array(deps), &block
|
|
393
541
|
end
|
|
394
542
|
|
|
395
543
|
# :call-seq:
|
|
@@ -401,8 +549,8 @@ module Buildr
|
|
|
401
549
|
#
|
|
402
550
|
# When called on a project without a name, returns the project itself. You can use that when
|
|
403
551
|
# setting project properties, for example:
|
|
404
|
-
# define
|
|
405
|
-
# project.version =
|
|
552
|
+
# define 'foo' do
|
|
553
|
+
# project.version = '1.0'
|
|
406
554
|
# end
|
|
407
555
|
def project(*args)
|
|
408
556
|
if Hash === args.last
|
|
@@ -431,101 +579,186 @@ module Buildr
|
|
|
431
579
|
Project.projects *(args + [{ :scope=>self.name }.merge(options)])
|
|
432
580
|
end
|
|
433
581
|
|
|
582
|
+
def inspect #:nodoc:
|
|
583
|
+
%Q{project(#{name.inspect})}
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
protected
|
|
587
|
+
|
|
434
588
|
# :call-seq:
|
|
435
|
-
#
|
|
436
|
-
# file(path=>prereqs) => Task
|
|
437
|
-
# file(path) { |task| ... } => Task
|
|
438
|
-
#
|
|
439
|
-
# Creates and returns a new file task in the project. Similar to calling Rake's
|
|
440
|
-
# file method, but the path is expanded relative to the project's base directory,
|
|
441
|
-
# and the task executes in the project's base directory.
|
|
589
|
+
# base_dir = dir
|
|
442
590
|
#
|
|
443
|
-
#
|
|
444
|
-
#
|
|
445
|
-
# define "bar" do
|
|
446
|
-
# file("src") { ... }
|
|
447
|
-
# end
|
|
448
|
-
# end
|
|
591
|
+
# Sets the project's base directory. Allows you to specify a base directory by calling
|
|
592
|
+
# this accessor, or with the :base_dir property when calling #define.
|
|
449
593
|
#
|
|
450
|
-
#
|
|
451
|
-
#
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
594
|
+
# You can only set the base directory once for a given project, and only before accessing
|
|
595
|
+
# the base directory (for example, by calling #file or #path_to).
|
|
596
|
+
# Set the base directory. Note: you can only do this once for a project,
|
|
597
|
+
# and only before accessing the base directory. If you try reading the
|
|
598
|
+
# value with #base_dir, the base directory cannot be set again.
|
|
599
|
+
def base_dir=(dir)
|
|
600
|
+
raise 'Cannot set base directory twice, or after reading its value' if @base_dir
|
|
601
|
+
@base_dir = File.expand_path(dir)
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
# Sets the project layout. Accepts Layout object or class (or for that matter, anything
|
|
605
|
+
# that can expand).
|
|
606
|
+
def layout=(layout)
|
|
607
|
+
raise 'Cannot set directory layout twice, or after reading its value' if @layout
|
|
608
|
+
@layout = layout.is_a?(Class) ? layout.new : layout
|
|
456
609
|
end
|
|
457
610
|
|
|
458
611
|
# :call-seq:
|
|
459
|
-
#
|
|
460
|
-
# task(name=>prereqs) => Task
|
|
461
|
-
# task(name) { |task| ... } => Task
|
|
462
|
-
#
|
|
463
|
-
# Creates and returns a new task in the project. Similar to calling Rake's task
|
|
464
|
-
# method, but prefixes the task name with the project name and executes the task
|
|
465
|
-
# in the project's base directory.
|
|
466
|
-
#
|
|
467
|
-
# For example:
|
|
468
|
-
# define "foo" do
|
|
469
|
-
# task "doda"
|
|
470
|
-
# end
|
|
471
|
-
#
|
|
472
|
-
# puts project("foo").task("doda").name
|
|
473
|
-
# => "foo:doda"
|
|
474
|
-
#
|
|
475
|
-
# When called from within the project definition, creates a new task if the task
|
|
476
|
-
# does not already exist. If called from outside the project definition, returns
|
|
477
|
-
# the named task and raises an exception if the task is not defined.
|
|
612
|
+
# define(name, properties?) { |project| ... } => project
|
|
478
613
|
#
|
|
479
|
-
#
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
Rake::Task.define_task(task_name[1..-1]=>deps, &block)
|
|
488
|
-
ensure
|
|
489
|
-
@scope = scope
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
|
-
elsif Rake.application.current_scope == name.split(":")
|
|
493
|
-
Rake::Task.define_task(task_name=>deps, &block)
|
|
494
|
-
else
|
|
495
|
-
if task = Rake.application.lookup(task_name, name.split(":"))
|
|
496
|
-
deps = [deps] unless deps.respond_to?(:to_ary)
|
|
497
|
-
task.enhance deps, &block
|
|
498
|
-
else
|
|
499
|
-
full_name = "#{name}:#{task_name}"
|
|
500
|
-
raise "You cannot define a project task outside the project definition, and no task #{full_name} defined in the project"
|
|
501
|
-
end
|
|
614
|
+
# Define a new sub-project within this project. See Buildr#define.
|
|
615
|
+
def define(name, properties = nil, &block)
|
|
616
|
+
Project.define "#{self.name}:#{name}", properties, &block
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
def execute(args) #:nodoc:
|
|
620
|
+
Buildr.application.switch_to_namespace name.split(':') do
|
|
621
|
+
super
|
|
502
622
|
end
|
|
503
623
|
end
|
|
504
624
|
|
|
505
|
-
# :
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
# in all the sub-projects.
|
|
510
|
-
def recursive_task(args, &block)
|
|
511
|
-
task_name, deps = Rake.application.resolve_args(args)
|
|
512
|
-
deps = [deps] unless deps.respond_to?(:to_ary)
|
|
513
|
-
task = Buildr.options.parallel ? multitask(task_name) : task(task_name)
|
|
514
|
-
parent.task(task_name).enhance [task] if parent
|
|
515
|
-
task.enhance deps, &block
|
|
625
|
+
# Call all callbacks for a particular state, e.g. :before_define, :after_define.
|
|
626
|
+
def call_callbacks(state) #:nodoc:
|
|
627
|
+
methods = @callbacks.delete(state) || []
|
|
628
|
+
methods.each { |method| method.call(project) }
|
|
516
629
|
end
|
|
517
630
|
|
|
518
|
-
def
|
|
519
|
-
|
|
520
|
-
Rake.application.in_namespace(":#{name}") { super }
|
|
631
|
+
def add_callback(callback)
|
|
632
|
+
@callbacks[:after_define] << callback.method(:after_define) if callback.respond_to?(:after_define)
|
|
521
633
|
end
|
|
522
634
|
|
|
523
|
-
|
|
524
|
-
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
# The basic mechanism for extending projects in Buildr are Ruby modules. In fact,
|
|
639
|
+
# base features like compiling and testing are all developed in the form of modules,
|
|
640
|
+
# and then added to the core Project class.
|
|
641
|
+
#
|
|
642
|
+
# A module defines instance methods that are then mixed into the project and become
|
|
643
|
+
# instance methods of the project. There are two general ways for extending projects.
|
|
644
|
+
# You can extend all projects by including the module in Project:
|
|
645
|
+
# class Project
|
|
646
|
+
# include MyExtension
|
|
647
|
+
# end
|
|
648
|
+
# You can also extend a given project instance and only that instance by extending
|
|
649
|
+
# it with the module:
|
|
650
|
+
# define 'foo' do
|
|
651
|
+
# extend MyExtension
|
|
652
|
+
# end
|
|
653
|
+
#
|
|
654
|
+
# Some extensions require tighter integration with the project, specifically for
|
|
655
|
+
# setting up tasks and properties, or for configuring tasks based on the project
|
|
656
|
+
# definition. You can do that by adding callbacks to the process.
|
|
657
|
+
#
|
|
658
|
+
# The easiest way to add callbacks is by incorporating the Extension module in your
|
|
659
|
+
# own extension, and using the various class methods to define callback behavior:
|
|
660
|
+
# * first_time -- This block will be called once for any particular extension.
|
|
661
|
+
# You can use this to setup top-level and local tasks.
|
|
662
|
+
# * before_define -- This block is called once for the project with the project
|
|
663
|
+
# instance, right before running the project definition. You can use this
|
|
664
|
+
# to add tasks and set properties that will be used in the project definition.
|
|
665
|
+
# * after_define -- This block is called once for the project with the project
|
|
666
|
+
# instance, right after running the project definition. You can use this to
|
|
667
|
+
# do any post-processing that depends on the project definition.
|
|
668
|
+
#
|
|
669
|
+
# This example illustrates how to write a simple extension:
|
|
670
|
+
# module LinesOfCode
|
|
671
|
+
# include Extension
|
|
672
|
+
#
|
|
673
|
+
# first_time do
|
|
674
|
+
# # Define task not specific to any projet.
|
|
675
|
+
# desc 'Count lines of code in current project'
|
|
676
|
+
# Project.local_task('loc')
|
|
677
|
+
# end
|
|
678
|
+
#
|
|
679
|
+
# before_define do |project|
|
|
680
|
+
# # Define the loc task for this particular project.
|
|
681
|
+
# Rake::Task.define_task 'loc' do |task|
|
|
682
|
+
# lines = task.prerequisites.map { |path| Dir['#{path}/**/*'] }.flatten.uniq.
|
|
683
|
+
# inject(0) { |total, file| total + File.readlines(file).count }
|
|
684
|
+
# puts "Project #{project.name} has #{lines} lines of code"
|
|
685
|
+
# end
|
|
686
|
+
# end
|
|
687
|
+
#
|
|
688
|
+
# after_define do |project|
|
|
689
|
+
# # Now that we know all the source directories, add them.
|
|
690
|
+
# task('loc'=>compile.sources + compile.test.sources)
|
|
691
|
+
# end
|
|
692
|
+
#
|
|
693
|
+
# # To use this method in your project:
|
|
694
|
+
# # loc path_1, path_2
|
|
695
|
+
# def loc(*paths)
|
|
696
|
+
# task('loc'=>paths)
|
|
697
|
+
# end
|
|
698
|
+
#
|
|
699
|
+
# end
|
|
700
|
+
#
|
|
701
|
+
# class Buildr::Project
|
|
702
|
+
# include LinesOfCode
|
|
703
|
+
# end
|
|
704
|
+
module Extension
|
|
705
|
+
|
|
706
|
+
def self.included(base) #:nodoc:
|
|
707
|
+
base.extend ClassMethods
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
# Methods added to the extension module when including Extension.
|
|
711
|
+
module ClassMethods
|
|
712
|
+
|
|
713
|
+
def included(base) #:nodoc:
|
|
714
|
+
# When included in Project, add callback and call first_time.
|
|
715
|
+
if Project == base && !base.callbacks.include?(callbacks)
|
|
716
|
+
base.callbacks << callbacks
|
|
717
|
+
callbacks.first_time if callbacks.respond_to?(:first_time)
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
def extended(base) #:nodoc:
|
|
722
|
+
# When extending project, add instance and call before_define.
|
|
723
|
+
if Project === base
|
|
724
|
+
callbacks = self.send(:callbacks).new
|
|
725
|
+
callbacks.before_define(base) if callbacks.respond_to?(:before_define)
|
|
726
|
+
base.send :add_callback, callbacks
|
|
727
|
+
end
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
# This block will be called once for any particular extension.
|
|
731
|
+
# You can use this to setup top-level and local tasks.
|
|
732
|
+
def first_time(&block)
|
|
733
|
+
meta = class << callbacks ; self ; end
|
|
734
|
+
meta.send :define_method, :first_time, &block
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
# This block is called once for the project with the project instance,
|
|
738
|
+
# right before running the project definition. You can use this to add
|
|
739
|
+
# tasks and set properties that will be used in the project definition.
|
|
740
|
+
def before_define(&block)
|
|
741
|
+
callbacks.send :define_method, :before_define, &block
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
# This block is called once for the project with the project instance,
|
|
745
|
+
# right after running the project definition. You can use this to do
|
|
746
|
+
# any post-processing that depends on the project definition.
|
|
747
|
+
def after_define(&block)
|
|
748
|
+
callbacks.send :define_method, :after_define, &block
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
private
|
|
752
|
+
|
|
753
|
+
def callbacks
|
|
754
|
+
const_get('Callbacks') rescue const_set('Callbacks', Class.new)
|
|
755
|
+
end
|
|
756
|
+
|
|
525
757
|
end
|
|
526
758
|
|
|
527
759
|
end
|
|
528
760
|
|
|
761
|
+
|
|
529
762
|
# :call-seq:
|
|
530
763
|
# define(name, properties?) { |project| ... } => project
|
|
531
764
|
#
|
|
@@ -547,17 +780,17 @@ module Buildr
|
|
|
547
780
|
# related to the project.
|
|
548
781
|
#
|
|
549
782
|
# For example:
|
|
550
|
-
# define
|
|
783
|
+
# define 'foo', :version=>'1.0' do
|
|
551
784
|
#
|
|
552
|
-
# define
|
|
553
|
-
# compile.with
|
|
785
|
+
# define 'bar' do
|
|
786
|
+
# compile.with 'org.apache.axis2:axis2:jar:1.1'
|
|
554
787
|
# end
|
|
555
788
|
# end
|
|
556
789
|
#
|
|
557
|
-
# puts project(
|
|
558
|
-
# =>
|
|
559
|
-
# puts project(
|
|
560
|
-
# =>
|
|
790
|
+
# puts project('foo').version
|
|
791
|
+
# => '1.0'
|
|
792
|
+
# puts project('foo:bar').compile.classpath.map(&:to_spec)
|
|
793
|
+
# => 'org.apache.axis2:axis2:jar:1.1'
|
|
561
794
|
# % buildr build
|
|
562
795
|
# => Compiling 14 source files in foo:bar
|
|
563
796
|
def define(name, properties = nil, &block) #:yields:project
|
|
@@ -570,9 +803,9 @@ module Buildr
|
|
|
570
803
|
# Returns a project definition.
|
|
571
804
|
#
|
|
572
805
|
# When called from outside a project definition, must reference the project by its
|
|
573
|
-
# full name, e.g.
|
|
574
|
-
# from inside a project, relative names are sufficient, e.g. <code>project(
|
|
575
|
-
# will find the sub-project
|
|
806
|
+
# full name, e.g. 'foo:bar' to access the sub-project 'bar' in 'foo'. When called
|
|
807
|
+
# from inside a project, relative names are sufficient, e.g. <code>project('foo').project('bar')</code>
|
|
808
|
+
# will find the sub-project 'bar' in 'foo'.
|
|
576
809
|
#
|
|
577
810
|
# You cannot reference a project before the project is defined. When working with
|
|
578
811
|
# sub-projects, the project definition is stored by calling #define, and evaluated
|
|
@@ -584,21 +817,21 @@ module Buildr
|
|
|
584
817
|
# or packages created by that project).
|
|
585
818
|
#
|
|
586
819
|
# For example:
|
|
587
|
-
# define
|
|
588
|
-
# self.version =
|
|
820
|
+
# define 'myapp' do
|
|
821
|
+
# self.version = '1.1'
|
|
589
822
|
#
|
|
590
|
-
# define
|
|
823
|
+
# define 'webapp' do
|
|
591
824
|
# # webapp is defined first, but beans is evaluated first
|
|
592
|
-
# compile.with project(
|
|
825
|
+
# compile.with project('beans')
|
|
593
826
|
# package :war
|
|
594
827
|
# end
|
|
595
828
|
#
|
|
596
|
-
# define
|
|
829
|
+
# define 'beans' do
|
|
597
830
|
# package :jar
|
|
598
831
|
# end
|
|
599
832
|
# end
|
|
600
833
|
#
|
|
601
|
-
# puts project(
|
|
834
|
+
# puts project('myapp:beans').version
|
|
602
835
|
def project(*args)
|
|
603
836
|
Project.project *args
|
|
604
837
|
end
|
|
@@ -616,20 +849,42 @@ module Buildr
|
|
|
616
849
|
# Be advised of circular dependencies.
|
|
617
850
|
#
|
|
618
851
|
# For example:
|
|
619
|
-
# files = projects.map { |prj| FileList[prj.path_to(
|
|
852
|
+
# files = projects.map { |prj| FileList[prj.path_to('src/**/*.java') }.flatten
|
|
620
853
|
# puts "There are #{files.size} source files in #{projects.size} projects"
|
|
621
854
|
#
|
|
622
|
-
# puts projects(
|
|
855
|
+
# puts projects('myapp:beans', 'myapp:webapp').map(&:name)
|
|
623
856
|
# Same as:
|
|
624
|
-
# puts project(
|
|
857
|
+
# puts project('myapp').projects.map(&:name)
|
|
625
858
|
def projects(*args)
|
|
626
859
|
Project.projects *args
|
|
627
860
|
end
|
|
628
861
|
|
|
629
862
|
# Forces all the projects to be evaluated before executing any other task.
|
|
630
863
|
# If we don't do that, we don't get to have tasks available when running Rake.
|
|
631
|
-
|
|
632
|
-
|
|
864
|
+
namespace 'buildr' do
|
|
865
|
+
task 'initialize' do
|
|
866
|
+
projects
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
desc "Freezes the Buildfile so it always uses Buildr version #{Buildr::VERSION}"
|
|
870
|
+
task 'freeze' do
|
|
871
|
+
puts "Freezing the Buildfile so it always uses Buildr version #{Buildr::VERSION}"
|
|
872
|
+
original = File.read(Buildr.application.buildfile)
|
|
873
|
+
if original =~ /gem\s*(["'])buildr\1/
|
|
874
|
+
modified = original.sub(/gem\s*(["'])buildr\1\s*,\s*(["']).*\2/, %{gem "buildr", "#{Buildr::VERSION}"})
|
|
875
|
+
else
|
|
876
|
+
modified = %{gem "buildr", "#{Buildr::VERSION}"\n} + original
|
|
877
|
+
end
|
|
878
|
+
File.open(Buildr.application.buildfile, "w") { |file| file.write modified }
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
desc 'Unfreezes the Buildfile to use the latest version of Buildr'
|
|
882
|
+
task 'unfreeze' do
|
|
883
|
+
puts 'Unfreezing the Buildfile to use the latest version of Buildr from your Gems repository.'
|
|
884
|
+
modified = File.read(Buildr.application.buildfile).sub(/^\s*gem\s*(["'])buildr\1.*\n/, "")
|
|
885
|
+
File.open(Buildr.application.buildfile, "w") { |file| file.write modified }
|
|
886
|
+
end
|
|
633
887
|
end
|
|
634
888
|
|
|
889
|
+
|
|
635
890
|
end
|