vic-buildr 1.3.3 → 1.3.4

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.
Files changed (98) hide show
  1. data/CHANGELOG +42 -11
  2. data/Rakefile +5 -3
  3. data/_buildr +9 -31
  4. data/addon/buildr/cobertura.rb +5 -218
  5. data/addon/buildr/drb.rb +281 -0
  6. data/addon/buildr/emma.rb +5 -220
  7. data/addon/buildr/nailgun.rb +94 -686
  8. data/bin/buildr +0 -9
  9. data/buildr.gemspec +6 -6
  10. data/doc/images/favicon.png +0 -0
  11. data/doc/pages/contributing.textile +6 -4
  12. data/doc/pages/download.textile +11 -0
  13. data/doc/pages/extending.textile +2 -2
  14. data/doc/pages/getting_started.textile +4 -4
  15. data/doc/pages/index.textile +8 -11
  16. data/doc/pages/more_stuff.textile +50 -22
  17. data/doc/pages/packaging.textile +1 -1
  18. data/doc/pages/projects.textile +2 -2
  19. data/doc/pages/settings_profiles.textile +2 -2
  20. data/doc/pages/testing.textile +1 -1
  21. data/doc/pages/whats_new.textile +12 -0
  22. data/doc/site.haml +1 -0
  23. data/lib/buildr.rb +2 -4
  24. data/lib/buildr/core.rb +2 -0
  25. data/lib/buildr/core/application.rb +304 -149
  26. data/lib/buildr/core/checks.rb +3 -131
  27. data/lib/buildr/core/common.rb +0 -4
  28. data/lib/buildr/core/compile.rb +1 -7
  29. data/lib/buildr/core/environment.rb +0 -3
  30. data/lib/buildr/core/filter.rb +7 -3
  31. data/lib/buildr/core/generate.rb +50 -52
  32. data/lib/buildr/core/help.rb +2 -1
  33. data/lib/buildr/core/osx.rb +49 -0
  34. data/lib/buildr/core/progressbar.rb +1 -1
  35. data/lib/buildr/core/project.rb +7 -9
  36. data/lib/buildr/core/test.rb +4 -4
  37. data/lib/buildr/core/transports.rb +13 -30
  38. data/lib/buildr/core/util.rb +8 -3
  39. data/lib/buildr/groovy/bdd.rb +1 -0
  40. data/lib/buildr/groovy/compiler.rb +1 -1
  41. data/lib/buildr/ide/eclipse.rb +30 -20
  42. data/lib/buildr/ide/idea.rb +3 -2
  43. data/lib/buildr/ide/idea7x.rb +4 -2
  44. data/lib/buildr/java/ant.rb +1 -1
  45. data/lib/buildr/java/bdd.rb +9 -5
  46. data/lib/buildr/java/cobertura.rb +236 -0
  47. data/lib/buildr/java/commands.rb +2 -1
  48. data/lib/buildr/java/emma.rb +238 -0
  49. data/lib/buildr/java/jtestr_runner.rb.erb +2 -0
  50. data/lib/buildr/java/packaging.rb +6 -2
  51. data/lib/buildr/java/pom.rb +0 -4
  52. data/lib/buildr/java/test_result.rb +45 -15
  53. data/lib/buildr/java/tests.rb +14 -9
  54. data/lib/buildr/packaging.rb +5 -2
  55. data/lib/buildr/packaging/archive.rb +488 -0
  56. data/lib/buildr/packaging/artifact.rb +36 -7
  57. data/lib/buildr/packaging/artifact_namespace.rb +2 -2
  58. data/lib/buildr/packaging/gems.rb +3 -3
  59. data/lib/buildr/packaging/package.rb +1 -1
  60. data/lib/buildr/packaging/tar.rb +85 -3
  61. data/lib/buildr/packaging/version_requirement.rb +172 -0
  62. data/lib/buildr/packaging/zip.rb +24 -682
  63. data/lib/buildr/packaging/ziptask.rb +313 -0
  64. data/lib/buildr/scala/compiler.rb +1 -1
  65. data/lib/buildr/scala/tests.rb +2 -2
  66. data/rakelib/apache.rake +58 -8
  67. data/rakelib/package.rake +4 -1
  68. data/rakelib/rspec.rake +2 -2
  69. data/rakelib/rubyforge.rake +6 -3
  70. data/rakelib/scm.rake +1 -1
  71. data/rakelib/setup.rake +0 -5
  72. data/rakelib/stage.rake +4 -1
  73. data/spec/addon/drb_spec.rb +328 -0
  74. data/spec/core/application_spec.rb +29 -22
  75. data/spec/core/build_spec.rb +8 -0
  76. data/spec/core/checks_spec.rb +293 -311
  77. data/spec/core/common_spec.rb +8 -2
  78. data/spec/core/compile_spec.rb +17 -1
  79. data/spec/core/generate_spec.rb +33 -0
  80. data/spec/core/project_spec.rb +18 -10
  81. data/spec/core/test_spec.rb +24 -1
  82. data/spec/ide/eclipse_spec.rb +96 -28
  83. data/spec/java/ant.rb +5 -0
  84. data/spec/java/bdd_spec.rb +4 -4
  85. data/spec/{addon → java}/cobertura_spec.rb +3 -3
  86. data/spec/{addon → java}/emma_spec.rb +3 -3
  87. data/spec/java/java_spec.rb +9 -1
  88. data/spec/java/packaging_spec.rb +19 -2
  89. data/spec/{addon → java}/test_coverage_spec.rb +7 -1
  90. data/spec/java/tests_spec.rb +5 -0
  91. data/spec/packaging/archive_spec.rb +1 -1
  92. data/spec/{core → packaging}/artifact_namespace_spec.rb +2 -2
  93. data/spec/packaging/artifact_spec.rb +46 -5
  94. data/spec/packaging/packaging_spec.rb +1 -1
  95. data/spec/sandbox.rb +16 -14
  96. data/spec/spec_helpers.rb +26 -3
  97. metadata +20 -11
  98. data/lib/buildr/core/application_cli.rb +0 -139
data/CHANGELOG CHANGED
@@ -1,21 +1,50 @@
1
- 1.3.3 (Pending)
1
+ 1.3.4 (Pending)
2
+ * Added: BUILDR-159 Improved 'check' to accept both tar and tgz archives.
3
+ * Added: BUILDR-164 New 'artifacts:sources' task to download source code
4
+ for artifact jars.
5
+ * Change: Introduced new options from Rake 0.8.3: -I (libdir), -R (rakelib),
6
+ --rules, --no-search, --silent.
7
+ * Changed: Upgraded to Rubyforge 1.0.1.
8
+ * Change: BUILDR-147 Upgraded to use Rake 0.8.3.
9
+ * Change: BUILDR-166 Upgraded to use RSpec 1.1.11.
10
+ * Change: BUILDR-171 Eclipse task generates meta-data files for projects with
11
+ test source code but no main source code.
12
+ * Change: BUILDR-177 Moved cobertura and emma extensions to lib directory.
13
+ * Change: BUILDR-187 Source code attachment for Eclipse .classpath.
14
+ * Change: BUILDR-188 Source code attachment for IDEA .iml file (Marko Sibakov).
15
+ * Fixed: Removed double complete/fail messages showing up on console.
16
+ * Fixed: BUILDR-158 Nailgun is now a delegate for buildr/drb (a pure-ruby dRuby server)
17
+ * Fixed: BUILDR-170 ArtifactNamespace#method_missing has a condition that is never true.
18
+ * Fixed: BUILDR-172 Scala compiler not loaded by default.
19
+ * Fixed: BUILDR-175 Fail to find child project when calling project method inside project definition.
20
+ * Fixed: BUILDR-192 TestNG report results are overwritten (Alexis Midon).
21
+ * Fixed: BUILDR-193 TestNG uses project name for suite name (not valid file
22
+ name on Windows).
23
+ * Fixed: BUILDR-194 Buildr always adds 'Manifest-Version' to generated manifest file.
24
+ * Fixed: BUILDR-198 Filter#run always calls mkpath with :verbose.
25
+ * Fixed: BUILDR-199 ArchiveTask#needed uses 'each' with no effect (Ittay Dror).
26
+ * Fixed: BUILDR-201 Sample project is not valid (Alexis Midon).
27
+ * Fixed: BUILDR-216 Profiles documentation is wrong (Shane Witbeck).
28
+
29
+ 1.3.3 (2008-10-08)
2
30
  * Added: JtestR support. Implemented pending jtestr specs.
3
31
  * Added: Growl notifications (OS X only).
4
32
  * Added: error, info and trace methods.
5
- * Added: BUILDR-128 Emma support
6
33
  * Added: Release task support for alternative SVN repository layout
7
34
  (e.g., http://my.repo.org/trunk/foo).
35
+ * Added: BUILDR-128 Emma support
36
+ * Added: BUILDR-135. Extracted reusable replacement logic into Filter::Mapper
8
37
  * Added: BUILDR-148 It is now possible to set the version of various 3rd
9
38
  party libraries from the build.yml file. Supported libraries
10
39
  include Ant and the various test and BDD frameworks.
11
40
  * Change: Error reporting now shows 'buildr aborted!' (used to say rake),
12
41
  more of the stack trace without running --trace, and when running
13
42
  with supported terminal, error message is red.
14
- * Change: BUILDR-104 Buildr::group has :under and :version, but not :type.
15
- Now it has :type too (Lacton).
16
43
  * Change: Eclipse task updated to documented Scala plugin requirements
17
44
  (http://www.scala-lang.org/node/94)
18
45
  * Change: Buildr.application.buildfile returns a task instead of a String.
46
+ * Change: BUILDR-104 Buildr::group has :under and :version, but not :type.
47
+ Now it has :type too (Lacton).
19
48
  * Change: BUILDR-139 Incremental test run.
20
49
  * Change: BUILDR-141 Removed NEXT_VERSION from release task.
21
50
  * Change: BUILDR-148 ant-junit no longer included in root classpath, but
@@ -23,9 +52,8 @@
23
52
  * Change: BUILDR-153 To customize the SVN tag used by the release task, set
24
53
  Release.tag_name to either the tag value or a proc that takes the
25
54
  version number and return the desired tag.
26
- * Fixed: BUILDR-135. Extracted reusable replacement logic into Filter::Mapper
27
- * Fixed: BUILDR-129. Modifying a project manifest should not alter it's
28
- parent project manifest.
55
+ * Fixed: Should not display "(in `pwd`, development)" when using --quiet.
56
+ * Fixed: Release task's regexp to find either THIS_VERSION and VERSION_NUMBER.
29
57
  * Fixed: BUILDR-106 download(artifact(...)=>url) broken in certain cases
30
58
  (Lacton).
31
59
  * Fixed: BUILDR-108 Trace to explain why a compile is done (Lacton).
@@ -36,10 +64,10 @@
36
64
  * Fixed: BUILDR-112 Using a user gem repository with 'rake setup' (Lacton).
37
65
  * Fixed: BUILDR-114 Hash.from_java_properties does not behave
38
66
  like java.util.Properties (Lacton).
39
- * Fixed: BUILDR-117 Shared directory for both code and resources produces
40
- duplicate Eclipse classpath entries (Nathan Hamblen)
41
67
  * Fixed: BUILDR-116: TestTask should include the main compile target in its
42
68
  dependencies, even when using non standard directories (Lacton).
69
+ * Fixed: BUILDR-117 Shared directory for both code and resources produces
70
+ duplicate Eclipse classpath entries (Nathan Hamblen)
43
71
  * Fixed: BUILDR-119 Eclipse task does not accept test resource folders
44
72
  (Lacton)
45
73
  * Fixed: BUILDR-122: eclipse task should not check for directory existence
@@ -48,11 +76,14 @@
48
76
  include (Rhett Sutphin).
49
77
  * Fixed: BUILDR-126 Tests options are shared between unrelated projects when
50
78
  using #options instead of #using (Lacton).
51
- * Fixed: Should not display "(in `pwd`, development)" when using --quiet.
52
- * Fixed: Release task's regexp to find either THIS_VERSION and VERSION_NUMBER.
79
+ * Fixed: BUILDR-129. Modifying a project manifest should not alter it's
80
+ parent project manifest.
81
+ * Fixed: BUILDR-137 JRuby 1.1.3 and Buildr 1.3.2 don't appear to work
82
+ (on Windows).
53
83
  * Fixed: BUILDR-138 ScalaTest premature use of Buildr::Repositories
54
84
  inconsistent with customizing locations.
55
85
  * Fixed: BUILDR-152 Project.task fails when task name starts with a colon.
86
+ * Fixed: BUILDR-157 Tasks library not loaded from a submodule.
56
87
  * Docs: BUILDR-111 Troubleshoot tip when Buildr's bin directory shows up in
57
88
  RUBYLIB (Geoffrey Ruscoe).
58
89
 
data/Rakefile CHANGED
@@ -28,7 +28,9 @@ end
28
28
  desc 'Compile Java libraries used by Buildr'
29
29
  task 'compile' do
30
30
  puts 'Compiling Java libraries ...'
31
- sh File.expand_path('_buildr'), '--buildfile=buildr.buildfile', 'compile'
31
+ args = File.expand_path('_buildr'), '--buildfile=buildr.buildfile', 'compile'
32
+ args << '--trace' if Rake.application.options.trace
33
+ sh *args
32
34
  puts 'OK'
33
35
  end
34
36
  file Rake::GemPackageTask.new(spec).package_dir=>'compile'
@@ -58,5 +60,5 @@ task 'stage:check' do
58
60
  # Dependency check for the other platform, i.e. if making a release with Ruby,
59
61
  # run dependency checks with JRuby. (Also, good opportunity to upgrade other
60
62
  # platform's dependencies)
61
- sh RUBY_PLATFORM =~ /java/ ? 'ruby' : 'jruby', '-S', 'rake', 'setup dependency'
62
- end
63
+ sh RUBY_PLATFORM =~ /java/ ? 'ruby' : 'jruby -S rake setup dependency'
64
+ end
data/_buildr CHANGED
@@ -14,37 +14,15 @@
14
14
  # License for the specific language governing permissions and limitations under
15
15
  # the License.
16
16
 
17
- # Run buildr from source, specifically for testing stuff without doing a rake install.
18
- # The _BUILDR_RB environment variable can be used to set the path to the ruby/jruby executable.
19
- # For example to use jruby:
20
- # export _BUILDR_RB=/path/to/jruby
21
-
22
- buildr_root = File.dirname(__FILE__)
23
- buildr_ruby = ENV['_BUILDR_RB'] || 'ruby'
24
17
 
25
- cmd = [
26
- buildr_ruby,
27
- "-I"+File.join(buildr_root, 'lib'),
28
- "-I"+File.join(buildr_root, 'addon'),
29
- ]
30
-
31
- cmd.push '-e', %q{
32
- start = Time.now
33
- require 'rubygems'
34
- gem 'rake', '0.8.1' # Required since Buildr won't run with 0.8.2 for now.
35
- require 'buildr'
36
- Buildr.application.run
37
- if verbose
38
- elapsed = Time.now - start
39
- real = []
40
- real << ("%ih" % (elapsed / 3600)) if elapsed >= 3600
41
- real << ("%im" % ((elapsed / 60) % 60)) if elapsed >= 60
42
- real << ("%.3fs" % (elapsed % 60))
43
- puts $terminal.color("Completed in #{real.join}", :green)
44
- end
45
- }
18
+ # Run buildr from source, specifically for testing stuff without doing a rake install.
46
19
 
47
- cmd.push '--' # The following args are for Buildr
48
- cmd.push *ARGV
49
- exec *cmd
20
+ require 'rubygems'
21
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') << File.join(File.dirname(__FILE__), 'addon')
22
+ spec = Gem::Specification.load(File.join(File.dirname(__FILE__), 'buildr.gemspec'))
23
+ spec.dependencies.each do |dep|
24
+ gem dep.name, dep.version_requirements.to_s
25
+ end
50
26
 
27
+ require 'buildr'
28
+ Buildr.application.run
@@ -14,222 +14,9 @@
14
14
  # the License.
15
15
 
16
16
 
17
- require 'buildr/java'
18
-
19
-
20
- module Buildr
21
-
22
- # Provides the <code>cobertura:html</code> and <code>cobertura:xml</code> tasks.
23
- # Require explicitly using <code>require "buildr/cobertura"</code>.
24
- #
25
- # You can generate cobertura reports for a single project
26
- # using the project name as prefix:
27
- #
28
- # project_name:cobertura:html
29
- #
30
- # You can also specify which classes to include/exclude from instrumentation by
31
- # passing a class name regexp to the <code>cobertura.include</code> or
32
- # <code>cobertura.exclude</code> methods.
33
- #
34
- # define 'someModule' do
35
- # cobertura.include 'some.package.*'
36
- # cobertura.include /some.(foo|bar).*/
37
- # cobertura.exclude 'some.foo.util.SimpleUtil'
38
- # cobertura.exclude /*.Const(ants)?/i
39
- # end
40
- module Cobertura
41
-
42
- class << self
43
-
44
- REQUIRES = ["net.sourceforge.cobertura:cobertura:jar:1.9", "log4j:log4j:jar:1.2.9",
45
- "asm:asm:jar:2.2.1", "asm:asm-tree:jar:2.2.1", "oro:oro:jar:2.0.8"] unless const_defined?('REQUIRES')
46
-
47
- def requires()
48
- @requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s)
49
- end
50
-
51
- def report_to(file = nil)
52
- File.expand_path(File.join(*["reports/cobertura", file.to_s].compact))
53
- end
54
-
55
- def data_file()
56
- File.expand_path("reports/cobertura.ser")
57
- end
58
-
59
- end
60
-
61
- class CoberturaConfig # :nodoc:
62
-
63
- def initialize(project)
64
- @project = project
65
- end
66
-
67
- attr_reader :project
68
- private :project
69
-
70
- attr_writer :data_file, :instrumented_dir, :report_dir
71
-
72
- def data_file
73
- @data_file ||= project.path_to(:reports, 'cobertura.ser')
74
- end
75
-
76
- def instrumented_dir
77
- @instrumented_dir ||= project.path_to(:target, :instrumented, :classes)
78
- end
79
-
80
- def report_dir
81
- @report_dir ||= project.path_to(:reports, :cobertura)
82
- end
83
-
84
- def report_to(file = nil)
85
- File.expand_path(File.join(*[report_dir, file.to_s].compact))
86
- end
87
-
88
- # :call-seq:
89
- # project.cobertura.include(*classPatterns)
90
- #
91
- def include(*classPatterns)
92
- includes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
93
- self
94
- end
95
-
96
- def includes
97
- @includeClasses ||= []
98
- end
99
-
100
- # :call-seq:
101
- # project.cobertura.exclude(*classPatterns)
102
- #
103
- def exclude(*classPatterns)
104
- excludes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
105
- self
106
- end
107
-
108
- def excludes
109
- @excludeClasses ||= []
110
- end
111
-
112
- def sources
113
- project.compile.sources
114
- end
115
- end
116
-
117
- module CoberturaExtension # :nodoc:
118
- include Buildr::Extension
119
-
120
- def cobertura
121
- @cobertura_config ||= CoberturaConfig.new(self)
122
- end
123
-
124
- after_define do |project|
125
- cobertura = project.cobertura
126
-
127
- namespace 'cobertura' do
128
- unless project.compile.target.nil?
129
- # Instrumented bytecode goes in a different directory. This task creates before running the test
130
- # cases and monitors for changes in the generate bytecode.
131
- instrumented = project.file(cobertura.instrumented_dir => project.compile.target) do |task|
132
- mkdir_p task.to_s, :verbose => false
133
- unless project.compile.sources.empty?
134
- info "Instrumenting classes with cobertura data file #{cobertura.data_file}"
135
- Buildr.ant "cobertura" do |ant|
136
- ant.taskdef :classpath=>Cobertura.requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
137
- ant.send "cobertura-instrument", :todir=>task.to_s, :datafile=>cobertura.data_file do
138
- includes, excludes = cobertura.includes, cobertura.excludes
139
-
140
- classes_dir = project.compile.target.to_s
141
- if includes.empty? && excludes.empty?
142
- ant.fileset :dir => classes_dir do
143
- ant.include :name => "**/*.class"
144
- end
145
- else
146
- includes = [//] if includes.empty?
147
- Dir.glob(File.join(classes_dir, "**/*.class")) do |cls|
148
- cls_name = cls.gsub(/#{classes_dir}\/?|\.class$/, '').gsub('/', '.')
149
- if includes.any? { |p| p === cls_name } && !excludes.any? { |p| p === cls_name }
150
- ant.fileset :file => cls
151
- end
152
- end
153
- end
154
- end
155
- end
156
- end
157
- touch task.to_s, :verbose=>false
158
- end
159
-
160
- task 'instrument' => instrumented
161
-
162
- # We now have two target directories with bytecode. It would make sense to remove compile.target
163
- # and add instrumented instead, but apparently Cobertura only creates some of the classes, so
164
- # we need both directories and instrumented must come first.
165
- project.test.dependencies.unshift cobertura.instrumented_dir
166
- project.test.with Cobertura.requires
167
- project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = cobertura.data_file
168
-
169
- [:xml, :html].each do |format|
170
- task format => ['instrument', 'test'] do
171
- info "Creating test coverage reports in #{cobertura.report_to(format)}"
172
- Buildr.ant "cobertura" do |ant|
173
- ant.taskdef :classpath=>Cobertura.requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
174
- ant.send "cobertura-report", :format=>format,
175
- :destdir=>cobertura.report_to(format), :datafile=>cobertura.data_file do
176
- cobertura.sources.flatten.each do |src|
177
- ant.fileset(:dir=>src.to_s) if File.exist?(src.to_s)
178
- end
179
- end
180
- end
181
- end
182
- end
183
- end
184
-
185
- end
186
-
187
- project.clean do
188
- rm_rf [cobertura.report_to, cobertura.data_file, cobertura.instrumented_dir], :verbose=>false
189
- end
190
-
191
- end
192
-
193
- end
194
-
195
- class Buildr::Project
196
- include CoberturaExtension
197
- end
198
-
199
- namespace "cobertura" do
200
-
201
- task "instrument" do
202
- Buildr.projects.each do |project|
203
- project.cobertura.data_file = data_file
204
- project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = data_file
205
- project.task('cobertura:instrument').invoke
206
- end
207
- end
208
-
209
- [:xml, :html].each do |format|
210
- report_target = report_to(format)
211
- desc "Run the test cases and produce code coverage reports in #{report_target}"
212
- task format => ["instrument", "test"] do
213
- info "Creating test coverage reports in #{report_target}"
214
- Buildr.ant "cobertura" do |ant|
215
- ant.taskdef :classpath=>requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
216
- ant.send "cobertura-report", :destdir=>report_target, :format=>format, :datafile=>data_file do
217
- Buildr.projects.map(&:cobertura).map(&:sources).flatten.each do |src|
218
- ant.fileset :dir=>src.to_s if File.exist?(src.to_s)
219
- end
220
- end
221
- end
222
- end
223
- end
224
-
225
- task "clean" do
226
- rm_rf [report_to, data_file], :verbose=>false
227
- end
228
- end
229
-
230
- task "clean" do
231
- task("cobertura:clean").invoke if Dir.pwd == Rake.application.original_dir
232
- end
233
-
234
- end
17
+ if Buildr::VERSION < '1.5'
18
+ Buildr.application.deprecated "'buildr/cobertura', use 'buildr/java/cobertura' instead"
19
+ require 'buildr/java/cobertura'
20
+ else
21
+ raise "#{__FILE__} should be removed since its use is deprecated since version 1.3.4"
235
22
  end
@@ -0,0 +1,281 @@
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 'delegate'
18
+ require 'drb/drb'
19
+
20
+
21
+ module Buildr
22
+
23
+ # This addon allows you start a DRb server hosting a buildfile, so that
24
+ # you can later invoke tasks on it without having to load
25
+ # the complete buildr runtime again.
26
+ #
27
+ # Usage:
28
+ #
29
+ # buildr -r buildr/drb drb:start
30
+ #
31
+ # Once the server has been started you can invoke tasks using a simple script:
32
+ #
33
+ # #!/usr/bin/env ruby
34
+ # require 'rubygems'
35
+ # require 'buildr/drb'
36
+ # Buildr::DRbApplication.run
37
+ #
38
+ # Save this script as 'dbuildr', make it executable and use it to invoke tasks.
39
+ #
40
+ # dbuildr clean compile
41
+ #
42
+ # The dbuildr script will run as the server if there isn't one already running.
43
+ # Subsequent calls to dbuildr will act as the client and invoke the tasks you
44
+ # provide in the server.
45
+ # If the buildfile has been modified it will be reloaded on the BuildrServer.
46
+ #
47
+ # JRuby users can use a nailgun client to invoke tasks as fast as possible
48
+ # without having to incur JVM startup time.
49
+ # See the documentation for buildr/nailgun.
50
+ module DRbApplication
51
+
52
+ port = ENV['DRB_PORT'] || 2111
53
+ PORT = port.to_i
54
+
55
+ class SavedTask #:nodoc:
56
+
57
+ def initialize(original)
58
+ @original = original.clone
59
+ @prerequisites = original.prerequisites.clone if original.respond_to?(:prerequisites)
60
+ @actions = original.actions.clone if original.respond_to?(:actions)
61
+ end
62
+
63
+ def name
64
+ @original.name
65
+ end
66
+
67
+ def actions
68
+ @actions ||= []
69
+ end
70
+
71
+ def prerequisites
72
+ @prerequisites ||= []
73
+ end
74
+
75
+ def define!
76
+ @original.class.send(:define_task, @original.name => prerequisites).tap do |task|
77
+ task.comment = @original.comment
78
+ actions.each { |action| task.enhance &action }
79
+ end
80
+ end
81
+ end # SavedTask
82
+
83
+ class Snapshot #:nodoc:
84
+
85
+ attr_accessor :projects, :tasks, :rules, :layout, :options
86
+
87
+ # save the tasks,rules,layout defined by buildr
88
+ def initialize
89
+ @rules = Buildr.application.instance_eval { @rules || [] }.clone
90
+ @options = Buildr.application.options.clone
91
+ @options.rakelib ||= ['tasks']
92
+ @layout = Layout.default.clone
93
+ @projects = Project.instance_eval { @projects || {} }.clone
94
+ @tasks = Buildr.application.tasks.inject({}) do |hash, original|
95
+ unless projects.key? original.name # don't save project definitions
96
+ hash.update original.name => SavedTask.new(original)
97
+ end
98
+ hash
99
+ end
100
+ end
101
+
102
+ end # Snapshot
103
+
104
+ class << self
105
+
106
+ attr_accessor :original, :snapshot
107
+
108
+ def run
109
+ begin
110
+ client = connect
111
+ rescue DRb::DRbConnError => e
112
+ run_server!
113
+ else
114
+ run_client(client)
115
+ end
116
+ end
117
+
118
+ def client_uri
119
+ "druby://:#{PORT + 1}"
120
+ end
121
+
122
+ def remote_run(cfg)
123
+ with_config(cfg) { Buildr.application.remote_run(self) }
124
+ rescue => e
125
+ cfg[:err].puts e.message
126
+ e.backtrace.each { |b| cfg[:err].puts "\tfrom #{b}" }
127
+ raise e
128
+ end
129
+
130
+ def save_snapshot(app)
131
+ if app.instance_eval { @rakefile }
132
+ @snapshot = self::Snapshot.new
133
+ app.buildfile_reloaded!
134
+ end
135
+ end
136
+
137
+ private
138
+
139
+ def server_uri
140
+ "druby://:#{PORT}"
141
+ end
142
+
143
+ def connect
144
+ buildr = DRbObject.new(nil, server_uri)
145
+ uri = buildr.client_uri # obtain our uri from the server
146
+ DRb.start_service(uri)
147
+ buildr
148
+ end
149
+
150
+ def run_client(client)
151
+ client.remote_run :dir => Dir.pwd, :argv => ARGV,
152
+ :in => $stdin, :out => $stdout, :err => $stderr
153
+ end
154
+
155
+ def setup
156
+ unless original
157
+ # Create the stdio delegator that can be cached (eg by fileutils)
158
+ delegate_stdio
159
+
160
+ # Lazily load buildr the first time it's needed
161
+ require 'buildr'
162
+
163
+ # Save the tasks,rules,layout defined by buildr
164
+ # before loading any project
165
+ @original = self::Snapshot.new
166
+
167
+ Buildr.application.extend self
168
+ save_snapshot(Buildr.application)
169
+ end
170
+ end
171
+
172
+ def run_server
173
+ setup
174
+ DRb.start_service(server_uri, self)
175
+ puts "#{self} waiting on #{server_uri}"
176
+ end
177
+
178
+ def run_server!
179
+ setup
180
+ if RUBY_PLATFORM[/java/]
181
+ require 'buildr/nailgun'
182
+ Buildr.application['nailgun:drb'].invoke
183
+ else
184
+ run_server
185
+ DRb.thread.join
186
+ end
187
+ end
188
+
189
+ def delegate_stdio
190
+ $stdin = SimpleDelegator.new($stdin)
191
+ $stdout = SimpleDelegator.new($stdout)
192
+ $stderr = SimpleDelegator.new($stderr)
193
+ end
194
+
195
+ def with_config(remote)
196
+ @invoked = true
197
+ set = lambda do |env|
198
+ ARGV.replace env[:argv]
199
+ $stdin.__setobj__(env[:in])
200
+ $stdout.__setobj__(env[:out])
201
+ $stderr.__setobj__(env[:err])
202
+ Buildr.application.instance_variable_set :@original_dir, env[:dir]
203
+ end
204
+ original = {
205
+ :dir => Buildr.application.instance_variable_get(:@original_dir),
206
+ :argv => ARGV,
207
+ :in => $stdin.__getobj__,
208
+ :out => $stdout.__getobj__,
209
+ :err => $stderr.__getobj__
210
+ }
211
+ begin
212
+ set[remote]
213
+ yield
214
+ ensure
215
+ set[original]
216
+ end
217
+ end
218
+
219
+ end # class << DRbApplication
220
+
221
+ def remote_run(server)
222
+ @options = server.original.options.clone
223
+ init 'Distributed Buildr'
224
+ if @rakefile
225
+ if buildfile_needs_reload?
226
+ reload_buildfile(server, server.original)
227
+ else
228
+ clear_invoked_tasks(server.snapshot || server.original)
229
+ end
230
+ else
231
+ reload_buildfile(server, server.original)
232
+ end
233
+ top_level
234
+ end
235
+
236
+ def buildfile_reloaded!
237
+ @last_loaded = buildfile.timestamp if @rakefile
238
+ end
239
+
240
+ private
241
+
242
+ def buildfile_needs_reload?
243
+ !@last_loaded || @last_loaded < buildfile.timestamp
244
+ end
245
+
246
+ def reload_buildfile(server, snapshot)
247
+ clear_for_reload(snapshot)
248
+ load_buildfile
249
+ server.save_snapshot(self)
250
+ end
251
+
252
+ def clear_for_reload(snapshot)
253
+ Project.clear
254
+ @tasks = {}
255
+ @rules = snapshot.rules.clone
256
+ snapshot.tasks.each_pair { |name, saved| saved.define! }
257
+ Layout.default = snapshot.layout.clone
258
+ end
259
+
260
+ def clear_invoked_tasks(snapshot)
261
+ @rules = snapshot.rules.clone
262
+ (@tasks.keys - snapshot.projects.keys).each do |name|
263
+ if saved = snapshot.tasks[name]
264
+ # reenable this task, restoring its actions/prereqs
265
+ task = @tasks[name]
266
+ task.reenable
267
+ task.prerequisites.replace saved.prerequisites.clone
268
+ task.actions.replace saved.actions.clone
269
+ else
270
+ # tasks generated at runtime, drop it
271
+ @tasks.delete(name)
272
+ end
273
+ end
274
+ end
275
+
276
+ task('drb:start') { run_server! } if Buildr.respond_to?(:application)
277
+
278
+ end # DRbApplication
279
+
280
+ end
281
+