buildr 1.3.0-java
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 +780 -0
- data/DISCLAIMER +7 -0
- data/KEYS +151 -0
- data/LICENSE +176 -0
- data/NOTICE +31 -0
- data/README +173 -0
- data/Rakefile +63 -0
- data/addon/buildr/antlr.rb +65 -0
- data/addon/buildr/cobertura.rb +232 -0
- data/addon/buildr/hibernate.rb +142 -0
- data/addon/buildr/javacc.rb +85 -0
- data/addon/buildr/jdepend.rb +60 -0
- data/addon/buildr/jetty.rb +248 -0
- data/addon/buildr/nailgun.rb +892 -0
- data/addon/buildr/openjpa.rb +90 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
- data/addon/buildr/xmlbeans.rb +93 -0
- data/bin/buildr +21 -0
- 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 +47 -0
- 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/buildr/core/build.rb +262 -0
- data/lib/buildr/core/checks.rb +382 -0
- 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/buildr/core/generate.rb +195 -0
- data/lib/buildr/core/help.rb +118 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/buildr/core/project.rb +890 -0
- data/lib/buildr/core/test.rb +690 -0
- data/lib/buildr/core/transports.rb +486 -0
- data/lib/buildr/core/util.rb +235 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/buildr/ide/eclipse.rb +181 -0
- data/lib/buildr/ide/idea.ipr.template +300 -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/buildr/java/pom.rb +178 -0
- 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/buildr/packaging/artifact.rb +729 -0
- 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/buildr/packaging/tar.rb +104 -0
- data/lib/buildr/packaging/zip.rb +719 -0
- 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 +324 -0
|
@@ -0,0 +1,85 @@
|
|
|
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/java'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
module Buildr
|
|
21
|
+
# Provides JavaCC compile tasks. Require explicitly using <code>require "buildr/javacc"</code>.
|
|
22
|
+
module JavaCC
|
|
23
|
+
|
|
24
|
+
REQUIRES = [ "net.java.dev.javacc:javacc:jar:4.0", "net.java.dev.javacc:javacc:jar:4.0" ]
|
|
25
|
+
|
|
26
|
+
Java.classpath << REQUIRES
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
|
|
30
|
+
def javacc(*args)
|
|
31
|
+
options = Hash === args.last ? args.pop : {}
|
|
32
|
+
rake_check_options options, :output
|
|
33
|
+
|
|
34
|
+
args = args.flatten.map(&:to_s).collect { |f| File.directory?(f) ? FileList[f + "/**/*.jj"] : f }.flatten
|
|
35
|
+
args.unshift "-OUTPUT_DIRECTORY=#{options[:output]}" if options[:output]
|
|
36
|
+
Java.load
|
|
37
|
+
Java.org.javacc.parser.Main.mainProgram(args.to_java(Java.java.lang.String)) == 0 or
|
|
38
|
+
fail "Failed to run JavaCC, see errors above."
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def jjtree(*args)
|
|
42
|
+
options = Hash === args.last ? args.pop : {}
|
|
43
|
+
rake_check_options options, :output, :build_node_files
|
|
44
|
+
|
|
45
|
+
args = args.flatten.map(&:to_s).collect { |f| File.directory?(f) ? FileList[f + "**/*.jjt"] : f }.flatten
|
|
46
|
+
args.unshift "-OUTPUT_DIRECTORY=#{options[:output]}" if options[:output]
|
|
47
|
+
args.unshift "-BUILD_NODE_FILES=#{options[:build_node_files] || false}"
|
|
48
|
+
Java.load
|
|
49
|
+
Java.org.javacc.jjtree.JJTree.new.main(args.to_java(Java.java.lang.String)) == 0 or
|
|
50
|
+
fail "Failed to run JJTree, see errors above."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def javacc(*args)
|
|
56
|
+
if Hash === args.last
|
|
57
|
+
options = args.pop
|
|
58
|
+
in_package = options[:in_package].split(".")
|
|
59
|
+
else
|
|
60
|
+
in_package = []
|
|
61
|
+
end
|
|
62
|
+
file(path_to(:target, :generated, :javacc)=>args.flatten) do |task|
|
|
63
|
+
JavaCC.javacc task.prerequisites, :output=>File.join(task.name, in_package)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def jjtree(*args)
|
|
68
|
+
if Hash === args.last
|
|
69
|
+
options = args.pop
|
|
70
|
+
in_package = options[:in_package].split(".")
|
|
71
|
+
build_node_files = options[:build_node_files]
|
|
72
|
+
else
|
|
73
|
+
in_package = []
|
|
74
|
+
end
|
|
75
|
+
file(path_to(:target, :generated, :jjtree)=>args.flatten) do |task|
|
|
76
|
+
JavaCC.jjtree task.prerequisites, :output=>File.join(task.name, in_package), :build_node_files=>build_node_files
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class Project
|
|
83
|
+
include JavaCC
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
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/java'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
module Buildr
|
|
21
|
+
|
|
22
|
+
# Addes the <code>jdepend:swing</code>, <code>jdepend:text</code> and <code>jdepend:xml</code> tasks.
|
|
23
|
+
# Require explicitly using <code>require "buildr/jdepend"</code>.
|
|
24
|
+
module Jdepend
|
|
25
|
+
|
|
26
|
+
REQUIRES = ["jdepend:jdepend:jar:2.9.1"]
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
|
|
30
|
+
def requires()
|
|
31
|
+
@requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def paths()
|
|
35
|
+
Project.projects.map(&:compile).each(&:invoke).map(&:target).
|
|
36
|
+
map(&:to_s).select { |path| File.exist?(path) }.map { |path| File.expand_path(path) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
namespace "jdepend" do
|
|
42
|
+
|
|
43
|
+
desc "Runs JDepend on all your projects (Swing UI)"
|
|
44
|
+
task "swing" do
|
|
45
|
+
Java::Commands.java "jdepend.swingui.JDepend", paths, :classpath=>requires, :name=>"JDepend"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
desc "Runs JDepend on all your projects (Text UI)"
|
|
49
|
+
task "text" do
|
|
50
|
+
Java::Commands.java "jdepend.textui.JDepend", paths, :classpath=>requires, :name=>"JDepend"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Runs JDepend on all your projects (XML output to jdepend.xml)"
|
|
54
|
+
task "xml" do
|
|
55
|
+
Java::Commands.java "jdepend.xmlui.JDepend", "-file", "jdepend.xml", paths, :classpath=>requires, :name=>"JDepend"
|
|
56
|
+
puts "Created jdepend.xml"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,248 @@
|
|
|
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 'uri'
|
|
18
|
+
require 'net/http'
|
|
19
|
+
require 'buildr/core/project'
|
|
20
|
+
require 'buildr/java'
|
|
21
|
+
require 'buildr/packaging'
|
|
22
|
+
require 'thread'
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
module Buildr
|
|
26
|
+
|
|
27
|
+
# Provides a collection of tasks and methods for using Jetty, specifically as a server
|
|
28
|
+
# for testing your application.
|
|
29
|
+
#
|
|
30
|
+
# Build files should always start Jetty by invoking the #use task, typically as
|
|
31
|
+
# a prerequisite. This task will start Jetty once during the build, and shut it down
|
|
32
|
+
# when the build completes.
|
|
33
|
+
#
|
|
34
|
+
# If you want to keep Jetty running across builds, and look at error messages, you can
|
|
35
|
+
# start Jetty in a separate console with:
|
|
36
|
+
# buildr jetty:start
|
|
37
|
+
# To stop this instance of Jetty, simply kill the process (Ctrl-C) or run:
|
|
38
|
+
# buildr jetty:stop
|
|
39
|
+
#
|
|
40
|
+
# If you start Jetty separately from the build, the #use task will connect to that
|
|
41
|
+
# existing server. Since you are using Jetty across several builds, you will want to
|
|
42
|
+
# cleanup any mess created by each build. You can use the #setup and #teardown tasks,
|
|
43
|
+
# which are called when Jetty is first used in the build, and when the build ends.
|
|
44
|
+
class Jetty
|
|
45
|
+
|
|
46
|
+
# Which version of Jetty we're using by default (change with options.jetty.version).
|
|
47
|
+
VERSION = "6.1.3" unless const_defined?('VERSION')
|
|
48
|
+
SLF4J_VERSION = "1.4.3"
|
|
49
|
+
|
|
50
|
+
# Libraries used by Jetty.
|
|
51
|
+
REQUIRES = [ "org.mortbay.jetty:jetty:jar:#{VERSION}", "org.mortbay.jetty:jetty-util:jar:#{VERSION}",
|
|
52
|
+
"org.mortbay.jetty:servlet-api-2.5:jar:#{VERSION}", "org.slf4j:slf4j-api:jar:#{SLF4J_VERSION}",
|
|
53
|
+
"org.slf4j:slf4j-simple:jar:#{SLF4J_VERSION}", "org.slf4j:jcl104-over-slf4j:jar:#{SLF4J_VERSION}" ]
|
|
54
|
+
|
|
55
|
+
Java.classpath << REQUIRES
|
|
56
|
+
Java.classpath << File.dirname(__FILE__)
|
|
57
|
+
|
|
58
|
+
# Default URL for Jetty (change with options.jetty.url).
|
|
59
|
+
URL = "http://localhost:8080"
|
|
60
|
+
|
|
61
|
+
class << self
|
|
62
|
+
|
|
63
|
+
# :call-seq:
|
|
64
|
+
# instance() => Jetty
|
|
65
|
+
#
|
|
66
|
+
# Returns an instance of Jetty.
|
|
67
|
+
def instance()
|
|
68
|
+
@instance ||= Jetty.new("jetty", URL)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def initialize(name, url) #:nodoc:
|
|
74
|
+
@url = url
|
|
75
|
+
namespace name do
|
|
76
|
+
@setup = task("setup")
|
|
77
|
+
@teardown = task("teardown")
|
|
78
|
+
@use = task("use") { fire }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The URL for the Jetty server. Leave as is if you want to use the default server
|
|
83
|
+
# (http://localhost:8080).
|
|
84
|
+
attr_accessor :url
|
|
85
|
+
|
|
86
|
+
# :call-seq:
|
|
87
|
+
# start(pipe?)
|
|
88
|
+
#
|
|
89
|
+
# Starts Jetty. This method does not return, it keeps the thread running until
|
|
90
|
+
# Jetty is stopped. If you want to run Jetty parallel with other tasks in the build,
|
|
91
|
+
# invoke the #use task instead.
|
|
92
|
+
def start(sync = nil)
|
|
93
|
+
begin
|
|
94
|
+
puts "classpath #{Java.classpath.inspect}"
|
|
95
|
+
port = URI.parse(url).port
|
|
96
|
+
puts "Starting Jetty at http://localhost:#{port}" if verbose
|
|
97
|
+
Java.load
|
|
98
|
+
jetty = Java.org.apache.buildr.JettyWrapper.new(port)
|
|
99
|
+
sync << "Started" if sync
|
|
100
|
+
sleep # Forever
|
|
101
|
+
rescue Interrupt # Stopped from console
|
|
102
|
+
rescue Exception=>error
|
|
103
|
+
puts "#{error.class}: #{error.message}"
|
|
104
|
+
end
|
|
105
|
+
exit! # No at_exit
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# :call-seq:
|
|
109
|
+
# stop()
|
|
110
|
+
#
|
|
111
|
+
# Stops Jetty. Stops a server running in a separate process.
|
|
112
|
+
def stop()
|
|
113
|
+
uri = URI.parse(url)
|
|
114
|
+
begin
|
|
115
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
116
|
+
http.request_post "/buildr/stop", ""
|
|
117
|
+
end
|
|
118
|
+
rescue Errno::ECONNREFUSED
|
|
119
|
+
# Expected if Jetty server not running.
|
|
120
|
+
rescue EOFError
|
|
121
|
+
# We get EOFError because Jetty is brutally killed.
|
|
122
|
+
end
|
|
123
|
+
puts "Jetty server stopped"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# :call-seq:
|
|
127
|
+
# running?() => boolean
|
|
128
|
+
#
|
|
129
|
+
# Returns true if it finds a running Jetty server that supports the Buildr
|
|
130
|
+
# requests for deploying, stopping, etc.
|
|
131
|
+
def running?()
|
|
132
|
+
uri = URI.parse(url)
|
|
133
|
+
begin
|
|
134
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
135
|
+
response = http.request_get("/buildr/")
|
|
136
|
+
response.is_a?(Net::HTTPSuccess) && response.body =~ /Alive/
|
|
137
|
+
end
|
|
138
|
+
rescue Errno::ECONNREFUSED, Errno::EBADF
|
|
139
|
+
false
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# :call-seq:
|
|
144
|
+
# deploy(url, webapp) => path
|
|
145
|
+
#
|
|
146
|
+
# Deploy a WAR in the specified URL.
|
|
147
|
+
def deploy(url, webapp)
|
|
148
|
+
use.invoke
|
|
149
|
+
uri = URI.parse(url)
|
|
150
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
151
|
+
response = http.request_post("/buildr/deploy", "webapp=#{webapp}&path=#{uri.path}")
|
|
152
|
+
if Net::HTTPOK === response && response.body =~ /Deployed/
|
|
153
|
+
path = response.body.split[1]
|
|
154
|
+
puts "Deployed #{webapp}, context path #{uri.path}" if Rake.application.options.trace
|
|
155
|
+
path
|
|
156
|
+
else
|
|
157
|
+
fail "Deployment failed: #{response}"
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# :call-seq:
|
|
163
|
+
# undeploy(url) => boolean
|
|
164
|
+
#
|
|
165
|
+
# Undeploys a WAR from the specified URL.
|
|
166
|
+
def undeploy(url)
|
|
167
|
+
use.invoke
|
|
168
|
+
uri = URI.parse(url)
|
|
169
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
170
|
+
response = http.request_post("/buildr/undeploy", "path=#{uri.path}")
|
|
171
|
+
if Net::HTTPOK === response && response.body =~ /Undeployed/
|
|
172
|
+
true
|
|
173
|
+
else
|
|
174
|
+
fail "Deployment failed: #{response}"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# :call-seq:
|
|
180
|
+
# setup(*prereqs) => task
|
|
181
|
+
# setup(*prereqs) { |task| .. } => task
|
|
182
|
+
#
|
|
183
|
+
# This task executes when Jetty is first used in the build. You can use it to
|
|
184
|
+
# deploy artifacts into Jetty.
|
|
185
|
+
def setup(*prereqs, &block)
|
|
186
|
+
@setup.enhance prereqs, &block
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# :call-seq:
|
|
190
|
+
# teardown(*prereqs) => task
|
|
191
|
+
# teardown(*prereqs) { |task| .. } => task
|
|
192
|
+
#
|
|
193
|
+
# This task executes when the build is done. You can use it to undeploy artifacts
|
|
194
|
+
# previously deployed into Jetty.
|
|
195
|
+
def teardown(*prereqs, &block)
|
|
196
|
+
@teardown.enhance prereqs, &block
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# :call-seq:
|
|
200
|
+
# use(*prereqs) => task
|
|
201
|
+
# use(*prereqs) { |task| .. } => task
|
|
202
|
+
#
|
|
203
|
+
# If you intend to use Jetty, invoke this task. It will start a new instance of
|
|
204
|
+
# Jetty and close it when the build is done. However, if you already have a server
|
|
205
|
+
# running in the background (e.g. jetty:start), it will use that server and will
|
|
206
|
+
# not close it down.
|
|
207
|
+
def use(*prereqs, &block)
|
|
208
|
+
@use.enhance prereqs, &block
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
protected
|
|
212
|
+
|
|
213
|
+
# If you want to start Jetty inside the build, call this method instead of #start.
|
|
214
|
+
# It will spawn a separate process that will run Jetty, and will stop Jetty when
|
|
215
|
+
# the build ends. However, if you already started Jetty from the console (with
|
|
216
|
+
# take jetty:start), it will use the existing instance without shutting it down.
|
|
217
|
+
def fire()
|
|
218
|
+
unless running?
|
|
219
|
+
sync = Queue.new
|
|
220
|
+
Thread.new { start sync }
|
|
221
|
+
# Wait for Jetty to fire up before doing anything else.
|
|
222
|
+
sync.pop == "Started" or fail "Jetty not started"
|
|
223
|
+
puts "Jetty started" if verbose
|
|
224
|
+
at_exit { stop }
|
|
225
|
+
end
|
|
226
|
+
@setup.invoke
|
|
227
|
+
at_exit { @teardown.invoke }
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
namespace "jetty" do
|
|
233
|
+
desc "Start an instance of Jetty running in the background"
|
|
234
|
+
task("start") { Jetty.instance.start }
|
|
235
|
+
desc "Stop an instance of Jetty running in the background"
|
|
236
|
+
task("stop") { Jetty.instance.stop }
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# :call-seq:
|
|
240
|
+
# jetty() => Jetty
|
|
241
|
+
#
|
|
242
|
+
# Returns a Jetty object. You can use this to discover the Jetty#use task,
|
|
243
|
+
# configure the Jetty#setup and Jetty#teardown tasks, deploy and undeploy to Jetty.
|
|
244
|
+
def jetty()
|
|
245
|
+
@jetty ||= Jetty.instance
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
end
|
|
@@ -0,0 +1,892 @@
|
|
|
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 'benchmark'
|
|
18
|
+
require 'jruby'
|
|
19
|
+
require 'monitor'
|
|
20
|
+
require 'ostruct'
|
|
21
|
+
require 'rbconfig'
|
|
22
|
+
require 'thread'
|
|
23
|
+
require 'buildr/core/application_cli'
|
|
24
|
+
|
|
25
|
+
module Buildr
|
|
26
|
+
|
|
27
|
+
# See the nailgun_help method for documentation.
|
|
28
|
+
module Nailgun # :nodoc:
|
|
29
|
+
extend self
|
|
30
|
+
|
|
31
|
+
VERSION = '0.7.1'
|
|
32
|
+
NAME = "nailgun-#{VERSION}"
|
|
33
|
+
URL = "http://downloads.sourceforge.net/nailgun/#{NAME}.zip"
|
|
34
|
+
ARTIFACT_SPEC = "com.martiansoftware:nailgun:jar:#{VERSION}"
|
|
35
|
+
BUILDR_PATHS = [File.expand_path('../', File.dirname(__FILE__)),
|
|
36
|
+
File.expand_path('../../lib', File.dirname(__FILE__))]
|
|
37
|
+
|
|
38
|
+
attr_accessor :artifact
|
|
39
|
+
attr_accessor :server, :port, :jruby_queue_size, :buildr_queue_size
|
|
40
|
+
attr_accessor :jruby_home, :home
|
|
41
|
+
|
|
42
|
+
self.jruby_home = if PLATFORM =~ /java/
|
|
43
|
+
Config::CONFIG['prefix']
|
|
44
|
+
else
|
|
45
|
+
ENV['JRUBY_HOME'] || File.join(ENV['HOME'], '.jruby')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
self.home = ENV['NAILGUN_HOME'] || File.join(jruby_home, 'tool', 'nailgun')
|
|
49
|
+
self.server = 'localhost'
|
|
50
|
+
self.port = 2113
|
|
51
|
+
self.jruby_queue_size = 3
|
|
52
|
+
self.buildr_queue_size = 3
|
|
53
|
+
|
|
54
|
+
def namespace(&block)
|
|
55
|
+
if Object.const_defined?(:Rake)
|
|
56
|
+
Rake.application.in_namespace(:nailgun, &block)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def boot(&block)
|
|
61
|
+
if block
|
|
62
|
+
@boot = block
|
|
63
|
+
else
|
|
64
|
+
@boot.call
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
module Application
|
|
69
|
+
def nailgun_help
|
|
70
|
+
" " + <<-DESC.strip.gsub(/ *\n +/, "\n ")
|
|
71
|
+
NailGun is a client, protocol, and server for running Java
|
|
72
|
+
programs from the command line without incurring the JVM
|
|
73
|
+
startup overhead. Nailgun integration is currently available
|
|
74
|
+
only when running Buildr with JRuby.
|
|
75
|
+
|
|
76
|
+
Buildr provides a custom nailgun server, allowing you to
|
|
77
|
+
start a single JVM and let buildr create a queue of runtimes.
|
|
78
|
+
These JRuby runtimes can be cached (indexed by buildfile path)
|
|
79
|
+
and are automatically reloaded when the buildfile has been modified.
|
|
80
|
+
Runtime caching allows you to execute tasks without
|
|
81
|
+
spending time creating the buildr environment. Some nailgun
|
|
82
|
+
tasks have been provided to manage the cached runtimes.
|
|
83
|
+
|
|
84
|
+
To start the buildr server execute the following task:
|
|
85
|
+
|
|
86
|
+
nailgun:start
|
|
87
|
+
|
|
88
|
+
Server output will display a message when it becomes ready, you
|
|
89
|
+
will also see messages when the JRuby runtimes are being created,
|
|
90
|
+
or when a new buildr environment is being loaded on them.
|
|
91
|
+
After the runtime queues have been populated, you can start calling
|
|
92
|
+
buildr as you normally do, by invoking the $NAILGUN_HOME/ng binary:
|
|
93
|
+
|
|
94
|
+
# on another terminal, change directory to a project.
|
|
95
|
+
# if this project is the same nailgun:start was invoked on, it's
|
|
96
|
+
# runtime has been cached, so no loading is performed unless
|
|
97
|
+
# the buildfile has been modified. otherwise the buildfile
|
|
98
|
+
# will be loaded on a previously loaded fresh-buildr runtime
|
|
99
|
+
# and it will be cached.
|
|
100
|
+
cd /some/buildr/project
|
|
101
|
+
ng nailgun:help # display nailgun help
|
|
102
|
+
ng nailgun:tasks # display overview of ng tasks
|
|
103
|
+
ng clean compile # just invoke those two tasks
|
|
104
|
+
|
|
105
|
+
Configuration and Environment Variables.
|
|
106
|
+
|
|
107
|
+
Before starting the server, buildr will check if you have
|
|
108
|
+
nailgun already installed by seeking the nailgun jar under
|
|
109
|
+
|
|
110
|
+
$NAILGUN_HOME
|
|
111
|
+
|
|
112
|
+
You can override this environment variable to tell buildr where
|
|
113
|
+
to find or where to install nailgun. If missing, NAILGUN_HOME
|
|
114
|
+
defaults to the $JRUBY_HOME/tool/nailgun directory. You can
|
|
115
|
+
also specify the nailgun_home on your buildfile with the following
|
|
116
|
+
code:
|
|
117
|
+
|
|
118
|
+
require 'buildr/nailgun'
|
|
119
|
+
Buildr::Nailgun.home = File.expand_path('~/.jruby/tool/nailgun')
|
|
120
|
+
|
|
121
|
+
Buildr will also check that the nailgun client binary (ng.exe for
|
|
122
|
+
Windows systems, ng otherwise) is installed on NAILGUN_HOME.
|
|
123
|
+
If no binary is found, buildr will download nailgun and
|
|
124
|
+
compile+install it.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
The buildr server binds itself to localhost, port 2113. You can
|
|
128
|
+
override this on your buildfile, by placing the following code:
|
|
129
|
+
|
|
130
|
+
require 'buildr/nailgun'
|
|
131
|
+
Buildr::Nailgun.server = '127.0.0.1'
|
|
132
|
+
Buildr::Nailgun.port = 2233
|
|
133
|
+
|
|
134
|
+
If you provided custom host/port settings you need
|
|
135
|
+
to tell the nailgun client where to connect to:
|
|
136
|
+
|
|
137
|
+
ng --nailgun-server 127.0.0.1 --nailgun-port 2233 nailgun:tasks
|
|
138
|
+
|
|
139
|
+
The buildr server starts a BuildrFactory responsible for providing
|
|
140
|
+
a pool of JRuby runtimes configured and ready for task execution.
|
|
141
|
+
This BuildrFactory consists of two queues: One of pure JRuby runtimes
|
|
142
|
+
with almost nothing loaded, and another of Buildr runtimes (consumed
|
|
143
|
+
from the first queue) with the Buildr runtime preloaded but without
|
|
144
|
+
any project definition. The jruby queue is used for sandboxing code
|
|
145
|
+
like running GetoptLong, but most importantly its the place where
|
|
146
|
+
buildr runtimes begin life, to be later added on the buildr queue.
|
|
147
|
+
By default both queues are of size 3, you can customize this with:
|
|
148
|
+
|
|
149
|
+
require 'buildr/nailgun'
|
|
150
|
+
Buildr::Nailgun.jruby_queue_size = 4 # JRuby creation is fast!
|
|
151
|
+
Buildr::Nailgun.buildr_queue_size = 5 # loading buildr takes longer
|
|
152
|
+
|
|
153
|
+
The buildr_queue_size is of particular importance if you expect to
|
|
154
|
+
reload lots of buildfiles.
|
|
155
|
+
|
|
156
|
+
Execute nailgun:tasks get an overview of available nailgun tasks.
|
|
157
|
+
|
|
158
|
+
DESC
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def nailgun_tasks
|
|
162
|
+
tasks = {}
|
|
163
|
+
tasks['nailgun:help'] = 'Display nailgun help'
|
|
164
|
+
tasks['nailgun:start'] = 'Start the Nailgun server.'
|
|
165
|
+
tasks['nailgun:stop'] = 'Stop the Nailgun server.'
|
|
166
|
+
tasks['nailgun:tasks'] = 'Display this message'
|
|
167
|
+
tasks['nailgun:list'] = <<-DESC
|
|
168
|
+
Display a list of builfile paths having an associated
|
|
169
|
+
buildr runtime. Having a cached runtime reduces buidlr
|
|
170
|
+
execution time.
|
|
171
|
+
|
|
172
|
+
If buildr finds the current buildfile on this list,
|
|
173
|
+
no file loading will be performed, only execution of
|
|
174
|
+
specified tasks on the previously loaded environment.
|
|
175
|
+
However if the cached runtime is out of date (buildfile
|
|
176
|
+
has been modified) the runtime will be reloaded.
|
|
177
|
+
|
|
178
|
+
This feature becomes handy when performing development
|
|
179
|
+
cycle: edit -> compile -> test -> report.
|
|
180
|
+
|
|
181
|
+
This task exits inmediatly after printing the file list.
|
|
182
|
+
DESC
|
|
183
|
+
tasks['nailgun:clear'] = <<-DESC
|
|
184
|
+
Remove all cached buildr runtimes and exit
|
|
185
|
+
DESC
|
|
186
|
+
tasks['nailgun:load'] = <<-DESC
|
|
187
|
+
Add or update a cached runtime.
|
|
188
|
+
|
|
189
|
+
Use this task to create a cached buildr runtime for a
|
|
190
|
+
buildfile.
|
|
191
|
+
DESC
|
|
192
|
+
tasks['nailgun:delete'] = <<-DESC
|
|
193
|
+
Delete cached runtime for a buildfile and exit.
|
|
194
|
+
DESC
|
|
195
|
+
tasks['nailgun:once [tasks]'] = <<-DESC
|
|
196
|
+
Ignore cached runtime and perform tasks on a newly
|
|
197
|
+
created environment. This new runtime is dropped right
|
|
198
|
+
after buildr completion.
|
|
199
|
+
DESC
|
|
200
|
+
|
|
201
|
+
out = ""
|
|
202
|
+
out << "\nNailgun tasks:\n"
|
|
203
|
+
tasks.each_pair do |task, desc|
|
|
204
|
+
out << "\n"
|
|
205
|
+
out << sprintf(" %20-s\n", [task].flatten.join(' | '))
|
|
206
|
+
out << sprintf(" %s\n", desc.strip.gsub(/ *\n +/, "\n "))
|
|
207
|
+
end
|
|
208
|
+
out
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def buildfile(dir = nil, candidates = nil)
|
|
212
|
+
dir ||= Dir.pwd
|
|
213
|
+
candidates ||= @rakefiles.dup
|
|
214
|
+
Util.find_buildfile(dir, candidates, options.nosearch)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def clear_invoked
|
|
218
|
+
tasks.each do |task|
|
|
219
|
+
is_project = Project.instance_variable_get(:@projects).key?(task.name)
|
|
220
|
+
task.instance_variable_set(:@already_invoked, false) unless is_project
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
if Buildr.const_defined?(:Application)
|
|
225
|
+
class Buildr::Application
|
|
226
|
+
include Nailgun::Application
|
|
227
|
+
public :requires
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
module ContextRunner
|
|
233
|
+
extend self
|
|
234
|
+
|
|
235
|
+
def parse_options(ctx, opts)
|
|
236
|
+
opts.requires = []
|
|
237
|
+
Buildr.const_set(:VERSION, ctx.server.runtime.object.const_get(:Buildr)::VERSION)
|
|
238
|
+
|
|
239
|
+
obj = OpenStruct.new(:ctx => ctx, :opts => opts)
|
|
240
|
+
class << obj
|
|
241
|
+
include Buildr::CommandLineInterface
|
|
242
|
+
|
|
243
|
+
def help
|
|
244
|
+
super
|
|
245
|
+
puts
|
|
246
|
+
puts 'To get a summary of Nailgun features use'
|
|
247
|
+
puts ' nailgun:help'
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def do_option(opt, value)
|
|
251
|
+
case opt
|
|
252
|
+
when '--help'
|
|
253
|
+
help
|
|
254
|
+
opts.exit = true
|
|
255
|
+
when '--version'
|
|
256
|
+
puts version
|
|
257
|
+
opts.exit = true
|
|
258
|
+
when '--environment'
|
|
259
|
+
ctx.env['BUILDR_ENV'] = value
|
|
260
|
+
when '--buildfile'
|
|
261
|
+
opts.buildfile = value
|
|
262
|
+
when '--require'
|
|
263
|
+
opts.requires << value
|
|
264
|
+
when '--nosearch'
|
|
265
|
+
opts.nosearch = true
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
ARGV.replace(ctx.argv)
|
|
271
|
+
obj.parse_options
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def run(ctx)
|
|
275
|
+
ARGV.replace(ctx.argv)
|
|
276
|
+
Dir.chdir(ctx.pwd)
|
|
277
|
+
ctx.env.each { |k, v| ENV[k.to_s] = v.to_s }
|
|
278
|
+
Buildr::Application.module_eval do
|
|
279
|
+
include Nailgun::Application
|
|
280
|
+
end
|
|
281
|
+
task 'nailgun:load' do
|
|
282
|
+
puts "Buildfile #{Rake.application.buildfile} loaded"
|
|
283
|
+
end
|
|
284
|
+
if ctx.fresh
|
|
285
|
+
run_fresh(ctx)
|
|
286
|
+
else
|
|
287
|
+
run_local(ctx)
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
private
|
|
292
|
+
|
|
293
|
+
def run_fresh(ctx)
|
|
294
|
+
Project.clear
|
|
295
|
+
old_app = Rake.application
|
|
296
|
+
Rake.application = Buildr::Application.new
|
|
297
|
+
Rake.application.instance_eval do
|
|
298
|
+
@tasks = old_app.instance_variable_get(:@tasks)
|
|
299
|
+
@rules = old_app.instance_variable_get(:@rules)
|
|
300
|
+
run
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def run_local(ctx)
|
|
305
|
+
Rake.application.instance_eval do
|
|
306
|
+
verbose(nil)
|
|
307
|
+
options.trace = false
|
|
308
|
+
parse_options
|
|
309
|
+
collect_tasks
|
|
310
|
+
clear_invoked
|
|
311
|
+
top_level_tasks.delete('buildr:initialize')
|
|
312
|
+
Util.benchmark { top_level }
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
module Util
|
|
318
|
+
extend self
|
|
319
|
+
|
|
320
|
+
def find_buildfile(pwd, candidates, nosearch=false)
|
|
321
|
+
candidates = [candidates].flatten
|
|
322
|
+
buildfile = candidates.find { |c| File.file?(File.expand_path(c, pwd)) }
|
|
323
|
+
return File.expand_path(buildfile, pwd) if buildfile
|
|
324
|
+
return nil if nosearch
|
|
325
|
+
updir = File.dirname(pwd)
|
|
326
|
+
return nil if File.expand_path(updir) == File.expand_path(pwd)
|
|
327
|
+
find_buildfile(updir, candidates)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def benchmark(action = ['Completed'], verbose = true)
|
|
331
|
+
result = nil
|
|
332
|
+
times = Benchmark.measure do
|
|
333
|
+
result = yield(action)
|
|
334
|
+
end
|
|
335
|
+
if verbose
|
|
336
|
+
real = []
|
|
337
|
+
real << ("%ih" % (times.real / 3600)) if times.real >= 3600
|
|
338
|
+
real << ("%im" % ((times.real / 60) % 60)) if times.real >= 60
|
|
339
|
+
real << ("%.3fs" % (times.real % 60))
|
|
340
|
+
puts "#{[action].flatten.join(' ')} in #{real.join}"
|
|
341
|
+
end
|
|
342
|
+
result
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def on_runtime(runtime, *args, &block)
|
|
346
|
+
raise_error = lambda do |cls, msg, trace|
|
|
347
|
+
raise RuntimeError.new(cls + ": "+ msg.to_s).tap { |e| e.set_backtrace(trace.map(&:to_s)) }
|
|
348
|
+
end
|
|
349
|
+
executor = runtime.object.const_get(:Module).new do
|
|
350
|
+
extend self
|
|
351
|
+
def runtime_exec(*args, &prc)
|
|
352
|
+
define_method(:runtime_exec, &prc)
|
|
353
|
+
runtime_exec(*args)
|
|
354
|
+
rescue => e
|
|
355
|
+
[:error, e.class.name, e.message, e.backtrace]
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
result = executor.runtime_exec(*args, &block)
|
|
359
|
+
raise_error.call(*result[1..-1]) if result.kind_of?(Array) && result.first == :error
|
|
360
|
+
result
|
|
361
|
+
end
|
|
362
|
+
end # module Util
|
|
363
|
+
|
|
364
|
+
boot do
|
|
365
|
+
|
|
366
|
+
class ::ConcreteJavaProxy
|
|
367
|
+
def self.jclass(name = nil)
|
|
368
|
+
name ||= self.java_class.name
|
|
369
|
+
Nailgun::Util.class_for_name(name)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def self.jnew(*args)
|
|
373
|
+
objs = []
|
|
374
|
+
classes = args.map do |a|
|
|
375
|
+
case a
|
|
376
|
+
when nil
|
|
377
|
+
obj << nil
|
|
378
|
+
nil
|
|
379
|
+
when Hash
|
|
380
|
+
objs << a.keys.first
|
|
381
|
+
cls = a.values.first
|
|
382
|
+
cls = Nailgun::Util.proxy_class(cls) if String == cls
|
|
383
|
+
cls
|
|
384
|
+
else
|
|
385
|
+
objs << a
|
|
386
|
+
a.java_class
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
classes = classes.to_java(java.lang.Class)
|
|
390
|
+
ctor = jclass.getDeclaredConstructor(classes)
|
|
391
|
+
ctor.setAccessible(true)
|
|
392
|
+
ctor.newInstance(objs.to_java(java.lang.Object))
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
module Util
|
|
397
|
+
def class_for_name(name)
|
|
398
|
+
java.lang.Class.forName(name)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def add_to_sysloader(path)
|
|
402
|
+
sysloader = java.lang.ClassLoader.system_class_loader
|
|
403
|
+
add_url_method = class_for_name('java.net.URLClassLoader').
|
|
404
|
+
getDeclaredMethod('addURL', [java.net.URL].to_java(java.lang.Class))
|
|
405
|
+
add_url_method.accessible = true
|
|
406
|
+
add_url_method.invoke(sysloader, [java.io.File.new(path.to_s).
|
|
407
|
+
toURL].to_java(java.net.URL))
|
|
408
|
+
end
|
|
409
|
+
add_to_sysloader Nailgun.artifact
|
|
410
|
+
|
|
411
|
+
def proxy_class(name)
|
|
412
|
+
JavaUtilities.get_proxy_class(name)
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
import org.jruby.RubyIO
|
|
416
|
+
def set_stdio(runtime, dev)
|
|
417
|
+
set_global = lambda do |global, constant, stream|
|
|
418
|
+
runtime.global_variables.set(global, stream)
|
|
419
|
+
runtime.object.send(:remove_const, constant)
|
|
420
|
+
runtime.object.send(:const_set, constant, stream)
|
|
421
|
+
end
|
|
422
|
+
stdin = runtime.global_variables.get('$stdin')
|
|
423
|
+
stdout = runtime.global_variables.get('$stdout')
|
|
424
|
+
stderr = runtime.global_variables.get('$stderr')
|
|
425
|
+
input = RubyIO.jnew(runtime, dev.in => java.io.InputStream)
|
|
426
|
+
output = RubyIO.jnew(runtime, dev.out => java.io.OutputStream)
|
|
427
|
+
error = RubyIO.jnew(runtime, dev.err => java.io.OutputStream)
|
|
428
|
+
# stdin.reopen(input, 'r') # not working on jruby, :(
|
|
429
|
+
set_global.call('$stdin', 'STDIN', input)
|
|
430
|
+
stdout.reopen(output, 'w')
|
|
431
|
+
stderr.reopen(error, 'w')
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
def redirect_stdio(runtime, nail)
|
|
435
|
+
result = nil
|
|
436
|
+
begin
|
|
437
|
+
set_stdio(runtime, nail)
|
|
438
|
+
result = yield
|
|
439
|
+
ensure
|
|
440
|
+
set_stdio(runtime, java.lang.System)
|
|
441
|
+
end
|
|
442
|
+
result
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
class Buildfile
|
|
447
|
+
attr_reader :path, :requires, :loaded_time
|
|
448
|
+
attr_accessor :runtime
|
|
449
|
+
|
|
450
|
+
def initialize(path, *requires)
|
|
451
|
+
@path = File.expand_path(path)
|
|
452
|
+
@requires = requires.dup
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def loaded!
|
|
456
|
+
@loaded_time = Time.now
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def last_modification
|
|
460
|
+
File.timestamp(path)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def should_be_loaded?
|
|
464
|
+
(loaded_time || Rake::EARLY) < last_modification
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def to_s
|
|
468
|
+
buff = path.dup
|
|
469
|
+
buff << sprintf("\n %-25s %s", "Last Modified:", last_modification)
|
|
470
|
+
unless requires.empty?
|
|
471
|
+
buff << sprintf("\n %-25s %s", "Requires:", requires.join(" "))
|
|
472
|
+
end
|
|
473
|
+
if should_be_loaded?
|
|
474
|
+
buff << sprintf("\n %-25s %s", "Needs reload, last was:", loaded_time)
|
|
475
|
+
else
|
|
476
|
+
buff << sprintf("\n %-25s %s", "Loaded at:", loaded_time)
|
|
477
|
+
end
|
|
478
|
+
buff << sprintf("\n %-25s %s", "Runtime:", runtime)
|
|
479
|
+
buff
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
class BuildrNail
|
|
484
|
+
include org.apache.buildr.BuildrNail
|
|
485
|
+
Main = Util.proxy_class 'org.apache.buildr.BuildrNail$Main'
|
|
486
|
+
|
|
487
|
+
attr_reader :buildfile
|
|
488
|
+
|
|
489
|
+
def initialize
|
|
490
|
+
buildfile = Buildfile.new(Rake.application.buildfile,
|
|
491
|
+
*Rake.application.requires)
|
|
492
|
+
buildfile.loaded!
|
|
493
|
+
buildfile.runtime = JRuby.runtime
|
|
494
|
+
@buildfiles = { buildfile.path => buildfile }
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def main(nail)
|
|
498
|
+
Thread.exclusive { Thread.current.priority = 100; run(nail) }
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
private
|
|
502
|
+
def run(nail)
|
|
503
|
+
nail.assert_loopback_client
|
|
504
|
+
nail.out.println "Using #{nail.getNGServer}"
|
|
505
|
+
ctx = context_from_nail(nail)
|
|
506
|
+
|
|
507
|
+
case ctx.action
|
|
508
|
+
when :start
|
|
509
|
+
nail.out.println "Cannot start nailgun when running as client"
|
|
510
|
+
return nail.exit(0)
|
|
511
|
+
when :stop
|
|
512
|
+
puts "Stopping #{nail.getNGServer}"
|
|
513
|
+
nail.out.println "Stopping #{nail.getNGServer}"
|
|
514
|
+
return nail.getNGServer.shutdown(true)
|
|
515
|
+
when :list
|
|
516
|
+
if @buildfiles.empty?
|
|
517
|
+
nail.out.println "No defined runtimes"
|
|
518
|
+
else
|
|
519
|
+
nail.out.println "Defined runtimes:"
|
|
520
|
+
@buildfiles.each_value { |f| nail.out.println "- #{f}" }
|
|
521
|
+
end
|
|
522
|
+
return nail.exit(0)
|
|
523
|
+
when :clear
|
|
524
|
+
@buildfiles.clear
|
|
525
|
+
nail.out.println "Cleared all runtimes"
|
|
526
|
+
return nail.exit(0)
|
|
527
|
+
when :tasks
|
|
528
|
+
nail.out.println ""
|
|
529
|
+
nail.out.println Rake.application.nailgun_tasks
|
|
530
|
+
return nail.exit(0)
|
|
531
|
+
when :help
|
|
532
|
+
nail.out.println ""
|
|
533
|
+
nail.out.println Rake.application.nailgun_help
|
|
534
|
+
return nail.exit(0)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
opts = OpenStruct.new
|
|
538
|
+
|
|
539
|
+
runtime = ctx.runtime
|
|
540
|
+
#Util.set_stdio(runtime, nail)
|
|
541
|
+
runtime.object.const_get(:Buildr)::Nailgun::ContextRunner.parse_options(ctx, opts)
|
|
542
|
+
return nail.exit(0) if opts.exit
|
|
543
|
+
|
|
544
|
+
candidates = Buildr::Application::DEFAULT_BUILDFILES
|
|
545
|
+
candidates = [opts.buildfile] if opts.buildfile
|
|
546
|
+
|
|
547
|
+
path = Util.find_buildfile(ctx.pwd, candidates, opts.nosearch) ||
|
|
548
|
+
File.expand_path(candidates.first, ctx.pwd)
|
|
549
|
+
|
|
550
|
+
if ctx.action == :delete
|
|
551
|
+
nail.out.println "Deleting runtime for #{path}"
|
|
552
|
+
@buildfiles.delete(path)
|
|
553
|
+
return nail.exit(0)
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
puts "Getting buildr runtime for #{path}"
|
|
557
|
+
buildfile = @buildfiles[path] || Buildfile.new(path, *opts.requires)
|
|
558
|
+
|
|
559
|
+
save = buildfile.should_be_loaded? || ctx.action == :load
|
|
560
|
+
|
|
561
|
+
runtime = buildfile.runtime
|
|
562
|
+
|
|
563
|
+
if save || ctx.action == :once
|
|
564
|
+
ctx.argv.unshift 'nailgun:load'
|
|
565
|
+
ctx.fresh = true
|
|
566
|
+
runtime = ctx.buildr
|
|
567
|
+
if save
|
|
568
|
+
buildfile.runtime = runtime
|
|
569
|
+
buildfile.loaded!
|
|
570
|
+
@buildfiles[buildfile.path] = buildfile
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
Util.redirect_stdio(runtime, nail) do
|
|
575
|
+
runtime.object.send :puts
|
|
576
|
+
runtime.object.const_get(:Buildr)::Nailgun::ContextRunner.run(ctx)
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def context_from_nail(nail)
|
|
581
|
+
ctx = OpenStruct.new
|
|
582
|
+
ctx.pwd = nail.getWorkingDirectory
|
|
583
|
+
ctx.env = nail.env
|
|
584
|
+
ctx.argv = [nail.command] + nail.args.map(&:to_s)
|
|
585
|
+
ctx.server = nail.getNGServer
|
|
586
|
+
def ctx.runtime; @runtime ||= server.buildr_factory.runtime; end
|
|
587
|
+
def ctx.buildr; @buildr ||= server.buildr_factory.obtain; end
|
|
588
|
+
actions = {
|
|
589
|
+
:load => %w{ nailgun:load },
|
|
590
|
+
:delete => %w{ nailgun:delete },
|
|
591
|
+
:clear => %w{ nailgun:clear },
|
|
592
|
+
:list => %w{ nailgun:list },
|
|
593
|
+
:start => %w{ nailgun:boot nailgun:start },
|
|
594
|
+
:stop => %w{ nailgun:stop },
|
|
595
|
+
:once => %w{ nailgun:once },
|
|
596
|
+
:tasks => %w{ nailgun:tasks },
|
|
597
|
+
:help => %w{ nailgun:help help:nailgun },
|
|
598
|
+
}
|
|
599
|
+
action = actions.find { |k,v| k if v.any? { |t| ctx.argv.delete(t) } }
|
|
600
|
+
ctx.action = action.first if action
|
|
601
|
+
ctx
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
end # class BuildrNail
|
|
605
|
+
|
|
606
|
+
class BuildrFactory
|
|
607
|
+
|
|
608
|
+
attr_accessor :buildrs_size, :runtimes_size
|
|
609
|
+
|
|
610
|
+
def initialize(buildrs_size = 1, runtimes_size = nil)
|
|
611
|
+
runtimes_size ||= buildrs_size
|
|
612
|
+
@buildrs_size = buildrs_size < 1 ? 1 : buildrs_size
|
|
613
|
+
@runtimes_size = runtimes_size < 1 ? 1 : runtimes_size
|
|
614
|
+
|
|
615
|
+
@buildrs = [].extend(MonitorMixin)
|
|
616
|
+
@buildrs_ready = @buildrs.new_cond
|
|
617
|
+
@buildrs_needed = @buildrs.new_cond
|
|
618
|
+
|
|
619
|
+
@buildrs_creators = [].extend(MonitorMixin)
|
|
620
|
+
|
|
621
|
+
@runtimes = [].extend(MonitorMixin)
|
|
622
|
+
@runtimes_ready = @runtimes.new_cond
|
|
623
|
+
@runtimes_needed = @runtimes.new_cond
|
|
624
|
+
|
|
625
|
+
@runtimes_creators = [].extend(MonitorMixin)
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
def obtain
|
|
629
|
+
get(:buildr)
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def runtime
|
|
633
|
+
get(:runtime)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def start
|
|
637
|
+
debug "Starting Buildr runtime factory"
|
|
638
|
+
@runtime_creator = Thread.new { loop { create :runtime } }
|
|
639
|
+
@runtime_creator.priority = -2
|
|
640
|
+
@buildr_creator = Thread.new { loop { create :buildr } }
|
|
641
|
+
@buildr_creator.priority = 1
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
def stop
|
|
645
|
+
@buildr_creator.kill if @buildr_creator
|
|
646
|
+
@runtime_creator.kill if @runtime_creator
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
private
|
|
650
|
+
def debug(*msg)
|
|
651
|
+
puts *msg if Rake.application.options.trace
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
def get(thing)
|
|
655
|
+
collection = instance_variable_get("@#{thing}s")
|
|
656
|
+
needs = instance_variable_get("@#{thing}s_needed")
|
|
657
|
+
ready = instance_variable_get("@#{thing}s_ready")
|
|
658
|
+
result = nil
|
|
659
|
+
collection.synchronize do
|
|
660
|
+
if collection.empty?
|
|
661
|
+
debug "no #{thing} available, ask to create more"
|
|
662
|
+
needs.broadcast
|
|
663
|
+
debug "should be creating #{thing}"
|
|
664
|
+
ready.wait_while { collection.empty? }
|
|
665
|
+
end
|
|
666
|
+
debug "Getting my #{thing}"
|
|
667
|
+
result = collection.shift
|
|
668
|
+
debug "would need more #{thing}s"
|
|
669
|
+
needs.broadcast
|
|
670
|
+
debug "got my #{thing}: #{result.inspect}"
|
|
671
|
+
Thread.pass
|
|
672
|
+
end
|
|
673
|
+
debug "returning #{result.inspect}"
|
|
674
|
+
result
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
def create(thing, *args, &prc)
|
|
678
|
+
creator = needed(thing)
|
|
679
|
+
collection = instance_variable_get("@#{thing}s")
|
|
680
|
+
ready = instance_variable_get("@#{thing}s_ready")
|
|
681
|
+
needs = instance_variable_get("@#{thing}s_needed")
|
|
682
|
+
unless creator
|
|
683
|
+
collection.synchronize do
|
|
684
|
+
debug "awake those wanting a #{thing}"
|
|
685
|
+
ready.broadcast
|
|
686
|
+
Thread.pass
|
|
687
|
+
debug "wait until more #{thing}s are needed"
|
|
688
|
+
# needs.wait(1); return
|
|
689
|
+
needs.wait_until { creator = needed(thing) }
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
debug "About to create #{thing} # #{creator}"
|
|
693
|
+
method = "create_#{thing}"
|
|
694
|
+
creators = instance_variable_get("@#{thing}s_creators")
|
|
695
|
+
debug "registering creator for #{thing} #{creator}"
|
|
696
|
+
creators.synchronize { creators << creator }
|
|
697
|
+
result = send(method, creator, *args, &prc)
|
|
698
|
+
debug "created #{thing}[#{creator}] => #{result.inspect}"
|
|
699
|
+
creators.synchronize do
|
|
700
|
+
debug "unregistering creator for #{thing} #{creator}"
|
|
701
|
+
creators.delete(creator)
|
|
702
|
+
collection.synchronize do
|
|
703
|
+
debug "adding object on queue for #{thing} #{creator}"
|
|
704
|
+
collection << result
|
|
705
|
+
end
|
|
706
|
+
end
|
|
707
|
+
rescue => e
|
|
708
|
+
puts "#{e.backtrace.shift}: #{e.message}"
|
|
709
|
+
e.backtrace.each { |i| puts "\tfrom #{i}" }
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
def needed(thing)
|
|
713
|
+
collection = instance_variable_get("@#{thing}s")
|
|
714
|
+
creators = instance_variable_get("@#{thing}s_creators")
|
|
715
|
+
size = instance_variable_get("@#{thing}s_size")
|
|
716
|
+
collection.synchronize do
|
|
717
|
+
count = collection.size
|
|
718
|
+
if count < size
|
|
719
|
+
count += creators.synchronize { creators.size }
|
|
720
|
+
end
|
|
721
|
+
count if count < size
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
def create_runtime(creator)
|
|
726
|
+
debug "Creating runtime[#{creator}]"
|
|
727
|
+
Util.benchmark do |header|
|
|
728
|
+
runtime = org.jruby.Ruby.newInstance
|
|
729
|
+
runtime.global_variables.set('$nailgun_server', JRuby.reference($nailgun_server))
|
|
730
|
+
BUILDR_PATHS.each { |path| runtime.load_service.load_path.unshift path }
|
|
731
|
+
runtime.load_service.require 'buildr/nailgun'
|
|
732
|
+
header.replace ["Created runtime[#{creator}]", runtime]
|
|
733
|
+
runtime
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def create_buildr(creator)
|
|
738
|
+
debug "Obtaining runtime to load buildr[#{creator}] on it"
|
|
739
|
+
runtime = get(:runtime)
|
|
740
|
+
debug "Loading buildr[#{creator}] on #{runtime} ..."
|
|
741
|
+
Util.benchmark ["Loaded buildr[#{creator}] on #{runtime}"] do
|
|
742
|
+
load_service = runtime.load_service
|
|
743
|
+
load_service.require 'rubygems'
|
|
744
|
+
load_service.require 'buildr'
|
|
745
|
+
end
|
|
746
|
+
runtime
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
end # BuildrFactory
|
|
750
|
+
|
|
751
|
+
class BuildrServer < com.martiansoftware.nailgun.NGServer
|
|
752
|
+
|
|
753
|
+
attr_reader :buildr_factory
|
|
754
|
+
|
|
755
|
+
def initialize(host = 'localhost', port = 2113, buildr_factory = nil)
|
|
756
|
+
super(java.net.InetAddress.get_by_name(host), port)
|
|
757
|
+
@buildr_factory = buildr_factory
|
|
758
|
+
@host, @port = host, port
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
def runtime
|
|
762
|
+
JRuby.runtime
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
def start_server
|
|
766
|
+
self.allow_nails_by_class_name = false
|
|
767
|
+
|
|
768
|
+
BuildrNail::Main.nail = BuildrNail.new
|
|
769
|
+
self.default_nail_class = BuildrNail::Main
|
|
770
|
+
buildr_factory.start
|
|
771
|
+
|
|
772
|
+
@thread = java.lang.Thread.new(self)
|
|
773
|
+
@thread.setName(to_s)
|
|
774
|
+
@thread.start
|
|
775
|
+
|
|
776
|
+
sleep 1 while getPort == 0
|
|
777
|
+
puts "#{self} Started."
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
def stop_server
|
|
781
|
+
buildr_factory.stop
|
|
782
|
+
@thread.kill
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
def to_s
|
|
786
|
+
"BuildrServer(" <<
|
|
787
|
+
[Rake.application.version, @host, @port].join(", ") <<
|
|
788
|
+
")"
|
|
789
|
+
end
|
|
790
|
+
end # class BuildrServer
|
|
791
|
+
|
|
792
|
+
end # Nailgun boot
|
|
793
|
+
|
|
794
|
+
namespace do
|
|
795
|
+
tmp = lambda { |*files| File.join(Dir.tmpdir, "nailgun", *files) }
|
|
796
|
+
dist_zip = Buildr.download(tmp[NAME + ".zip"] => URL)
|
|
797
|
+
dist_dir = Buildr.unzip(tmp[NAME] => dist_zip)
|
|
798
|
+
|
|
799
|
+
if File.exist?(File.join(home, NAME + ".jar"))
|
|
800
|
+
ng_jar = file(File.join(home, NAME + ".jar"))
|
|
801
|
+
else
|
|
802
|
+
ng_jar = file(tmp[NAME, NAME, NAME+".jar"] => dist_dir)
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
self.artifact = Buildr.artifact(ARTIFACT_SPEC).from(ng_jar)
|
|
806
|
+
|
|
807
|
+
compiled_bin = tmp[NAME, NAME, "ng"+Config::CONFIG['EXEEXT']]
|
|
808
|
+
compiled_bin = file(compiled_bin => dist_dir.target) do |task|
|
|
809
|
+
unless task.to_s.pathmap('%x') == '.exe'
|
|
810
|
+
Dir.chdir(task.to_s.pathmap('%d')) do
|
|
811
|
+
puts "Compiling #{task.to_s}"
|
|
812
|
+
system('make', task.to_s.pathmap('%f')) or
|
|
813
|
+
fail "Nailgun binary compilation failed."
|
|
814
|
+
end
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
installed_bin = file(File.join(home,
|
|
819
|
+
compiled_bin.to_s.pathmap('%f')) => compiled_bin) do |task|
|
|
820
|
+
mkpath task.to_s.pathmap('%d'), :verbose => false
|
|
821
|
+
cp compiled_bin.to_s, task.to_s, :verbose => false
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
task :boot => artifact do |task|
|
|
825
|
+
if $nailgun_server
|
|
826
|
+
raise "Already nunning on Nailgun server: #{$nailgun_server}"
|
|
827
|
+
end
|
|
828
|
+
tasks = Rake.application.instance_eval { @top_level_tasks.dup }
|
|
829
|
+
tasks.delete_if do |t|
|
|
830
|
+
t =~ /^(buildr:initialize|(ng|nailgun):.+)$/
|
|
831
|
+
end
|
|
832
|
+
unless tasks.empty?
|
|
833
|
+
raise "Don't specify more targets when starting Nailgun server"
|
|
834
|
+
end
|
|
835
|
+
boot
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
task :start => [installed_bin, :boot] do
|
|
839
|
+
factory = BuildrFactory.new(buildr_queue_size, jruby_queue_size)
|
|
840
|
+
$nailgun_server = BuildrServer.new(server, port, factory)
|
|
841
|
+
puts "Starting #{$nailgun_server}"
|
|
842
|
+
$nailgun_server.start_server
|
|
843
|
+
|
|
844
|
+
is_win = Buildr::Util.win_os?
|
|
845
|
+
bin_path = File.expand_path(installed_bin.to_s.pathmap("%d"))
|
|
846
|
+
bin_name = installed_bin.to_s.pathmap("%f")
|
|
847
|
+
|
|
848
|
+
puts <<-NOTICE
|
|
849
|
+
|
|
850
|
+
Buildr server has been started, you may need to update your PATH
|
|
851
|
+
variable in order to execute the #{bin_name} binary.
|
|
852
|
+
|
|
853
|
+
#{ is_win ?
|
|
854
|
+
"> set NAILGUN_HOME=#{bin_path}" :
|
|
855
|
+
"$ export NAILGUN_HOME=#{bin_path}"
|
|
856
|
+
}
|
|
857
|
+
#{ is_win ?
|
|
858
|
+
"> set PATH=%NAILGUN_HOME%;%PATH%" :
|
|
859
|
+
"$ export PATH=${NAILGUN_HOME}:${PATH}"
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
Runtime for #{Rake.application.buildfile} has been cached, this
|
|
863
|
+
means you can open a terminal inside
|
|
864
|
+
|
|
865
|
+
#{Rake.application.buildfile.pathmap("%d")}
|
|
866
|
+
|
|
867
|
+
Invoke tasks by executing the #{bin_name} program, it takes the
|
|
868
|
+
same parameters you normally use for ``buildr''.
|
|
869
|
+
|
|
870
|
+
To display Nailgun related help, execute the command:
|
|
871
|
+
``#{bin_name} nailgun:help''
|
|
872
|
+
|
|
873
|
+
To get an overview of Nailgun tasks, execute the command:
|
|
874
|
+
``#{bin_name} nailgun:tasks''
|
|
875
|
+
|
|
876
|
+
NOTICE
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
task :help do
|
|
880
|
+
puts Rake.application.nailgun_help
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
task :tasks do
|
|
884
|
+
puts Rake.application.nailgun_tasks
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
end # namespace :nailgun
|
|
888
|
+
|
|
889
|
+
end # module Nailgun
|
|
890
|
+
|
|
891
|
+
end
|
|
892
|
+
|