buildr 1.3.3 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +76 -0
- data/NOTICE +1 -1
- data/README.rdoc +9 -21
- data/Rakefile +20 -37
- data/_buildr +3 -12
- data/{doc/print.toc.yaml → _jbuildr} +14 -14
- data/addon/buildr/cobertura.rb +5 -219
- data/addon/buildr/drb.rb +281 -0
- data/addon/buildr/emma.rb +5 -221
- data/addon/buildr/nailgun.rb +93 -689
- data/bin/buildr +0 -9
- data/buildr.buildfile +4 -4
- data/buildr.gemspec +27 -21
- data/doc/_layouts/default.html +82 -0
- data/doc/_layouts/preface.html +22 -0
- data/doc/{pages/artifacts.textile → artifacts.textile} +82 -42
- data/doc/{pages/building.textile → building.textile} +89 -47
- data/doc/{pages/contributing.textile → contributing.textile} +53 -45
- data/doc/css/default.css +6 -5
- data/doc/css/print.css +17 -24
- data/doc/css/syntax.css +7 -36
- data/doc/download.textile +78 -0
- data/doc/{pages/extending.textile → extending.textile} +45 -24
- data/doc/{pages/getting_started.textile → getting_started.textile} +146 -88
- data/doc/images/asf-logo.gif +0 -0
- data/doc/images/note.png +0 -0
- data/doc/index.textile +47 -0
- data/doc/{pages/languages.textile → languages.textile} +108 -54
- data/doc/mailing_lists.textile +25 -0
- data/doc/{pages/more_stuff.textile → more_stuff.textile} +152 -73
- data/doc/{pages/packaging.textile → packaging.textile} +181 -96
- data/doc/preface.textile +28 -0
- data/doc/{pages/projects.textile → projects.textile} +55 -40
- data/doc/scripts/buildr-git.rb +364 -264
- data/doc/scripts/gitflow.rb +296 -0
- data/doc/scripts/install-jruby.sh +2 -2
- data/doc/scripts/install-linux.sh +6 -6
- data/doc/scripts/install-osx.sh +2 -2
- data/doc/{pages/settings_profiles.textile → settings_profiles.textile} +83 -45
- data/doc/{pages/testing.textile → testing.textile} +77 -41
- data/lib/buildr.rb +5 -5
- data/lib/buildr/core.rb +2 -0
- data/lib/buildr/core/application.rb +321 -151
- data/lib/buildr/core/build.rb +298 -167
- data/lib/buildr/core/checks.rb +4 -132
- data/lib/buildr/core/common.rb +1 -5
- data/lib/buildr/core/compile.rb +3 -9
- data/lib/buildr/core/environment.rb +12 -3
- data/lib/buildr/core/filter.rb +20 -18
- data/lib/buildr/core/generate.rb +36 -36
- data/lib/buildr/core/help.rb +2 -1
- data/lib/buildr/core/osx.rb +46 -0
- data/lib/buildr/core/progressbar.rb +1 -1
- data/lib/buildr/core/project.rb +7 -34
- data/lib/buildr/core/test.rb +12 -6
- data/lib/buildr/core/transports.rb +13 -11
- data/lib/buildr/core/util.rb +14 -23
- data/lib/buildr/groovy/bdd.rb +3 -2
- data/lib/buildr/groovy/compiler.rb +1 -1
- data/lib/buildr/ide/eclipse.rb +31 -21
- data/lib/buildr/ide/idea.rb +3 -2
- data/lib/buildr/ide/idea7x.rb +6 -4
- data/lib/buildr/java/ant.rb +3 -1
- data/lib/buildr/java/bdd.rb +9 -7
- data/lib/buildr/java/cobertura.rb +243 -0
- data/lib/buildr/java/compiler.rb +5 -4
- data/lib/buildr/java/emma.rb +244 -0
- data/lib/buildr/java/packaging.rb +11 -8
- data/lib/buildr/java/pom.rb +0 -4
- data/lib/buildr/java/rjb.rb +1 -1
- data/lib/buildr/java/test_result.rb +5 -7
- data/lib/buildr/java/tests.rb +17 -11
- data/lib/buildr/packaging.rb +5 -2
- data/lib/buildr/packaging/archive.rb +488 -0
- data/lib/buildr/packaging/artifact.rb +48 -29
- data/lib/buildr/packaging/artifact_namespace.rb +6 -6
- data/lib/buildr/packaging/gems.rb +4 -4
- data/lib/buildr/packaging/package.rb +3 -2
- data/lib/buildr/packaging/tar.rb +85 -3
- data/lib/buildr/packaging/version_requirement.rb +172 -0
- data/lib/buildr/packaging/zip.rb +24 -682
- data/lib/buildr/packaging/ziptask.rb +313 -0
- data/lib/buildr/scala.rb +5 -0
- data/lib/buildr/scala/bdd.rb +100 -0
- data/lib/buildr/scala/compiler.rb +45 -4
- data/lib/buildr/scala/tests.rb +12 -59
- data/rakelib/checks.rake +57 -0
- data/rakelib/doc.rake +58 -68
- data/rakelib/jekylltask.rb +110 -0
- data/rakelib/package.rake +35 -37
- data/rakelib/release.rake +119 -35
- data/rakelib/rspec.rake +29 -39
- data/rakelib/setup.rake +21 -59
- data/rakelib/stage.rake +184 -26
- data/spec/addon/drb_spec.rb +328 -0
- data/spec/core/application_spec.rb +32 -25
- data/spec/core/build_spec.rb +336 -126
- data/spec/core/checks_spec.rb +292 -310
- data/spec/core/common_spec.rb +8 -2
- data/spec/core/compile_spec.rb +17 -1
- data/spec/core/generate_spec.rb +3 -3
- data/spec/core/project_spec.rb +18 -10
- data/spec/core/test_spec.rb +8 -1
- data/spec/core/transport_spec.rb +40 -3
- data/spec/core/util_spec.rb +67 -0
- data/spec/ide/eclipse_spec.rb +96 -28
- data/spec/ide/idea7x_spec.rb +84 -0
- data/spec/java/ant.rb +5 -0
- data/spec/java/bdd_spec.rb +12 -3
- data/spec/{addon → java}/cobertura_spec.rb +6 -6
- data/spec/{addon → java}/emma_spec.rb +5 -6
- data/spec/java/java_spec.rb +12 -2
- data/spec/java/packaging_spec.rb +31 -2
- data/spec/{addon → java}/test_coverage_spec.rb +3 -3
- data/spec/java/tests_spec.rb +5 -0
- data/spec/packaging/archive_spec.rb +11 -1
- data/spec/{core → packaging}/artifact_namespace_spec.rb +10 -2
- data/spec/packaging/artifact_spec.rb +44 -3
- data/spec/packaging/packaging_spec.rb +1 -1
- data/spec/sandbox.rb +17 -14
- data/spec/scala/bdd_spec.rb +150 -0
- data/spec/scala/compiler_spec.rb +27 -0
- data/spec/scala/scala.rb +38 -0
- data/spec/scala/tests_spec.rb +78 -33
- data/spec/spec_helpers.rb +29 -5
- data/spec/version_requirement_spec.rb +6 -0
- metadata +175 -171
- data/DISCLAIMER +0 -7
- data/doc/images/apache-incubator-logo.png +0 -0
- data/doc/pages/download.textile +0 -51
- data/doc/pages/index.textile +0 -42
- data/doc/pages/mailing_lists.textile +0 -17
- data/doc/pages/recipes.textile +0 -103
- data/doc/pages/troubleshooting.textile +0 -103
- data/doc/pages/whats_new.textile +0 -323
- data/doc/print.haml +0 -51
- data/doc/site.haml +0 -56
- data/doc/site.toc.yaml +0 -47
- data/etc/git-svn-authors +0 -16
- data/lib/buildr/core/application_cli.rb +0 -139
- data/rakelib/apache.rake +0 -191
- data/rakelib/changelog.rake +0 -57
- data/rakelib/rubyforge.rake +0 -53
- data/rakelib/scm.rake +0 -49
@@ -1,9 +1,13 @@
|
|
1
|
-
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Testing
|
4
|
+
---
|
5
|
+
|
2
6
|
|
3
7
|
Untested code is broken code, so we take testing seriously. Off the bat you get to use either JUnit or TestNG for writing unit tests and integration tests. And you can also add your own framework, or even script tests using Ruby. But= first, let's start with the basics.
|
4
8
|
|
5
9
|
|
6
|
-
h2. Writing Tests
|
10
|
+
h2(#writing). Writing Tests
|
7
11
|
|
8
12
|
Each project has a @TestTask@ that you can access using the @test@ method. @TestTask@ reflects on the fact that each project has one task responsible for getting the tests to run and acting on the results. But in fact there are several tasks that do all the work, and a @test@ task coordinates all of that.
|
9
13
|
|
@@ -18,86 +22,106 @@ Once compiled, the @test@ task runs all the tests.
|
|
18
22
|
Different languages use different test frameworks. You can find out more about available test frameworks in the "Languages":languages.html section.
|
19
23
|
|
20
24
|
|
21
|
-
h2. Excluding Tests and Ignoring Failures
|
25
|
+
h2(#ignoring). Excluding Tests and Ignoring Failures
|
22
26
|
|
23
27
|
If you have a lot of tests that are failing or just hanging there collecting dusts, you can tell Buildr to ignore them. You can either tell Buildr to only run specific tests, for example:
|
24
28
|
|
25
|
-
|
29
|
+
<notextile>
|
30
|
+
{% highlight ruby %}
|
26
31
|
test.include 'com.acme.tests.passing.*'
|
27
|
-
}
|
32
|
+
{% endhighlight %}
|
33
|
+
</notextile>
|
28
34
|
|
29
35
|
Or tell it to exclude specific tests, for example:
|
30
36
|
|
31
|
-
|
37
|
+
<notextile>
|
38
|
+
{% highlight ruby %}
|
32
39
|
test.exclude '*FailingTest', '*FailingWorseTest'
|
33
|
-
}
|
40
|
+
{% endhighlight %}
|
41
|
+
</notextile>
|
34
42
|
|
35
43
|
Note that we're always using the package qualified class name, and you can use star (@*@) to substitute for any set of characters.
|
36
44
|
|
37
45
|
When tests fail, Buildr fails the @test@ task. This is usually a good thing, but you can also tell Buildr to ignore failures by resetting the @:fail_on_failure@ option:
|
38
46
|
|
39
|
-
|
47
|
+
<notextile>
|
48
|
+
{% highlight ruby %}
|
40
49
|
test.using :fail_on_failure=>false
|
41
|
-
}
|
50
|
+
{% endhighlight %}
|
51
|
+
</notextile>
|
42
52
|
|
43
53
|
Besides giving you a free pass to ignore failures, you can use it for other causes, for example, to be somewhat forgiving:
|
44
54
|
|
45
|
-
|
55
|
+
<notextile>
|
56
|
+
{% highlight ruby %}
|
46
57
|
test do
|
47
58
|
fail 'More than 3 tests failed!' if test.failed_tests.size > 3
|
48
59
|
end
|
49
|
-
}
|
60
|
+
{% endhighlight %}
|
61
|
+
</notextile>
|
50
62
|
|
51
63
|
The @failed_tests@ collection holds the names of all classes with failed tests. And there's @classes@, which holds the names of all test classes. Ruby arithmetic allows you to get the name of all passed test classes with a simple @test.classes – test.failed_tests@. We'll let you imagine creative use for these two.
|
52
64
|
|
53
65
|
|
54
|
-
h2. Running Tests
|
66
|
+
h2(#running). Running Tests
|
55
67
|
|
56
68
|
It's a good idea to run tests every time you change the source code, so we wired the @build@ task to run the @test@ task at the end of the build. And conveniently enough, the @build@ task is the default task, so another way to build changes in your code and run your tests:
|
57
69
|
|
58
|
-
|
70
|
+
<notextile>
|
71
|
+
{% highlight sh %}
|
59
72
|
$ buildr
|
60
|
-
}
|
73
|
+
{% endhighlight %}
|
74
|
+
</notextile>
|
61
75
|
|
62
76
|
That only works with the local @build@ task and any local task that depends on it, like @package@, @install@ and @upload@. Each project also has its own @build@ task that does not invoke the @test@ task, so @buildr build@ will run the tests cases, but @buildr foo:build@ will not.
|
63
77
|
|
64
78
|
While it's a good idea to always run your tests, it's not always possible. There are two ways you can get @build@ to not run the @test@ task. You can set the environment variable @test@ to @no@ (but @skip@ and @off@ will also work). You can do that when running Buildr:
|
65
79
|
|
66
|
-
|
80
|
+
<notextile>
|
81
|
+
{% highlight sh %}
|
67
82
|
$ buildr test=no
|
68
|
-
}
|
83
|
+
{% endhighlight %}
|
84
|
+
</notextile>
|
69
85
|
|
70
86
|
Or set it once in your environment:
|
71
87
|
|
72
|
-
|
88
|
+
<notextile>
|
89
|
+
{% highlight sh %}
|
73
90
|
$ export TEST=no
|
74
91
|
$ buildr
|
75
|
-
}
|
92
|
+
{% endhighlight %}
|
93
|
+
</notextile>
|
76
94
|
|
77
95
|
If you're feeling really adventurous, you can also disable tests from your Buildfile or @buildr.rb@ file, by setting @options.test = false@. We didn't say it's a good idea, we're just giving you the option.
|
78
96
|
|
79
97
|
The @test@ task is just smart enough to run all the tests it finds, but will accept include/exclude patterns. Often enough you're only working on one broken test and you only want to run that one test. Better than changing your Buildfile, you can run the @test@ task with a pattern. For example:
|
80
98
|
|
81
|
-
|
99
|
+
<notextile>
|
100
|
+
{% highlight sh %}
|
82
101
|
$ buildr test:KillerAppTest
|
83
|
-
}
|
102
|
+
{% endhighlight %}
|
103
|
+
</notextile>
|
84
104
|
|
85
105
|
Buildr will then run only tests that match the pattern @KillerAppTest@. It uses pattern matching, so @test:Foo@ will run @com.acme.FooTest@ and @com.acme.FooBarTest@. With Java, you can use this to pick a class name, or a package name to run all tests in that package, or any such combination. In fact, you can specify several patterns separated with commas. For example:
|
86
106
|
|
87
|
-
|
107
|
+
<notextile>
|
108
|
+
{% highlight sh %}
|
88
109
|
$ buildr test:FooTest,BarTest
|
89
|
-
}
|
110
|
+
{% endhighlight %}
|
111
|
+
</notextile>
|
90
112
|
|
91
113
|
As you probably noticed, Buildr will stop your build at the first test that fails. We think it's a good idea, except when it's not. If you're using a continuous build system, you'll want a report of all the failed tests without stopping at the first failure. To make that happen, set the environment variable @test@ to "all", or the Buildr @options.test@ option to @:all@. For example:
|
92
114
|
|
93
|
-
|
115
|
+
<notextile>
|
116
|
+
{% highlight sh %}
|
94
117
|
$ buildr package test=all
|
95
|
-
}
|
118
|
+
{% endhighlight %}
|
119
|
+
</notextile>
|
96
120
|
|
97
121
|
We're using @package@ and not @build@ above. When using a continuous build system, you want to make sure that packages are created, contain the right files, and also run the integration tests.
|
98
122
|
|
99
123
|
|
100
|
-
h2. Integration Tests
|
124
|
+
h2(#integration). Integration Tests
|
101
125
|
|
102
126
|
So far we talked about unit tests. Unit tests are run in isolation on the specific project they test, in an isolated environment, generally with minimal setup and teardown. You get a sense of that when we told you tests run after the @build@ task, and include JMock in the dependency list.
|
103
127
|
|
@@ -105,44 +129,52 @@ In contrast, integration tests are run with a number of components, in an enviro
|
|
105
129
|
|
106
130
|
You write integration tests much the same way as you write unit tests, using @test.compile@ and @test.resources@. However, you need to tell Buildr that your tests will execute during integration test. To do so, add the following line in your project definition:
|
107
131
|
|
108
|
-
|
132
|
+
<notextile>
|
133
|
+
{% highlight ruby %}
|
109
134
|
test.using :integration
|
110
|
-
}
|
135
|
+
{% endhighlight %}
|
136
|
+
</notextile>
|
111
137
|
|
112
138
|
Typically you'll use unit tests in projects that create internal modules, such as JARs, and integration tests in projects that create components, such as WARs and EARs. You only need to use the @:integration@ option with the later.
|
113
139
|
|
114
140
|
To run integration tests on the current project:
|
115
141
|
|
116
|
-
|
142
|
+
<notextile>
|
143
|
+
{% highlight sh %}
|
117
144
|
$ buildr integration
|
118
|
-
}
|
145
|
+
{% endhighlight %}
|
146
|
+
</notextile>
|
119
147
|
|
120
148
|
You can also run specific tests cases, for example:
|
121
149
|
|
122
|
-
|
150
|
+
<notextile>
|
151
|
+
{% highlight sh %}
|
123
152
|
$ buildr integration:ClientTest
|
124
|
-
}
|
153
|
+
{% endhighlight %}
|
154
|
+
</notextile>
|
125
155
|
|
126
156
|
If you run the @package@ task (or any task that depends on it, like @install@ and @upload@), Buildr will first run the @build@ task and all its unit tests, and then create the packages and run the integration tests. That gives you full coverage for your tests and ready to release packages. As with unit tests, you can set the environment variable @test@ to "no" to skip integration tests, or "all" to ignore failures.
|
127
157
|
|
128
158
|
|
129
|
-
h2. Using Setup and Teardown
|
159
|
+
h2(#setup_teardown). Using Setup and Teardown
|
130
160
|
|
131
161
|
Some tests need you to setup an environment before they run, and tear it down afterwards. The test frameworks (JUnit, TestNG) allow you to do that for each test. Buildr provides two additional mechanisms for dealing with more complicated setup and teardown procedures.
|
132
162
|
|
133
163
|
Integration tests run a setup task before the tests, and a teardown task afterwards. You can use this task to setup a Web server for testing your Web components, or a database server for testing persistence. You can access either task by calling @integration.setup@ and @integration.teardown@. For example:
|
134
164
|
|
135
|
-
|
165
|
+
<notextile>
|
166
|
+
{% highlight ruby %}
|
136
167
|
integration.setup { server.start ; server.deploy }
|
137
168
|
integration.teardown { server.stop }
|
138
|
-
}
|
169
|
+
{% endhighlight %}
|
170
|
+
</notextile>
|
139
171
|
|
140
172
|
Depending on your build, you may want to enhance the setup/teardown tasks from within a project, for example, to populate the database with data used by that project's test, or from outside the project definition, for example, to start and stop the Web server.
|
141
173
|
|
142
174
|
Likewise, each project has its own setup and teardown tasks that are run before and after tests for that specific project. You can access these tasks using @test.setup@ and @test.teardown@.
|
143
175
|
|
144
176
|
|
145
|
-
h2. Testing Your Build
|
177
|
+
h2(#checks). Testing Your Build
|
146
178
|
|
147
179
|
So you got the build running and all the tests pass, binaries are shipping when you find out some glaring omissions. The license file is empty, the localized messages for Japanese are missing, the CSS files are not where you expect them to be. The fact is, some errors slip by unit and integration tests. So how do we make sure the same mistake doesn't happen again?
|
148
180
|
|
@@ -150,7 +182,8 @@ Each project has a @check@ task that runs just after packaging. You can use thi
|
|
150
182
|
|
151
183
|
You use the @check@ method to express and expectation. Buildr will then run all these expectations against your project, and fail at the first expectation that doesn't match. An expectation says three things. Let's look at a few examples:
|
152
184
|
|
153
|
-
|
185
|
+
<notextile>
|
186
|
+
{% highlight ruby %}
|
154
187
|
check package(:war), 'should exist' do
|
155
188
|
it.should exist
|
156
189
|
end
|
@@ -172,17 +205,20 @@ end
|
|
172
205
|
check file('target/classes/killerapp/Code.class'), 'should exist' do
|
173
206
|
it.should exist
|
174
207
|
end
|
175
|
-
}
|
208
|
+
{% endhighlight %}
|
209
|
+
</notextile>
|
176
210
|
|
177
211
|
The first argument is the subject, or the project if you skip the first argument. The second argument is the description, optional, but we recommend using it. The method @it@ returns the subject.
|
178
212
|
|
179
213
|
You can also write the first expectation like this:
|
180
214
|
|
181
|
-
|
215
|
+
<notextile>
|
216
|
+
{% highlight ruby %}
|
182
217
|
check do
|
183
218
|
package(:jar).should exist
|
184
219
|
end
|
185
|
-
}
|
220
|
+
{% endhighlight %}
|
221
|
+
</notextile>
|
186
222
|
|
187
223
|
We recommend using the subject and description, they make your build easier to read and maintain, and produce better error messages.
|
188
224
|
|
@@ -195,14 +231,14 @@ Buildr provides the following matchers:
|
|
195
231
|
| @empty@ | Given a file task checks that the file (or directory) is empty. |
|
196
232
|
| @contain@ | Given a file task referencing a file, checks its contents, using string or regular expression. For a file task referencing a directory, checks that it contains the specified files; global patterns using @*@ and @**@ are allowed. |
|
197
233
|
|
198
|
-
All these matchers operate against a file task. If you run them against a ZipTask (including JAR, WAR, etc) they can also check the contents of the
|
234
|
+
All these matchers operate against a file task. If you run them against a ZipTask (including JAR, WAR, etc) or a TarTask, they can also check the contents of the archive. And as you can see in the examples above, you can also run them against a path in an archive, checking its contents as if it was a directory, or against an entry in an archive, checking the content of that file.
|
199
235
|
|
200
236
|
p(note). The @package@ method returns a package task based on packaging type, identifier, group, version and classifier. The last four are inferred, but if you create a package with different specifications (for example, you specify a classifier) your checks must call @package@ with the same qualifying arguments to return the very same package task.
|
201
237
|
|
202
238
|
Buildr expectations are based on RSpec. "RSpec":http://rspec.info/ is the behavior-driven development framework we use to test Buildr itself. Check the RSpec documentation if want to see all the supported matchers, or want to write your own.
|
203
239
|
|
204
240
|
|
205
|
-
h2. Behaviour-Driven Development
|
241
|
+
h2(#bdd). Behaviour-Driven Development
|
206
242
|
|
207
243
|
Buildr supports several Behaviour-Driven Development(BDD) frameworks for testing your projects. Buildr follows each framework naming conventions, searching for files under the @src/spec/{lang}@ directory.
|
208
244
|
|
data/lib/buildr.rb
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
# the License.
|
15
15
|
|
16
16
|
module Buildr
|
17
|
-
VERSION = '1.3.
|
17
|
+
VERSION = '1.3.4'.freeze
|
18
18
|
end
|
19
19
|
|
20
20
|
require 'buildr/core'
|
@@ -28,8 +28,8 @@ module Buildr ; extend self ; end
|
|
28
28
|
# The Buildfile object (self) has access to all the Buildr methods and constants.
|
29
29
|
class << self ; include Buildr ; end
|
30
30
|
class Object #:nodoc:
|
31
|
-
Buildr.constants.each
|
31
|
+
Buildr.constants.each do |name|
|
32
|
+
const = Buildr.const_get(name)
|
33
|
+
const_set name, const if const.is_a?(Module)
|
34
|
+
end
|
32
35
|
end
|
33
|
-
|
34
|
-
# Prevent RSpec runner from running at_exit.
|
35
|
-
require 'spec'
|
data/lib/buildr/core.rb
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
# License for the specific language governing permissions and limitations under
|
14
14
|
# the License.
|
15
15
|
|
16
|
+
|
16
17
|
# Portion of this file derived from Rake.
|
17
18
|
# Copyright (c) 2003, 2004 Jim Weirich
|
18
19
|
#
|
@@ -35,15 +36,15 @@
|
|
35
36
|
# SOFTWARE.
|
36
37
|
|
37
38
|
|
38
|
-
require 'highline/import'
|
39
39
|
require 'rake'
|
40
|
+
require 'highline/import'
|
40
41
|
require 'rubygems/source_info_cache'
|
41
|
-
require 'buildr/core/application_cli'
|
42
42
|
require 'buildr/core/util'
|
43
|
+
Gem.autoload :SourceInfoCache, 'rubygems/source_info_cache'
|
43
44
|
|
44
45
|
|
45
46
|
# Gem::user_home is nice, but ENV['HOME'] lets you override from the environment.
|
46
|
-
ENV[
|
47
|
+
ENV['HOME'] ||= File.expand_path(Gem::user_home)
|
47
48
|
ENV['BUILDR_ENV'] ||= 'development'
|
48
49
|
|
49
50
|
|
@@ -68,19 +69,22 @@ module Buildr
|
|
68
69
|
|
69
70
|
def initialize(application) #:nodoc:
|
70
71
|
@application = application
|
71
|
-
@user = load_from('settings', @application.home_dir)
|
72
|
-
@build = load_from('build')
|
73
|
-
@profiles = load_from('profiles')
|
74
72
|
end
|
75
73
|
|
76
74
|
# User settings loaded from setting.yaml file in user's home directory.
|
77
|
-
|
75
|
+
def user
|
76
|
+
@user ||= load_from('settings', @application.home_dir)
|
77
|
+
end
|
78
78
|
|
79
79
|
# Build settings loaded from build.yaml file in build directory.
|
80
|
-
|
80
|
+
def build
|
81
|
+
@build ||= load_from('build')
|
82
|
+
end
|
81
83
|
|
82
84
|
# Profiles loaded from profiles.yaml file in build directory.
|
83
|
-
|
85
|
+
def profiles
|
86
|
+
@profiles ||= load_from('profiles')
|
87
|
+
end
|
84
88
|
|
85
89
|
# :call-seq:
|
86
90
|
# profile => hash
|
@@ -92,9 +96,12 @@ module Buildr
|
|
92
96
|
|
93
97
|
private
|
94
98
|
|
95
|
-
def load_from(
|
96
|
-
|
97
|
-
|
99
|
+
def load_from(name, path = nil)
|
100
|
+
unless path
|
101
|
+
fail "Internal error: attempting to access local setting before buildfile located" unless @application.rakefile
|
102
|
+
path = File.dirname(@application.rakefile)
|
103
|
+
end
|
104
|
+
file_name = ['yaml', 'yml'].map { |ext| File.join(path, "#{name}.#{ext}") }.find { |fn| File.exist?(fn) }
|
98
105
|
return {} unless file_name
|
99
106
|
yaml = YAML.load(File.read(file_name)) || {}
|
100
107
|
fail "Expecting #{file_name} to be a map (name: value)!" unless Hash === yaml
|
@@ -107,28 +114,41 @@ module Buildr
|
|
107
114
|
|
108
115
|
class Application < Rake::Application #:nodoc:
|
109
116
|
|
117
|
+
# Deprecated: rakefile/Rakefile, removed in 1.5
|
110
118
|
DEFAULT_BUILDFILES = ['buildfile', 'Buildfile'] + DEFAULT_RAKEFILES
|
111
119
|
|
112
|
-
include CommandLineInterface
|
113
|
-
|
114
120
|
attr_reader :rakefiles, :requires
|
115
121
|
private :rakefiles, :requires
|
116
122
|
|
117
123
|
def initialize
|
118
124
|
super
|
119
|
-
@rakefiles = DEFAULT_BUILDFILES
|
120
|
-
@name = 'Buildr'
|
121
|
-
@requires = []
|
125
|
+
@rakefiles = DEFAULT_BUILDFILES.dup
|
122
126
|
@top_level_tasks = []
|
123
|
-
parse_options
|
124
|
-
collect_tasks
|
125
127
|
@home_dir = File.expand_path('.buildr', ENV['HOME'])
|
126
|
-
mkpath @home_dir
|
127
|
-
@
|
128
|
+
mkpath @home_dir unless File.exist?(@home_dir)
|
129
|
+
@settings = Settings.new(self)
|
128
130
|
@on_completion = []
|
129
131
|
@on_failure = []
|
130
132
|
end
|
131
133
|
|
134
|
+
def run
|
135
|
+
standard_exception_handling do
|
136
|
+
init 'Buildr'
|
137
|
+
load_buildfile
|
138
|
+
top_level
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Not for external consumption.
|
143
|
+
def switch_to_namespace(names) #:nodoc:
|
144
|
+
current, @scope = @scope, names
|
145
|
+
begin
|
146
|
+
yield
|
147
|
+
ensure
|
148
|
+
@scope = current
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
132
152
|
# Returns list of Gems associated with this buildfile, as listed in build.yaml.
|
133
153
|
# Each entry is of type Gem::Specification.
|
134
154
|
attr_reader :gems
|
@@ -137,13 +157,12 @@ module Buildr
|
|
137
157
|
attr_reader :home_dir
|
138
158
|
|
139
159
|
# Copied from BUILD_ENV.
|
140
|
-
|
160
|
+
def environment
|
161
|
+
ENV['BUILDR_ENV']
|
162
|
+
end
|
141
163
|
|
142
164
|
# Returns the Settings associated with this build.
|
143
|
-
|
144
|
-
fail "Internal error: Called Buildr.settings before buildfile located" unless rakefile
|
145
|
-
@settings ||= Settings.new(self)
|
146
|
-
end
|
165
|
+
attr_reader :settings
|
147
166
|
|
148
167
|
# :call-seq:
|
149
168
|
# buildfile
|
@@ -151,28 +170,13 @@ module Buildr
|
|
151
170
|
def buildfile
|
152
171
|
@buildfile_task ||= BuildfileTask.define_task(File.expand_path(rakefile))
|
153
172
|
end
|
154
|
-
|
173
|
+
|
155
174
|
# Files that complement the buildfile itself
|
156
175
|
def build_files #:nodoc:
|
176
|
+
deprecated 'Please call buildfile.prerequisites instead'
|
157
177
|
buildfile.prerequisites
|
158
178
|
end
|
159
179
|
|
160
|
-
def run
|
161
|
-
standard_exception_handling do
|
162
|
-
find_buildfile
|
163
|
-
load_gems
|
164
|
-
load_artifacts
|
165
|
-
load_tasks
|
166
|
-
load_requires
|
167
|
-
load_buildfile
|
168
|
-
load_imports
|
169
|
-
task('buildr:initialize').invoke
|
170
|
-
top_level
|
171
|
-
end
|
172
|
-
title, message = 'Your build has completed', "#{Dir.pwd}\nbuildr #{@top_level_tasks.join(' ')}"
|
173
|
-
@on_completion.each { |block| block.call(title, message) rescue nil }
|
174
|
-
end
|
175
|
-
|
176
180
|
# Yields to block on successful completion. Primarily used for notifications.
|
177
181
|
def on_completion(&block)
|
178
182
|
@on_completion << block
|
@@ -183,16 +187,6 @@ module Buildr
|
|
183
187
|
@on_failure << block
|
184
188
|
end
|
185
189
|
|
186
|
-
# Not for external consumption.
|
187
|
-
def switch_to_namespace(names) #:nodoc:
|
188
|
-
current, @scope = @scope, names
|
189
|
-
begin
|
190
|
-
yield
|
191
|
-
ensure
|
192
|
-
@scope = current
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
190
|
# :call-seq:
|
197
191
|
# deprecated(message)
|
198
192
|
#
|
@@ -213,30 +207,204 @@ module Buildr
|
|
213
207
|
end
|
214
208
|
end
|
215
209
|
|
216
|
-
|
210
|
+
protected
|
211
|
+
|
212
|
+
def load_buildfile # replaces load_rakefile
|
213
|
+
standard_exception_handling do
|
214
|
+
find_buildfile
|
215
|
+
load_gems
|
216
|
+
load_artifact_ns
|
217
|
+
load_tasks
|
218
|
+
raw_load_buildfile
|
219
|
+
end
|
220
|
+
end
|
217
221
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
def top_level # adds on_completion hook
|
223
|
+
standard_exception_handling do
|
224
|
+
if options.show_tasks
|
225
|
+
display_tasks_and_comments
|
226
|
+
elsif options.show_prereqs
|
227
|
+
display_prerequisites
|
228
|
+
elsif options.execute
|
229
|
+
eval options.execute
|
230
|
+
else
|
231
|
+
@start = Time.now
|
232
|
+
top_level_tasks.each { |task_name| invoke_task(task_name) }
|
233
|
+
if verbose
|
234
|
+
elapsed = Time.now - @start
|
235
|
+
real = []
|
236
|
+
real << ('%ih' % (elapsed / 3600)) if elapsed >= 3600
|
237
|
+
real << ('%im' % ((elapsed / 60) % 60)) if elapsed >= 60
|
238
|
+
real << ('%.3fs' % (elapsed % 60))
|
239
|
+
puts $terminal.color("Completed in #{real.join}", :green)
|
240
|
+
end
|
241
|
+
# On OS X this will load Cocoa and Growl which takes half a second we
|
242
|
+
# don't want to measure, so put this after the console message.
|
243
|
+
title, message = "Your build has completed", "#{Dir.pwd}\nbuildr #{@top_level_tasks.join(' ')}"
|
244
|
+
@on_completion.each do |block|
|
245
|
+
block.call(title, message) rescue nil
|
246
|
+
end
|
247
|
+
end
|
227
248
|
end
|
228
249
|
end
|
229
250
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
251
|
+
def handle_options
|
252
|
+
options.rakelib = ['tasks']
|
253
|
+
|
254
|
+
OptionParser.new do |opts|
|
255
|
+
opts.banner = "buildr [-f rakefile] {options} targets..."
|
256
|
+
opts.separator ""
|
257
|
+
opts.separator "Options are ..."
|
258
|
+
|
259
|
+
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
|
260
|
+
puts opts
|
261
|
+
exit
|
262
|
+
end
|
263
|
+
standard_buildr_options.each { |args| opts.on(*args) }
|
264
|
+
end.parse!
|
265
|
+
end
|
266
|
+
|
267
|
+
def standard_buildr_options # replaces standard_rake_options
|
268
|
+
[
|
269
|
+
['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
|
270
|
+
lambda { |value|
|
271
|
+
options.show_tasks = true
|
272
|
+
options.full_description = true
|
273
|
+
options.show_task_pattern = Regexp.new(value || '')
|
274
|
+
}
|
275
|
+
],
|
276
|
+
['--execute', '-E CODE',
|
277
|
+
"Execute some Ruby code after loading the buildfile",
|
278
|
+
lambda { |value| options.execute = value }
|
279
|
+
],
|
280
|
+
['--environment', '-e ENV',
|
281
|
+
"Environment name (e.g. development, test, production).",
|
282
|
+
lambda { |value| ENV['BUILDR_ENV'] = value }
|
283
|
+
],
|
284
|
+
['--generate [PATH]',
|
285
|
+
"Generate buildfile from either pom.xml file or directory path.",
|
286
|
+
lambda { |value|
|
287
|
+
value ||= File.exist?('pom.xml') ? 'pom.xml' : Dir.pwd
|
288
|
+
raw_generate_buildfile value
|
289
|
+
exit
|
290
|
+
}
|
291
|
+
],
|
292
|
+
['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
|
293
|
+
lambda { |value| $:.push(value) }
|
294
|
+
],
|
295
|
+
['--prereqs', '-P [PATTERN]', "Display the tasks and dependencies (matching optional PATTERN), then exit.",
|
296
|
+
lambda { |value|
|
297
|
+
options.show_prereqs = true
|
298
|
+
options.show_task_pattern = Regexp.new(value || '')
|
299
|
+
}
|
300
|
+
],
|
301
|
+
['--quiet', '-q', "Do not log messages to standard output.",
|
302
|
+
lambda { |value| verbose(false) }
|
303
|
+
],
|
304
|
+
['--buildfile', '-f FILE', "Use FILE as the buildfile.",
|
305
|
+
lambda { |value|
|
306
|
+
@rakefiles.clear
|
307
|
+
@rakefiles << value
|
308
|
+
}
|
309
|
+
],
|
310
|
+
['--rakelibdir', '--rakelib', '-R PATH',
|
311
|
+
"Auto-import any .rake files in PATH. (default is 'tasks')",
|
312
|
+
lambda { |value| options.rakelib = value.split(':') }
|
313
|
+
],
|
314
|
+
['--require', '-r MODULE', "Require MODULE before executing rakefile.",
|
315
|
+
lambda { |value|
|
316
|
+
begin
|
317
|
+
require value
|
318
|
+
rescue LoadError => ex
|
319
|
+
begin
|
320
|
+
rake_require value
|
321
|
+
rescue LoadError => ex2
|
322
|
+
raise ex
|
323
|
+
end
|
324
|
+
end
|
325
|
+
}
|
326
|
+
],
|
327
|
+
['--rules', "Trace the rules resolution.",
|
328
|
+
lambda { |value| options.trace_rules = true }
|
329
|
+
],
|
330
|
+
['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
|
331
|
+
lambda { |value| options.nosearch = true }
|
332
|
+
],
|
333
|
+
['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
|
334
|
+
lambda { |value|
|
335
|
+
verbose(false)
|
336
|
+
options.silent = true
|
337
|
+
}
|
338
|
+
],
|
339
|
+
['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
|
340
|
+
lambda { |value|
|
341
|
+
options.show_tasks = true
|
342
|
+
options.show_task_pattern = Regexp.new(value || '')
|
343
|
+
options.full_description = false
|
344
|
+
}
|
345
|
+
],
|
346
|
+
['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
|
347
|
+
lambda { |value|
|
348
|
+
options.trace = true
|
349
|
+
verbose(true)
|
350
|
+
}
|
351
|
+
],
|
352
|
+
['--verbose', '-v', "Log message to standard output (default).",
|
353
|
+
lambda { |value| verbose(true) }
|
354
|
+
],
|
355
|
+
['--version', '-V', "Display the program version.",
|
356
|
+
lambda { |value|
|
357
|
+
puts "Buildr #{Buildr::VERSION} #{RUBY_PLATFORM[/java/] && '(JRuby '+JRUBY_VERSION+')'}"
|
358
|
+
exit
|
359
|
+
}
|
360
|
+
]
|
361
|
+
]
|
362
|
+
end
|
363
|
+
|
364
|
+
def find_buildfile
|
365
|
+
buildfile, location = find_rakefile_location || (tty_output? && ask_generate_buildfile)
|
366
|
+
fail "No Buildfile found (looking for: #{@rakefiles.join(', ')})" if buildfile.nil?
|
367
|
+
@rakefile = buildfile
|
368
|
+
Dir.chdir(location)
|
369
|
+
end
|
370
|
+
|
371
|
+
def ask_generate_buildfile
|
372
|
+
source = choose do |menu|
|
373
|
+
menu.header = "To use Buildr you need a buildfile. Do you want me to create one?"
|
374
|
+
menu.choice("From Maven2 POM file") { 'pom.xml' } if File.exist?('pom.xml')
|
375
|
+
menu.choice("From directory structure") { Dir.pwd }
|
376
|
+
menu.choice("Cancel") { }
|
377
|
+
end
|
378
|
+
if source
|
379
|
+
buildfile = raw_generate_buildfile(source)
|
380
|
+
[buildfile, File.dirname(buildfile)]
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
def raw_generate_buildfile(source)
|
385
|
+
# We need rakefile to be known, for settings.build to be accessible.
|
386
|
+
@rakefile = File.expand_path(DEFAULT_BUILDFILES.first)
|
387
|
+
fail "Buildfile already exists" if File.exist?(@rakefile) && !(tty_output? && agree('Buildfile exists, overwrite?'))
|
388
|
+
script = File.directory?(source) ? Generate.from_directory(source) : Generate.from_maven2_pom(source)
|
389
|
+
File.open @rakefile, 'w' do |file|
|
390
|
+
file.puts script
|
391
|
+
end
|
392
|
+
puts "Created #{@rakefile}" if verbose
|
393
|
+
@rakefile
|
238
394
|
end
|
239
|
-
|
395
|
+
|
396
|
+
def raw_load_buildfile # replaces raw_load_rakefile
|
397
|
+
puts "(in #{Dir.pwd}, #{environment})" unless options.silent
|
398
|
+
load File.expand_path(@rakefile) if @rakefile && @rakefile != ''
|
399
|
+
options.rakelib.each do |rlib|
|
400
|
+
glob("#{rlib}/*.rake") do |name|
|
401
|
+
add_import name
|
402
|
+
end
|
403
|
+
end
|
404
|
+
load_imports
|
405
|
+
Buildr.projects
|
406
|
+
end
|
407
|
+
|
240
408
|
# Load/install all Gems specified in build.yaml file.
|
241
409
|
def load_gems #:nodoc:
|
242
410
|
missing_deps, installed = listed_gems.partition { |gem| gem.is_a?(Gem::Dependency) }
|
@@ -259,42 +427,35 @@ module Buildr
|
|
259
427
|
@gems = installed
|
260
428
|
end
|
261
429
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
exit 1
|
272
|
-
else
|
273
|
-
raise error
|
274
|
-
end
|
275
|
-
end
|
276
|
-
here = Dir.pwd
|
430
|
+
# Returns Gem::Specification for every listed and installed Gem, Gem::Dependency
|
431
|
+
# for listed and uninstalled Gem, which is the installed before loading the buildfile.
|
432
|
+
def listed_gems #:nodoc:
|
433
|
+
Array(settings.build['gems']).map do |dep|
|
434
|
+
name, trail = dep.scan(/^\s*(\S*)\s*(.*)\s*$/).first
|
435
|
+
versions = trail.scan(/[=><~!]{0,2}\s*[\d\.]+/)
|
436
|
+
versions = ['>= 0'] if versions.empty?
|
437
|
+
dep = Gem::Dependency.new(name, versions)
|
438
|
+
Gem::SourceIndex.from_installed_gems.search(dep).last || dep
|
277
439
|
end
|
278
440
|
end
|
279
441
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
442
|
+
# Load artifact specs from the build.yaml file, making them available
|
443
|
+
# by name ( ruby symbols ).
|
444
|
+
def load_artifact_ns #:nodoc:
|
445
|
+
hash = settings.build['artifacts']
|
446
|
+
return unless hash
|
447
|
+
raise "Expected 'artifacts' element to be a hash" unless Hash === hash
|
448
|
+
# Currently we only use one artifact namespace to rule them all. (the root NS)
|
449
|
+
Buildr::ArtifactNamespace.load(:root => hash)
|
288
450
|
end
|
289
|
-
|
451
|
+
|
290
452
|
# Loads buildr.rb files from users home directory and project directory.
|
291
453
|
# Loads custom tasks from .rake files in tasks directory.
|
292
454
|
def load_tasks #:nodoc:
|
455
|
+
# TODO: this might need to be split up, look for deprecated features, better method name.
|
293
456
|
files = [ File.expand_path('buildr.rb', ENV['HOME']), 'buildr.rb' ].select { |file| File.exist?(file) }
|
294
457
|
files += [ File.expand_path('buildr.rake', ENV['HOME']), File.expand_path('buildr.rake') ].
|
295
458
|
select { |file| File.exist?(file) }.each { |file| warn "Please use '#{file.ext('rb')}' instead of '#{file}'" }
|
296
|
-
#Load local tasks that can be used in the Buildfile.
|
297
|
-
files += Dir[File.expand_path('tasks/*.rake')]
|
298
459
|
files.each do |file|
|
299
460
|
unless $LOADED_FEATURES.include?(file)
|
300
461
|
load file
|
@@ -305,49 +466,68 @@ module Buildr
|
|
305
466
|
true
|
306
467
|
end
|
307
468
|
|
308
|
-
def
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
puts "buildr #{
|
313
|
-
|
469
|
+
def display_tasks_and_comments
|
470
|
+
displayable_tasks = tasks.select { |t| t.comment && t.name =~ options.show_task_pattern }
|
471
|
+
if options.full_description
|
472
|
+
displayable_tasks.each do |t|
|
473
|
+
puts "buildr #{t.name_with_args}"
|
474
|
+
t.full_comment.split("\n").each do |line|
|
475
|
+
puts " #{line}"
|
476
|
+
end
|
477
|
+
puts
|
478
|
+
end
|
479
|
+
else
|
480
|
+
width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
|
481
|
+
max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
|
482
|
+
displayable_tasks.each do |t|
|
483
|
+
printf "#{name} %-#{width}s # %s\n",
|
484
|
+
t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
|
314
485
|
end
|
315
486
|
end
|
316
487
|
end
|
317
|
-
|
318
|
-
|
319
|
-
|
488
|
+
|
489
|
+
def display_prerequisites
|
490
|
+
displayable_tasks = tasks.select { |t| t.name =~ options.show_task_pattern }
|
491
|
+
displayable_tasks.each do |t|
|
492
|
+
puts "buildr #{t.name}"
|
493
|
+
t.prerequisites.each { |pre| puts " #{pre}" }
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
def standard_exception_handling # adds on_failure hook
|
320
498
|
begin
|
321
499
|
yield
|
322
500
|
rescue SystemExit => ex
|
323
501
|
# Exit silently with current status
|
324
502
|
exit(ex.status)
|
325
|
-
rescue
|
326
|
-
|
503
|
+
rescue OptionParser::ParseError => ex
|
504
|
+
$stderr.puts $terminal.color(ex.message, :red)
|
327
505
|
exit(1)
|
328
506
|
rescue Exception => ex
|
329
|
-
title, message =
|
330
|
-
@on_failure.each
|
507
|
+
title, message = "Your build failed with an error", "#{Dir.pwd}:\n#{ex.message}"
|
508
|
+
@on_failure.each do |block|
|
509
|
+
block.call(title, message, ex) rescue nil
|
510
|
+
end
|
331
511
|
# Exit with error message
|
332
|
-
$stderr.puts "
|
512
|
+
$stderr.puts "Buildr aborted!"
|
333
513
|
$stderr.puts $terminal.color(ex.message, :red)
|
334
514
|
if options.trace
|
335
515
|
$stderr.puts ex.backtrace.join("\n")
|
336
516
|
else
|
337
|
-
$stderr.puts ex.backtrace.select { |str| str =~ /#{
|
517
|
+
$stderr.puts ex.backtrace.select { |str| str =~ /#{rakefile}/ }.map { |line| $terminal.color(line, :red) }.join("\n") if rakefile
|
338
518
|
$stderr.puts "(See full trace by running task with --trace)"
|
339
519
|
end
|
340
520
|
exit(1)
|
341
521
|
end
|
342
522
|
end
|
343
|
-
|
523
|
+
|
344
524
|
end
|
345
525
|
|
346
526
|
|
347
527
|
# This task stands for the buildfile and all its associated helper files (e.g., buildr.rb, build.yaml).
|
348
528
|
# By using this task as a prerequisite for other tasks, you can ensure these tasks will be needed
|
349
529
|
# whenever the buildfile changes.
|
350
|
-
class BuildfileTask < Rake::FileTask
|
530
|
+
class BuildfileTask < Rake::FileTask #:nodoc:
|
351
531
|
|
352
532
|
def timestamp
|
353
533
|
([name] + prerequisites).map { |f| File.stat(f).mtime }.max rescue Time.now
|
@@ -357,10 +537,6 @@ module Buildr
|
|
357
537
|
|
358
538
|
class << self
|
359
539
|
|
360
|
-
task 'buildr:initialize' do
|
361
|
-
Buildr.load_tasks_and_local_files
|
362
|
-
end
|
363
|
-
|
364
540
|
# Returns the Buildr::Application object.
|
365
541
|
def application
|
366
542
|
Rake.application
|
@@ -399,38 +575,6 @@ else
|
|
399
575
|
end
|
400
576
|
|
401
577
|
|
402
|
-
# Let's see if we can use Growl. We do this at the very end, loading Ruby Cocoa
|
403
|
-
# could slow the build down, so later is better. We only do this when running
|
404
|
-
# from the console in verbose mode.
|
405
|
-
if $stdout.isatty && verbose && RUBY_PLATFORM =~ /darwin/
|
406
|
-
begin
|
407
|
-
require 'osx/cocoa'
|
408
|
-
icon = OSX::NSApplication.sharedApplication.applicationIconImage
|
409
|
-
icon = OSX::NSImage.alloc.initWithContentsOfFile(File.join(File.dirname(__FILE__), '../resources/buildr.icns'))
|
410
|
-
|
411
|
-
# Register with Growl, that way you can turn notifications on/off from system preferences.
|
412
|
-
OSX::NSDistributedNotificationCenter.defaultCenter.
|
413
|
-
postNotificationName_object_userInfo_deliverImmediately(:GrowlApplicationRegistrationNotification, nil,
|
414
|
-
{ :ApplicationName=>'Buildr', :AllNotifications=>['Completed', 'Failed'],
|
415
|
-
:ApplicationIcon=>icon.TIFFRepresentation }, true)
|
416
|
-
|
417
|
-
notify = lambda do |type, title, message|
|
418
|
-
OSX::NSDistributedNotificationCenter.defaultCenter.
|
419
|
-
postNotificationName_object_userInfo_deliverImmediately(:GrowlNotification, nil,
|
420
|
-
{ :ApplicationName=>'Buildr', :NotificationName=>type,
|
421
|
-
:NotificationTitle=>title, :NotificationDescription=>message }, true)
|
422
|
-
end
|
423
|
-
Buildr.application.on_completion { |title, message| notify['Completed', title, message] }
|
424
|
-
Buildr.application.on_failure { |title, message, ex| notify['Failed', title, message] }
|
425
|
-
rescue Exception # No growl
|
426
|
-
end
|
427
|
-
elsif $stdout.isatty && verbose
|
428
|
-
notify = lambda { |type, title, message| $stdout.puts "[#{type}] #{title}: #{message}" }
|
429
|
-
Buildr.application.on_completion { |title, message| notify['Completed', title, message] }
|
430
|
-
Buildr.application.on_failure { |title, message, ex| notify['Failed', title, message] }
|
431
|
-
end
|
432
|
-
|
433
|
-
|
434
578
|
alias :warn_without_color :warn
|
435
579
|
|
436
580
|
# Show warning message.
|
@@ -457,6 +601,13 @@ end
|
|
457
601
|
|
458
602
|
|
459
603
|
module Rake #:nodoc
|
604
|
+
# Rake's circular dependency checks (InvocationChain) only applies to task prerequisites,
|
605
|
+
# all other cases result in the non too-descriptive thread sleeping error. This change can
|
606
|
+
# deal with circular dependencies that occur from direct task invocation, e.g:
|
607
|
+
# task 'foo'=>'bar'
|
608
|
+
# task 'bar' do
|
609
|
+
# task('foo').invoke
|
610
|
+
# end
|
460
611
|
class Task #:nodoc:
|
461
612
|
def invoke(*args)
|
462
613
|
task_args = TaskArguments.new(arg_names, args)
|
@@ -487,3 +638,22 @@ module Rake #:nodoc
|
|
487
638
|
end
|
488
639
|
end
|
489
640
|
end
|
641
|
+
|
642
|
+
|
643
|
+
module RakeFileUtils #:nodoc:
|
644
|
+
FileUtils::OPT_TABLE.each do |name, opts|
|
645
|
+
default_options = []
|
646
|
+
if opts.include?(:verbose) || opts.include?("verbose")
|
647
|
+
default_options << ':verbose => RakeFileUtils.verbose_flag == true'
|
648
|
+
end
|
649
|
+
next if default_options.empty?
|
650
|
+
module_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
651
|
+
def #{name}( *args, &block )
|
652
|
+
super(
|
653
|
+
*rake_merge_option(args,
|
654
|
+
#{default_options.join(', ')}
|
655
|
+
), &block)
|
656
|
+
end
|
657
|
+
EOS
|
658
|
+
end
|
659
|
+
end
|