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/addon/buildr/emma.rb CHANGED
@@ -14,224 +14,9 @@
14
14
  # the License.
15
15
 
16
16
 
17
- require 'buildr/java'
18
-
19
-
20
- module Buildr
21
-
22
- # Provides the <code>emma:html</code> and <code>emma:xml</code> tasks.
23
- # Require explicitly using <code>require "buildr/emma"</code>.
24
- #
25
- # You can generate emma reports for a single project
26
- # using the project name as prefix:
27
- #
28
- # project_name:emma:html
29
- #
30
- # You can also specify which classes to include/exclude from instrumentation by
31
- # passing a class name regexp to the <code>emma.include</code> or
32
- # <code>emma.exclude</code> methods.
33
- #
34
- # define 'someModule' do
35
- # emma.include 'some.package.*'
36
- # emma.exclude 'some.foo.util.SimpleUtil'
37
- # end
38
- module Emma
39
-
40
- class << self
41
-
42
- REQUIRES = ['emma:emma_ant:jar:2.0.5312', 'emma:emma:jar:2.0.5312'] unless const_defined?('REQUIRES')
43
-
44
- def requires()
45
- @requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s)
46
- end
47
-
48
- def report_to format=nil
49
- File.expand_path('reports/emma')
50
- end
51
-
52
- def data_file()
53
- File.join(report_to, 'coverage.es')
54
- end
55
-
56
- def ant
57
- Buildr.ant 'emma' do |ant|
58
- ant.taskdef :classpath=>requires.join(File::PATH_SEPARATOR), :resource=>'emma_ant.properties'
59
- ant.emma :verbosity=>(Buildr.application.options.trace ? 'verbose' : 'warning') do
60
- yield ant
61
- end
62
- end
63
- end
64
- end
65
-
66
- class EmmaConfig # :nodoc:
67
-
68
- def initialize(project)
69
- @project = project
70
- end
71
-
72
- attr_reader :project
73
- private :project
74
-
75
- attr_writer :metadata_file, :coverage_file, :instrumented_dir, :report_dir
76
-
77
- def coverage_file
78
- @coverage_file ||= File.join(report_dir, 'coverage.ec')
79
- end
80
-
81
- def metadata_file
82
- @metadata_file ||= File.join(report_dir, 'coverage.em')
83
- end
84
-
85
- def instrumented_dir
86
- @instrumented_dir ||= project.path_to(:target, :instrumented, :classes)
87
- end
88
-
89
- def report_dir
90
- @report_dir ||= project.path_to(:reports, :emma)
91
- end
92
-
93
- def report_to format
94
- report_dir
95
- end
96
-
97
- # :call-seq:
98
- # project.emma.include(*classPatterns)
99
- #
100
- def include(*classPatterns)
101
- includes.push(*classPatterns)
102
- self
103
- end
104
-
105
- def includes
106
- @includeClasses ||= []
107
- end
108
-
109
- # :call-seq:
110
- # project.emma.exclude(*classPatterns)
111
- #
112
- def exclude(*classPatterns)
113
- excludes.push(*classPatterns)
114
- self
115
- end
116
-
117
- def excludes
118
- @excludeClasses ||= []
119
- end
120
-
121
- def sources
122
- project.compile.sources
123
- end
124
- end
125
-
126
- module EmmaExtension # :nodoc:
127
- include Buildr::Extension
128
-
129
- def emma
130
- @emma_config ||= EmmaConfig.new(self)
131
- end
132
-
133
- after_define do |project|
134
- emma = project.emma
135
-
136
- namespace 'emma' do
137
- unless project.compile.target.nil?
138
- # Instrumented bytecode goes in a different directory. This task creates before running the test
139
- # cases and monitors for changes in the generate bytecode.
140
- instrumented = project.file(emma.instrumented_dir => project.compile.target) do |task|
141
- unless project.compile.sources.empty?
142
- info "Instrumenting classes with emma metadata file #{emma.metadata_file}"
143
- Emma.ant do |ant|
144
- ant.instr :instrpath=>project.compile.target.to_s, :destdir=>task.to_s, :metadatafile=>emma.metadata_file do
145
- ant.filter :includes=>emma.includes.join(', ') unless emma.includes.empty?
146
- ant.filter :excludes=>emma.excludes.join(', ') unless emma.excludes.empty?
147
- end
148
- end
149
- touch task.to_s, :verbose=>false
150
- end
151
- end
152
-
153
- task 'instrument' => instrumented
154
-
155
- # We now have two target directories with bytecode.
156
- project.test.dependencies.unshift emma.instrumented_dir
157
- project.test.with Emma.requires
158
- project.test.options[:properties]["emma.coverage.out.file"] = emma.coverage_file
159
-
160
- [:xml, :html].each do |format|
161
- task format => ['instrument', 'test'] do
162
- missing_required_files = [emma.metadata_file, emma.coverage_file].reject { |f| File.exist?(f) }
163
- if missing_required_files.empty?
164
- info "Creating test coverage reports in #{emma.report_dir}"
165
- mkdir_p emma.report_dir, :verbose=>false
166
- Emma.ant do |ant|
167
- ant.report do
168
- ant.infileset :file=>emma.metadata_file
169
- ant.infileset :file=>emma.coverage_file
170
- ant.send format, :outfile=>File.join(emma.report_to(format),"coverage.#{format}")
171
- ant.sourcepath do
172
- emma.sources.flatten.each do |src|
173
- ant.dirset(:dir=>src.to_s) if File.exist?(src.to_s)
174
- end
175
- end
176
- end
177
- end
178
- else
179
- info "No test coverage report for #{project}. Missing: #{missing_required_files.join(', ')}"
180
- end
181
- end
182
- end
183
- end
184
- end
185
-
186
- project.clean do
187
- rm_rf [emma.report_dir, emma.coverage_file, emma.metadata_file, emma.instrumented_dir], :verbose=>false
188
- end
189
-
190
- end
191
-
192
- end
193
-
194
- class Buildr::Project
195
- include EmmaExtension
196
- end
197
-
198
- namespace "emma" do
199
-
200
- Project.local_task('instrument') { |name| "Instrumenting #{name}" }
201
-
202
- [:xml, :html].each do |format|
203
- desc "Run the test cases and produce code coverage reports in #{format}"
204
- task format => ['instrument', 'test'] do
205
- info "Creating test coverage reports in #{format}"
206
- mkdir_p report_to(format), :verbose=>false
207
- Emma.ant do |ant|
208
- ant.merge :outfile=>data_file do
209
- Buildr.projects.each do |project|
210
- ant.fileset :file=>project.emma.metadata_file
211
- ant.fileset :file=>project.emma.coverage_file
212
- end
213
- end
214
- ant.report do
215
- ant.infileset :file=>data_file
216
- ant.send format, :outfile=>File.join(report_to(format), "coverage.#{format}")
217
- ant.sourcepath do
218
- Buildr.projects.map(&:emma).map(&:sources).flatten.map(&:to_s).each do |src|
219
- ant.dirset :dir=>src if File.exist?(src)
220
- end
221
- end
222
- end
223
- end
224
- end
225
- end
226
-
227
- task :clean do
228
- rm_rf [report_to, data_file], :verbose=>false
229
- end
230
- end
231
-
232
- task :clean do
233
- task('emma:clean').invoke if Dir.pwd == Rake.application.original_dir
234
- end
235
-
236
- end
17
+ if Buildr::VERSION < '1.5'
18
+ Buildr.application.deprecated "'buildr/emma', use 'buildr/java/emma' instead"
19
+ require 'buildr/java/emma'
20
+ else
21
+ raise "#{__FILE__} should be removed since its use is deprecated since version 1.3.4"
237
22
  end
@@ -13,103 +13,39 @@
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
15
 
16
- require 'benchmark'
16
+
17
17
  require 'jruby'
18
- require 'monitor'
19
- require 'ostruct'
20
18
  require 'rbconfig'
21
- require 'thread'
22
- require 'buildr/core/application_cli'
19
+ require 'tmpdir'
20
+ require 'buildr/drb'
23
21
 
24
- module Buildr #:nodoc:
25
22
 
23
+ module Buildr
24
+
25
+ # This addon is provided for fast interaction with a DRb BuildrServer (buildr/drb).
26
+ #
27
+ # This module delegates task invocation to the BuildrServer, it only implements
28
+ # nailgun required logic (server/client).
29
+ #
30
+ # Usage:
31
+ #
32
+ # buildr -r buildr/nailgun nailgun:start
33
+ #
34
+ # Once the server has been started you can invoke tasks using the nailgun client
35
+ # installed on $JRUBY_HOME/tool/nailgun. It's recommended to add this path to
36
+ # your PATH environment variable, so that the ng command is available at any dir.
37
+ #
38
+ # ng build # invoke the build task
39
+ #
26
40
  module Nailgun
27
-
28
41
  extend self
29
-
30
- attr_reader :ng
31
- @ng ||= OpenStruct.new
32
42
 
33
43
  VERSION = '0.7.1'
34
44
  NAME = "nailgun-#{VERSION}"
35
45
  URL = "http://downloads.sourceforge.net/nailgun/#{NAME}.zip"
36
46
  ARTIFACT_SPEC = "com.martiansoftware:nailgun:jar:#{VERSION}"
37
-
38
- # Paths used to initialize a buildr runtime
39
- BUILDR_PATHS = [File.expand_path('../', File.dirname(__FILE__)),
40
- File.expand_path('../../lib', File.dirname(__FILE__))]
41
-
42
- HELP = <<-HELP.strip.gsub(/ *\n +/, "\n ")
43
- NailGun is a client, protocol, and server for running Java
44
- programs from the command line without incurring the JVM
45
- startup overhead. Nailgun integration is currently available
46
- only when running Buildr with JRuby.
47
-
48
- Buildr provides a custom nailgun server, allowing you to
49
- start a single JVM and let buildr create a queue of runtimes.
50
- These JRuby runtimes can be cached (indexed by buildfile path)
51
- and are automatically reloaded when the buildfile has been modified.
52
- Runtime caching allows you to execute tasks without
53
- spending time creating the buildr environment. Some nailgun
54
- tasks have been provided to manage the cached runtimes.
55
-
56
- To start the buildr server execute the following task:
57
-
58
- nailgun:start
59
-
60
- Server output will display a message when it becomes ready, you
61
- will also see messages when the JRuby runtimes are being created,
62
- or when a new buildr environment is being loaded on them.
63
- After the runtime queues have been populated, you can start calling
64
- buildr as you normally do, by invoking the $NAILGUN_HOME/ng binary:
65
-
66
- # on another terminal, change directory to a project.
67
- # if this project is the same nailgun:start was invoked on, it's
68
- # runtime has been cached, so no loading is performed unless
69
- # the buildfile has been modified. otherwise the buildfile
70
- # will be loaded on a previously loaded fresh-buildr runtime
71
- # and it will be cached.
72
- cd /some/buildr/project
73
- ng nailgun:help # display nailgun help
74
- ng nailgun:tasks # display overview of ng tasks
75
- ng clean compile # just invoke those two tasks
76
-
77
- Configuration and Environment Variables.
78
-
79
- Before starting the server, buildr will check if you have
80
- nailgun already installed by seeking the nailgun jar under
81
-
82
- $NAILGUN_HOME
83
-
84
- You can override this environment variable to tell buildr where
85
- to find or where to install nailgun. If missing, NAILGUN_HOME
86
- defaults to the $JRUBY_HOME/tool/nailgun directory.
87
-
88
- Buildr will also check that the nailgun client binary (ng.exe for
89
- Windows systems, ng otherwise) is installed on NAILGUN_HOME.
90
- If no binary is found, buildr will download nailgun and
91
- compile+install it.
92
-
93
- The buildr server binds itself to localhost, port 2113. You can
94
- override this when starting the nailgun server:
95
-
96
- buildr nailgun:start[4444,127.0.0.1]
97
-
98
- If you provided custom host/port settings you need
99
- to tell the nailgun client where to connect:
100
-
101
- ng --nailgun-server 127.0.0.1 --nailgun-port 4444 nailgun:tasks
102
-
103
- The buildr server starts a RuntimeFactory responsible for providing
104
- a pool of preloaded Buildr runtimes ready for task execution.
105
- You can provide a third argument to the nailgun:start task, to set
106
- the buildr queue size. You may want to increase this value if you
107
- need to load many buildfiles on the same server.
108
-
109
- Execute nailgun:tasks get an overview of available nailgun tasks.
110
- HELP
111
-
112
- private
47
+ PORT = DRbApplication::PORT + 2
48
+ ADDON_BIN = File.dirname(__FILE__)
113
49
 
114
50
  # Returns the path to JRUBY_HOME.
115
51
  def jruby_home
@@ -125,152 +61,9 @@ module Buildr #:nodoc:
125
61
  File.join(Dir.tmpdir, 'nailgun', *paths)
126
62
  end
127
63
 
128
- file_tasks = lambda do
129
-
130
- dist_zip = Buildr.download(tmp_path(NAME + '.zip') => URL)
131
- dist_dir = Buildr.unzip(tmp_path(NAME) => dist_zip)
132
-
133
- nailgun_jar = file(tmp_path(NAME, NAME, NAME + '.jar'))
134
- ng.artifact = Buildr.artifact(ARTIFACT_SPEC).from(nailgun_jar)
135
- unless File.exist?(nailgun_jar.to_s)
136
- nailgun_jar.enhance [dist_dir]
137
- end
138
-
139
- compiled_bin = file(tmp_path(NAME, NAME, 'ng' + Config::CONFIG['EXEEXT']) => dist_dir.target) do |task|
140
- unless task.to_s.pathmap('%x') == '.exe'
141
- Dir.chdir(task.to_s.pathmap('%d')) do
142
- info "Compiling #{task.to_s}"
143
- system('make', task.to_s.pathmap('%f')) or
144
- fail "Nailgun binary compilation failed."
145
- end
146
- end
147
- end
148
-
149
- ng.installed_bin = file(File.expand_path(compiled_bin.to_s.pathmap('%f'), nailgun_home) => compiled_bin) do |task|
150
- mkpath task.to_s.pathmap('%d'), :verbose => false
151
- cp compiled_bin.to_s, task.to_s, :verbose => false
152
- end
153
-
154
- end # file_tasks
155
-
156
- server_tasks = lambda do
157
-
158
- desc 'Start the nailgun server'
159
- task('start', :port, :iface, :queue_size) do |task, args|
160
-
161
- [ng.installed_bin, ng.artifact].map(&:invoke)
162
-
163
- iface = args[:iface].to_s.empty? ? '127.0.0.1' : args[:iface]
164
- port = args[:port].to_s.empty? ? 2113 : args[:port].to_i
165
- queue_size = args[:queue_size].to_s.empty? ? 3 : args[:queue_size].to_i
166
-
167
- fail "Already running on Nailgun server: #{ng.server || ng.nail}" if ng.server || ng.client
168
-
169
- info 'Booting Buildr nailgun server...'
170
- top_level = Buildr.application.instance_eval { @top_level_tasks.dup }
171
- top_level.delete_if { |t| t[/nailgun/] }
172
- unless top_level.empty?
173
- raise 'Don\'t specify more targets when starting Nailgun server: #{top_level}'
174
- end
175
- ng.server_setup.call
176
-
177
- factory = RuntimeFactory.new(queue_size, queue_size)
178
- ng.server = NGServer.new(iface, port, factory)
179
-
180
- ng.server.start
181
- end
182
-
183
- desc 'Show nailgun help'
184
- task('help') do
185
- info HELP
186
- exit(0)
187
- end
188
-
189
- desc 'List nailgun tasks'
190
- task('tasks') do
191
- task_hash = Buildr.application.instance_variable_get(:@tasks)
192
- tasks = task_hash.keys.select { |k| k =~ /^nailgun:/ }
193
- width = [tasks.map { |t| task_hash[t].name_with_args.size }, 20].flatten.max
194
- tasks.each do |name|
195
- task = task_hash[name]
196
- title = task.name_with_args
197
- comment = task.full_comment
198
- info comment.empty? ? title : (" %-#{width}s # %s" % [title, comment])
199
- end
200
- exit(0)
201
- end
202
-
203
- desc 'List currently cached runtimes'
204
- task('list') do
205
- if Nailgun.ng.server
206
- Nailgun.ng.server.cached_stamps.each_pair do |bf, time|
207
- loaded = Nailgun.ng.server.loaded_times[bf]
208
- ary = [bf, "Load Timestamp", loaded, "Modification Timestamp", time]
209
- info("* %s\n %-25s %s\n %-25s %s\n\n" % ary)
210
- end
211
- else
212
- info "Not running on nailgun server"
213
- end
214
- exit(0)
215
- end
216
-
217
- desc 'Remove all cached runtimes'
218
- task('clear') do
219
- if Nailgun.ng.server
220
- Nailgun.ng.server.cached_runtimes.clear
221
- Nailgun.ng.server.cached_stamps.clear
222
- Nailgun.ng.server.loaded_times.clear
223
- info "Cleared all cached runtimes"
224
- else
225
- info "Not running on nailgun server"
226
- end
227
- exit(0)
228
- end
229
-
230
- desc 'Remove runtime for this buildfile'
231
- task('delete', :buildfile) do |task, args|
232
- if Nailgun.ng.server
233
- if args[:buildfile]
234
- buildfile = File.expand_path(args[:buildfile])
235
- else
236
- buildfile = Buildr.application.buildfile.to_s
237
- end
238
- Nailgun.ng.server.cached_runtimes.delete(buildfile)
239
- Nailgun.ng.server.cached_stamps.delete(buildfile)
240
- Nailgun.ng.server.loaded_times.delete(buildfile)
241
- info "Deleted #{buildfile} from runtime cache"
242
- else
243
- info "Not running on nailgun server"
244
- end
245
- exit(0)
246
- end
247
-
248
- end # server_tasks
249
-
250
- # Load java classes on server side.
251
- ng.server_setup = lambda do
252
-
253
- module Util
254
- include Buildr::Util
255
- end
256
-
257
- Util.add_to_sysloader ng.artifact.to_s
258
- Util.add_to_sysloader File.dirname(__FILE__)
259
-
260
- class NGClient
261
- include org.apache.buildr.BuildrNail
262
- include Client
263
- end
264
-
265
- class NGServer < com.martiansoftware.nailgun.NGServer
266
- include Server
267
- end
268
-
269
- end # server_setup
270
-
271
64
  module Util
272
65
  extend self
273
-
66
+
274
67
  def add_to_sysloader(path)
275
68
  sysloader = java.lang.ClassLoader.getSystemClassLoader
276
69
  add_url_method = java.lang.Class.forName('java.net.URLClassLoader').
@@ -279,43 +72,6 @@ module Buildr #:nodoc:
279
72
  add_url_method.invoke(sysloader, [java.io.File.new(path).toURI.toURL].to_java(java.net.URL))
280
73
  end
281
74
 
282
- def benchmark(action = ['Completed'], verbose = true)
283
- result = nil
284
- times = Benchmark.measure do
285
- result = yield(action)
286
- end
287
- if verbose
288
- real = []
289
- real << ("%ih" % (times.real / 3600)) if times.real >= 3600
290
- real << ("%im" % ((times.real / 60) % 60)) if times.real >= 60
291
- real << ("%.3fs" % (times.real % 60))
292
- trace "#{[action].flatten.join(' ')} in #{real.join}"
293
- end
294
- result
295
- end
296
-
297
- def find_file(pwd, candidates, nosearch=false)
298
- candidates = [candidates].flatten
299
- buildfile = candidates.find { |c| File.file?(File.expand_path(c, pwd)) }
300
- return File.expand_path(buildfile, pwd) if buildfile
301
- return nil if nosearch
302
- updir = File.dirname(pwd)
303
- return nil if File.expand_path(updir) == File.expand_path(pwd)
304
- find_file(updir, candidates)
305
- end
306
-
307
- def exception_handling(raise_again = true, show_error = true)
308
- begin
309
- yield
310
- rescue => e
311
- if show_error
312
- error "#{e.backtrace.shift}: #{e.message}"
313
- e.backtrace.each { |i| error "\tfrom #{i}" }
314
- end
315
- raise if raise_again
316
- end
317
- end
318
-
319
75
  # invoke a java constructor
320
76
  def ctor(on_class, *args)
321
77
  parameters = []
@@ -332,7 +88,7 @@ module Buildr #:nodoc:
332
88
  parameters.push(value)
333
89
  else
334
90
  parameters.push obj
335
- classes.push obj.java_class
91
+ classes.push obj.class.java_class
336
92
  end
337
93
  end
338
94
  on_class = [on_class.java_class].to_java(java.lang.Class)[0]
@@ -341,296 +97,36 @@ module Buildr #:nodoc:
341
97
  ctor.newInstance(parameters.to_java(java.lang.Object))
342
98
  end
343
99
 
344
- def on_runtime(runtime, *args, &block)
345
- raise_error = lambda do |cls, msg, trace|
346
- raise RuntimeError.new(cls + ": "+ msg.to_s).tap { |e| e.set_backtrace(trace.map(&:to_s)) }
347
- end
348
- executor = runtime.object.const_get(:Module).new do
349
- extend self
350
- def runtime_exec(*args, &prc)
351
- define_method(:runtime_exec, &prc)
352
- runtime_exec(*args)
353
- rescue => e
354
- [:error, e.class.name, e.message, e.backtrace]
355
- end
356
- end
357
- result = executor.runtime_exec(*args, &block)
358
- raise_error.call(*result[1..-1]) if result.kind_of?(Array) && result.first == :error
359
- result
360
- end
361
-
362
- def set_stdio(runtime, dev)
363
- set_global = lambda do |global, constant, stream|
364
- runtime.global_variables.set(global, stream)
365
- runtime.object.send(:remove_const, constant)
366
- runtime.object.send(:const_set, constant, stream)
367
- end
368
- stdin = runtime.global_variables.get('$stdin')
369
- stdout = runtime.global_variables.get('$stdout')
370
- stderr = runtime.global_variables.get('$stderr')
371
- #stdin.close; stdout.close; stderr.close;
372
- output = Util.ctor(org.jruby.RubyIO, runtime, java.io.OutputStream => dev.out)
373
- error = Util.ctor(org.jruby.RubyIO, runtime, java.io.OutputStream => dev.err)
374
- input = Util.ctor(org.jruby.RubyIO, runtime, java.io.InputStream => dev.in)
375
- #stdin.reopen(input, 'r') # not working on jruby, :(
376
- #stdout.reopen(output, 'w')
377
- #stderr.reopen(error, 'w')
378
- set_global.call('$stdin', 'STDIN', input)
379
- set_global.call('$stdout', 'STDOUT', output)
380
- set_global.call('$stderr', 'STDERR', error)
381
- end
382
-
383
- end # module Util
384
-
385
- class FieldAccessor
386
- def initialize(obj, clazz = nil)
387
- @obj = obj
388
- clazz ||= obj.class
389
- @cls = [clazz.java_class].to_java(java.lang.Class)[0]
390
- end
391
-
392
- def [](name)
393
- field = @cls.getDeclaredField(name.to_s)
394
- field.setAccessible(true)
395
- field.get(@obj)
396
- end
397
-
398
- def []=(name, value)
399
- field = @cls.getDeclaredField(name.to_s)
400
- field.setAccessible(true)
401
- field.set(@obj, value)
402
- end
403
-
404
- def method_missing(name, value =nil)
405
- if name.to_s =~ /=$/
406
- self[name.to_s.chomp('=')] = value
407
- else
408
- self[name]
409
- end
410
- end
411
- end
412
-
413
- module NailMethods
414
-
415
- def self.extend_object(obj)
416
- super
417
- (class << obj; self; end).module_eval do
418
- alias_method :pwd, :getWorkingDirectory
419
- alias_method :server, :getNGServer
420
- end
421
- end
422
-
423
- def argv
424
- [command] + args
425
- end
426
-
427
- def attach_runtime(runtime)
428
- runtime.extend RuntimeMixin
429
- runtime.evalScriptlet %q{
430
- require 'ostruct'
431
- module Buildr
432
- module Nailgun
433
- extend self
434
- attr_reader :ng
435
- @ng = OpenStruct.new
436
- end
437
- end
438
- }
439
- runtime.Buildr::Nailgun.ng.nail = self
440
- runtime.load_service.require __FILE__
441
- runtime
442
- end
443
- private :attach_runtime
444
-
445
- def jruby
446
- @jruby ||= server.runtime_factory.new_jruby.tap do |runtime|
447
- attach_runtime(runtime)
448
- end
449
- end
450
-
451
- def buildr
452
- @buildr ||= server.runtime_factory.new_buildr.tap do |runtime|
453
- attach_runtime(runtime)
454
- end
455
- end
456
-
457
- def options
458
- @options ||= OpenStruct.new
459
- end
460
-
461
- end # NailMethods
462
-
463
- module RuntimeMixin
464
- def Buildr
465
- object.const_get(:Buildr)
466
- end
467
- end
468
-
469
- module AppMixin
470
- def load_tasks
471
- trace "Not loading tasks again"
472
- end
473
-
474
- def load_buildfile
475
- trace "Not loading buildfile again"
476
- end
477
- end
100
+ end # Util
478
101
 
479
102
  module Client
480
103
 
481
- class << self
482
- include Buildr::CommandLineInterface
483
-
484
- def options
485
- Nailgun.ng.nail.options
486
- end
487
-
488
- def rakefiles
489
- Nailgun.ng.nail.options.rakefiles
490
- end
491
-
492
- def requires
493
- Nailgun.ng.nail.options.requires
494
- end
495
-
496
- def help
497
- super
498
- puts
499
- puts 'To get a summary of Nailgun features use'
500
- puts ' nailgun:help'
501
- end
502
-
503
- def version
504
- puts super
505
- end
104
+ def main(nail)
105
+ nail.out.println "Connected to #{nail.getNGServer}"
506
106
 
507
- def do_option(opt, value)
508
- case opt
509
- when '--help'
510
- options.exit = :help
511
- when '--version'
512
- options.exit = :version
513
- when '--nosearch'
514
- options.nosearch = true
515
- else
516
- super
517
- end
518
- end
107
+ runtime = JRuby.runtime
519
108
 
520
- def sBuildr
521
- Nailgun.ng.nail.server.runtime.object.const_get(:Buildr)
522
- end
109
+ stdout = Util.ctor(org.jruby.RubyIO, runtime, java.io.OutputStream => nail.out)
110
+ stderr = Util.ctor(org.jruby.RubyIO, runtime, java.io.OutputStream => nail.err)
111
+ stdin = Util.ctor(org.jruby.RubyIO, runtime, java.io.InputStream => nail.in)
523
112
 
524
- def attach_runtime
525
- nail = Nailgun.ng.nail
526
- ARGV.replace nail.argv
527
- Dir.chdir nail.pwd
528
- nail.env.each { |k, v| ENV[k.to_s] = v.to_s }
529
-
530
- Buildr.const_set(:VERSION, sBuildr::VERSION) unless Buildr.const_defined?(:VERSION)
531
- nail.options.rakefiles = sBuildr::Application::DEFAULT_BUILDFILES.dup
532
- nail.options.requires = []
533
- end
113
+ dir = nail.getWorkingDirectory
114
+ argv = [nail.command] + nail.args
534
115
 
535
- def client(runtime, nail, &block)
536
- Util.set_stdio(runtime, nail)
537
- nailgun_module = runtime.Buildr::Nailgun
538
- nailgun_module.ng.nail = nail
539
- nailgun_module::Client.attach_runtime
540
- nailgun_module::Client.instance_eval(&block)
541
- end
542
- end
543
-
544
- def main(nail)
545
- nail.extend NailMethods
546
- info "Got connection from #{nail.pwd}"
547
-
548
- Client.client(nail.jruby, nail) do
549
-
550
- parse_options
551
- if options.exit
552
- send(options.exit)
553
- nail.exit(0)
554
- end
555
-
556
- if options.project && File.directory?(options.project)
557
- Dir.chdir(options.project)
558
- end
559
-
560
- bf = Util.find_file(Dir.pwd, options.rakefiles, options.nosearch)
561
- unless bf
562
- nail.out.println "No buildfile found at #{Dir.pwd}"
563
- nail.exit(0)
564
- end
565
-
566
- rt = nail.server.cached_runtimes[bf]
567
- old_stamp = nail.server.cached_stamps[bf] || Rake::EARLY
568
- new_stamp = rt ? rt.Buildr.application.buildfile.timestamp : Rake::EARLY
569
-
570
- if rt.nil? || new_stamp > old_stamp
571
- rt = nail.buildr
572
- app = rt.Buildr.application
573
- else
574
- app = rt.Buildr.application.extend AppMixin
575
- app.lookup('buildr:initialize').instance_eval do
576
- @already_invoked = false
577
- @actions = []
578
- end
579
- app.instance_eval do
580
- @tasks.values.each do |task|
581
- is_project = rt.Buildr::Project.instance_variable_get(:@projects).key?(task.name)
582
- task.instance_variable_set(:@already_invoked, false) unless is_project
583
- end
584
- end
585
- end
586
-
587
- app.instance_eval do
588
- @original_dir = nail.pwd
589
- end
590
-
591
- Client.client(rt, nail) do
592
- Util.exception_handling do
593
- begin
594
- app.parse_options
595
- app.collect_tasks
596
- app.run
597
- rescue SystemExit => e
598
- nail.exit(1)
599
- end
600
- end
601
- end
602
-
603
- nail.server.cache(rt, app.buildfile)
604
- end
116
+ DRbApplication.remote_run :dir => dir, :argv => argv,
117
+ :in => stdin, :out => stdout, :err => stderr
118
+ rescue => e
119
+ nail.err.println e unless SystemExit === e
120
+ nail.exit 1
605
121
  end
606
122
 
607
- end # class Client
123
+ end # Client
608
124
 
609
125
  module Server
610
-
611
- attr_reader :runtime_factory
612
- attr_reader :cached_runtimes
613
- attr_reader :cached_stamps
614
- attr_reader :loaded_times
615
-
616
- def initialize(host = 'localhost', port = 2113, buildr_factory = nil)
617
- super(java.net.InetAddress.get_by_name(host), port)
618
- @cached_runtimes = {}
619
- @cached_stamps = {}
620
- @loaded_times = {}
621
- cache(runtime, Buildr.application.buildfile)
622
- @runtime_factory = buildr_factory
623
- @host, @port = host, port
624
- end
625
-
626
- def cache(runtime, buildfile)
627
- cached_runtimes[buildfile.to_s] = runtime
628
- cached_stamps[buildfile.to_s] = buildfile.timestamp
629
- loaded_times[buildfile.to_s] = Time.now
630
- end
631
-
632
- def runtime
633
- JRuby.runtime.extend RuntimeMixin
126
+ def initialize(host, port)
127
+ @host = host || "*"
128
+ @port = port
129
+ super(host, port)
634
130
  end
635
131
 
636
132
  def start
@@ -638,7 +134,6 @@ module Buildr #:nodoc:
638
134
 
639
135
  NGClient::Main.nail = NGClient.new
640
136
  self.default_nail_class = NGClient::Main
641
- runtime_factory.start
642
137
 
643
138
  @thread = java.lang.Thread.new(self)
644
139
  @thread.setName(to_s)
@@ -649,165 +144,78 @@ module Buildr #:nodoc:
649
144
  end
650
145
 
651
146
  def stop
652
- runtime_factory.stop
653
147
  @thread.kill
654
148
  end
655
149
 
656
150
  def to_s
657
- self.class.name+'('+[Buildr.application.version, @host, @port].join(', ')+')'
151
+ version = "Buildr #{Buildr::VERSION} #{RUBY_PLATFORM[/java/] && '(JRuby '+JRUBY_VERSION+')'}"
152
+ self.class.name+'('+[version, @host, @port].join(', ')+')'
658
153
  end
659
- end # module Server
660
-
661
- class RuntimeFactory
662
-
663
- attr_accessor :buildrs_size, :jrubys_size
664
-
665
- def initialize(buildrs_size = 1, jrubys_size = nil)
666
- # jrubys_size ||= buildrs_size
667
- @buildrs_size = buildrs_size < 1 ? 1 : buildrs_size
668
- # @jrubys_size = jrubys_size < 1 ? 1 : jrubys_size
154
+ end # Server
669
155
 
670
- @buildrs = [].extend(MonitorMixin)
671
- @buildrs_ready = @buildrs.new_cond
672
- @buildrs_needed = @buildrs.new_cond
673
-
674
- @buildrs_creators = [].extend(MonitorMixin)
156
+ namespace(:nailgun) do
675
157
 
676
- # @jrubys = [].extend(MonitorMixin)
677
- # @jrubys_ready = @jrubys.new_cond
678
- # @jrubys_needed = @jrubys.new_cond
679
-
680
- # @jrubys_creators = [].extend(MonitorMixin)
681
- end
158
+ dist_zip = Buildr.download(tmp_path(NAME + '.zip') => URL)
159
+ dist_dir = Buildr.unzip(tmp_path(NAME) => dist_zip)
682
160
 
683
- def new_buildr
684
- get(:buildr)
685
- end
161
+ nailgun_jar = file(tmp_path(NAME, NAME, NAME + '.jar'))
162
+ nailgun_jar.enhance [dist_dir] unless File.exist?(nailgun_jar.to_s)
686
163
 
687
- def new_jruby(&block)
688
- # get(:jruby)
689
- create_jruby(0, &block)
164
+ attr_reader :artifact
165
+ @artifact = Buildr.artifact(ARTIFACT_SPEC).from(nailgun_jar)
166
+
167
+ compiled_bin = file(tmp_path(NAME, NAME, 'ng' + Config::CONFIG['EXEEXT']) => dist_dir.target) do |task|
168
+ unless task.to_s.pathmap('%x') == '.exe'
169
+ Dir.chdir(task.to_s.pathmap('%d')) do
170
+ info "Compiling #{task.to_s}"
171
+ system('make', task.to_s.pathmap('%f')) or
172
+ fail "Nailgun binary compilation failed."
173
+ end
174
+ end
690
175
  end
691
176
 
692
- def start
693
- trace "Starting Buildr runtime factory"
694
- # @jruby_creator = Thread.new { loop { create :jruby } }
695
- # @jruby_creator.priority = -2
696
- @buildr_creator = Thread.new { loop { create :buildr } }
697
- @buildr_creator.priority = 1
177
+ attr_reader :installed_bin
178
+ @installed_bin = file(File.expand_path(compiled_bin.to_s.pathmap('%f'), nailgun_home) => compiled_bin) do |task|
179
+ mkpath task.to_s.pathmap('%d'), :verbose => false
180
+ cp compiled_bin.to_s, task.to_s, :verbose => false
698
181
  end
699
182
 
700
- def stop
701
- @buildr_creator.kill if @buildr_creator
702
- # @jruby_creator.kill if @jruby_creator
183
+ task('drb-notice') do
184
+ info ''
185
+ info 'Running in JRuby, a nailgun server will be started so that'
186
+ info 'you can use your nailgun client to invoke buildr tasks: '
187
+ info ''
188
+ info ' '+Nailgun.installed_bin.to_s
189
+ info ''
703
190
  end
704
191
 
705
- private
706
- def get(thing)
707
- collection = instance_variable_get("@#{thing}s")
708
- needs = instance_variable_get("@#{thing}s_needed")
709
- ready = instance_variable_get("@#{thing}s_ready")
710
- result = nil
711
- collection.synchronize do
712
- if collection.empty?
713
- trace "no #{thing} available, ask to create more"
714
- needs.broadcast
715
- trace "should be creating #{thing}"
716
- ready.wait_while { collection.empty? }
717
- end
718
- trace "Getting my #{thing}"
719
- result = collection.shift
720
- trace "would need more #{thing}s"
721
- needs.broadcast
722
- trace "got my #{thing}: #{result.inspect}"
723
- Thread.pass
724
- end
725
- trace "returning #{result.inspect}"
726
- result
192
+ task('drb' => ['drb-notice', 'start'])
193
+
194
+ desc 'Start the nailgun server'
195
+ task('start' => [installed_bin, 'setup']) do |task|
196
+ server = NGServer.new(nil, PORT)
197
+ server.start
727
198
  end
728
199
 
729
- def create(thing, *args, &block)
730
- Util.exception_handling do
731
- creator = needed(thing)
732
- collection = instance_variable_get("@#{thing}s")
733
- ready = instance_variable_get("@#{thing}s_ready")
734
- needs = instance_variable_get("@#{thing}s_needed")
735
- unless creator
736
- collection.synchronize do
737
- trace "awake those wanting a #{thing}"
738
- ready.broadcast
739
- Thread.pass
740
- trace "wait until more #{thing}s are needed"
741
- # needs.wait(1); return
742
- needs.wait_until { creator = needed(thing) }
743
- end
744
- end
745
- trace "About to create #{thing} # #{creator}"
746
- method = "create_#{thing}"
747
- creators = instance_variable_get("@#{thing}s_creators")
748
- trace "registering creator for #{thing} #{creator}"
749
- creators.synchronize { creators << creator }
750
- result = send(method, creator, *args, &block)
751
- trace "created #{thing}[#{creator}] => #{result.inspect}"
752
- creators.synchronize do
753
- trace "unregistering creator for #{thing} #{creator}"
754
- creators.delete(creator)
755
- collection.synchronize do
756
- trace "adding object on queue for #{thing} #{creator}"
757
- collection << result
758
- end
759
- end
200
+ task('setup' => artifact) do
201
+ module Util
202
+ include Buildr::Util
760
203
  end
761
- end
762
-
763
- def needed(thing)
764
- collection = instance_variable_get("@#{thing}s")
765
- creators = instance_variable_get("@#{thing}s_creators")
766
- size = instance_variable_get("@#{thing}s_size")
767
- collection.synchronize do
768
- count = collection.size
769
- if count < size
770
- count += creators.synchronize { creators.size }
771
- end
772
- count if count < size
204
+
205
+ Util.add_to_sysloader artifact.to_s
206
+ Util.add_to_sysloader ADDON_BIN
207
+
208
+ class NGClient
209
+ include org.apache.buildr.BuildrNail
210
+ include Client
773
211
  end
212
+
213
+ class NGServer < com.martiansoftware.nailgun.NGServer
214
+ include Server
215
+ end
774
216
  end
775
217
 
776
- def create_jruby(creator, &block)
777
- Util.exception_handling do
778
- trace "Creating jruby[#{creator}]"
779
- Util.benchmark do |header|
780
- cfg = org.jruby.RubyInstanceConfig.new
781
- yield cfg if block_given?
782
- jruby = org.jruby.Ruby.newInstance(cfg)
783
- jruby.load_service.load_path.unshift *BUILDR_PATHS
784
- header.replace ["Created jruby[#{creator}]", jruby]
785
- jruby
786
- end
787
- end
788
- end
789
-
790
- def create_buildr(creator)
791
- Util.exception_handling do
792
- trace "Obtaining jruby to load buildr[#{creator}] on it"
793
- jruby = new_jruby
794
- trace "Loading buildr[#{creator}] on #{jruby} ..."
795
- Util.benchmark ["Loaded buildr[#{creator}] on #{jruby}"] do
796
- load_service = jruby.load_service
797
- load_service.require 'rubygems'
798
- load_service.require 'buildr'
799
- end
800
- jruby
801
- end
802
- end
218
+ end # ng_tasks
803
219
 
804
- end # RuntimeFactory
805
-
806
- if Buildr.respond_to?(:application) && ng.nail.nil?
807
- Buildr.application.in_namespace(:nailgun, &file_tasks)
808
- Buildr.application.in_namespace(:nailgun, &server_tasks)
809
- end
810
-
811
220
  end # module Nailgun
812
-
813
221
  end