vic-buildr 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
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