BuildMaster 1.1.9 → 1.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/lib/buildmaster/algorithms.rb +2 -2
  2. data/lib/buildmaster/auto.rb +27 -0
  3. data/lib/buildmaster/auto/classpath.rb +86 -0
  4. data/lib/buildmaster/auto/git.rb +38 -0
  5. data/lib/buildmaster/auto/java.rb +23 -0
  6. data/lib/buildmaster/auto/java_project.rb +185 -0
  7. data/lib/buildmaster/auto/javac_ant.rb +64 -0
  8. data/lib/buildmaster/auto/junit_ant.rb +226 -0
  9. data/lib/buildmaster/auto/mysql_server.rb +30 -0
  10. data/lib/buildmaster/auto/package_ant.rb +60 -0
  11. data/lib/buildmaster/auto/ruby_platform.rb +51 -0
  12. data/lib/buildmaster/common.rb +3 -3
  13. data/lib/buildmaster/cotta.rb +8 -3
  14. data/lib/buildmaster/cotta/command_runner.rb +19 -3
  15. data/lib/buildmaster/cotta/cotta.rb +42 -12
  16. data/lib/buildmaster/cotta/cotta_dir.rb +18 -14
  17. data/lib/buildmaster/cotta/cotta_file.rb +5 -8
  18. data/lib/buildmaster/cotta/in_memory_system.rb +15 -4
  19. data/lib/buildmaster/cotta/physical_system.rb +13 -7
  20. data/lib/buildmaster/project.rb +3 -9
  21. data/lib/buildmaster/project/ant_driver.rb +11 -7
  22. data/lib/buildmaster/project/ci.rb +2 -2
  23. data/lib/buildmaster/project/pscp_driver.rb +0 -4
  24. data/lib/buildmaster/project/ruby_forge_project.rb +0 -3
  25. data/lib/buildmaster/project/svn_admin_driver.rb +0 -4
  26. data/lib/buildmaster/project/svn_driver.rb +0 -6
  27. data/lib/buildmaster/project/svn_helper.rb +0 -6
  28. data/lib/buildmaster/project/svn_server_driver.rb +0 -5
  29. data/lib/buildmaster/project/windows/iis_driver.rb +0 -4
  30. data/lib/buildmaster/project/windows/sql_server_driver.rb +0 -1
  31. data/lib/buildmaster/site.rb +16 -4
  32. data/lib/buildmaster/site/about_handler.rb +0 -4
  33. data/lib/buildmaster/site/content_engine_repository.rb +0 -2
  34. data/lib/buildmaster/site/element_processor_by_name.rb +0 -4
  35. data/lib/buildmaster/site/file_processor.rb +0 -4
  36. data/lib/buildmaster/site/site.rb +0 -4
  37. data/lib/buildmaster/site/site_server.rb +1 -4
  38. data/lib/buildmaster/site/site_spec.rb +4 -15
  39. data/lib/buildmaster/site/source_file_handler.rb +0 -3
  40. data/lib/buildmaster/site/template_error.rb +0 -2
  41. data/lib/buildmaster/site/template_runner.rb +0 -4
  42. data/lib/buildmaster/site/templatelets.rb +9 -10
  43. data/lib/buildmaster/site/templatelets/href.rb +0 -5
  44. data/lib/buildmaster/site/templatelets/when.rb +0 -4
  45. data/lib/buildmaster/site/xtemplate.rb +0 -3
  46. data/lib/buildmaster/version +1 -1
  47. data/lib/buildmaster/win32/auto_it.rb +4 -0
  48. data/lib/buildmaster/win32/auto_it_driver.rb +45 -0
  49. data/lib/buildmaster/win32/auto_it_window.rb +82 -0
  50. data/lib/buildmaster/win32/autoit/AutoItX3.dll +0 -0
  51. data/lib/buildmaster/win32/autoit/README +1 -0
  52. data/lib/buildmaster/windows.rb +3 -3
  53. data/test/buildmaster/algorithms/tc_opn_compare.rb +2 -2
  54. data/test/buildmaster/auto/javac/src/org/rubyforge/buildmaster/javac/One.java +5 -0
  55. data/test/buildmaster/auto/javac/src/resource.txt +1 -0
  56. data/test/buildmaster/auto/javac/src2/org/rubyforge/buildmaster/javac/Two.java +9 -0
  57. data/test/buildmaster/auto/tc_classpath.rb +79 -0
  58. data/test/buildmaster/auto/tc_git.rb +32 -0
  59. data/test/buildmaster/auto/tc_java.rb +12 -0
  60. data/test/buildmaster/auto/tc_java_project.rb +78 -0
  61. data/test/buildmaster/auto/tc_java_project_slow.rb +89 -0
  62. data/test/buildmaster/auto/tc_javac_ant.rb +38 -0
  63. data/test/buildmaster/auto/tc_junit_ant.rb +187 -0
  64. data/test/buildmaster/auto/tc_package_ant.rb +29 -0
  65. data/test/buildmaster/auto/tc_ruby_platform.rb +10 -0
  66. data/test/buildmaster/common/tc_properties.rb +1 -3
  67. data/test/buildmaster/common/tc_tree_to_object.rb +1 -3
  68. data/test/buildmaster/cotta/cotta_dir_behaviors.rb +46 -8
  69. data/test/buildmaster/cotta/cotta_file_behaviors.rb +6 -6
  70. data/test/buildmaster/cotta/cotta_specifications.rb +1 -6
  71. data/test/buildmaster/cotta/file_system_behaviors.rb +1 -3
  72. data/test/buildmaster/cotta/physical_system_stub.rb +22 -3
  73. data/test/buildmaster/cotta/system_file_specifications.rb +1 -3
  74. data/test/buildmaster/cotta/tc_command_interface.rb +1 -3
  75. data/test/buildmaster/cotta/tc_command_runner.rb +1 -4
  76. data/test/buildmaster/cotta/tc_cotta.rb +5 -8
  77. data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +6 -9
  78. data/test/buildmaster/cotta/tc_cotta_dir_physical.rb +3 -6
  79. data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +3 -7
  80. data/test/buildmaster/cotta/tc_cotta_file_physical.rb +4 -4
  81. data/test/buildmaster/cotta/tc_cotta_zip_support.rb +1 -5
  82. data/test/buildmaster/cotta/tc_in_memory_system.rb +3 -7
  83. data/test/buildmaster/cotta/tc_io_chain.rb +3 -8
  84. data/test/buildmaster/cotta/tc_pathname.rb +1 -3
  85. data/test/buildmaster/cotta/tc_physical_system.rb +7 -8
  86. data/test/buildmaster/project/tc_ant_driver.rb +1 -4
  87. data/test/buildmaster/project/tc_build_number_file.rb +1 -6
  88. data/test/buildmaster/project/tc_cvs_driver.rb +1 -5
  89. data/test/buildmaster/project/tc_java_manifest.rb +1 -5
  90. data/test/buildmaster/project/tc_release.rb +1 -3
  91. data/test/buildmaster/project/tc_server_manager.rb +1 -4
  92. data/test/buildmaster/project/tc_svn_driver.rb +1 -5
  93. data/test/buildmaster/project/tc_svn_status_info.rb +1 -3
  94. data/test/buildmaster/project/tc_version_number_file.rb +1 -6
  95. data/test/buildmaster/project/windows/tc_iis_driver.rb +2 -3
  96. data/test/buildmaster/project/windows/tc_sql_server_driver.rb +2 -5
  97. data/test/buildmaster/site/content/tc_content_engine_repository.rb +1 -5
  98. data/test/buildmaster/site/tc_element_processor_by_name.rb +1 -4
  99. data/test/buildmaster/site/tc_file_processor.rb +1 -7
  100. data/test/buildmaster/site/tc_site.rb +1 -6
  101. data/test/buildmaster/site/tc_site_server.rb +2 -8
  102. data/test/buildmaster/site/tc_site_spec.rb +8 -5
  103. data/test/buildmaster/site/tc_source_file_handler.rb +1 -4
  104. data/test/buildmaster/site/tc_template_builder.rb +1 -4
  105. data/test/buildmaster/site/tc_template_error.rb +1 -3
  106. data/test/buildmaster/site/tc_template_runner.rb +2 -7
  107. data/test/buildmaster/site/tc_templatelets.rb +2 -6
  108. data/test/buildmaster/site/tc_xtemplate.rb +1 -5
  109. data/test/buildmaster/site/templatelets/common_templatelet_test.rb +1 -8
  110. data/test/buildmaster/site/templatelets/tc_attribute.rb +3 -3
  111. data/test/buildmaster/site/templatelets/tc_code.rb +2 -2
  112. data/test/buildmaster/site/templatelets/tc_each.rb +3 -3
  113. data/test/buildmaster/site/templatelets/tc_href.rb +3 -3
  114. data/test/buildmaster/site/templatelets/tc_include.rb +3 -3
  115. data/test/buildmaster/site/templatelets/tc_link.rb +3 -3
  116. data/test/buildmaster/site/templatelets/tc_text.rb +3 -3
  117. data/test/buildmaster/site/templatelets/tc_when.rb +4 -4
  118. data/test/buildmaster/site/test.rb +1 -0
  119. data/test/buildmaster/test.rb +21 -0
  120. data/test/buildmaster/win32/tc_auto_it.rb +18 -0
  121. data/test/buildmaster/win32/tc_auto_it_window.rb +17 -0
  122. data/test/manual/bms.rb +2 -4
  123. data/test/tmp/svn_test/repository/conf/authz +14 -3
  124. data/test/tmp/svn_test/repository/conf/svnserve.conf +21 -4
  125. data/test/tmp/svn_test/repository/db/current +1 -1
  126. data/test/tmp/svn_test/repository/db/format +2 -1
  127. data/test/tmp/svn_test/repository/db/revprops/0/0 +5 -0
  128. data/test/tmp/svn_test/repository/db/revprops/{1 → 0/1} +1 -1
  129. data/test/tmp/svn_test/repository/db/revprops/{2 → 0/2} +1 -1
  130. data/test/tmp/svn_test/repository/db/revprops/{3 → 0/3} +1 -1
  131. data/test/tmp/svn_test/repository/db/revprops/{4 → 0/4} +1 -1
  132. data/test/tmp/svn_test/repository/db/revs/{0 → 0/0} +0 -0
  133. data/test/tmp/svn_test/repository/db/revs/0/1 +25 -0
  134. data/test/tmp/svn_test/repository/db/revs/{2 → 0/2} +9 -9
  135. data/test/tmp/svn_test/repository/db/revs/0/3 +33 -0
  136. data/test/tmp/svn_test/repository/db/revs/{4 → 0/4} +0 -0
  137. data/test/tmp/svn_test/repository/db/txn-current +1 -0
  138. data/{lib/buildmaster/project/java/class_path.rb → test/tmp/svn_test/repository/db/txn-current-lock} +0 -0
  139. data/test/tmp/svn_test/repository/db/uuid +1 -1
  140. data/test/tmp/svn_test/repository/hooks/post-revprop-change.tmpl +1 -1
  141. data/test/tmp/svn_test/repository/hooks/pre-unlock.tmpl +1 -0
  142. data/test/tmp/svn_test/repository/hooks/start-commit.tmpl +13 -2
  143. data/test/ts_buildmaster.rb +2 -2
  144. metadata +100 -46
  145. data/lib/buildmaster/project/java.rb +0 -4
  146. data/lib/buildmaster/project/java/javac.rb +0 -9
  147. data/test/tmp/svn_test/repository/db/revprops/0 +0 -5
  148. data/test/tmp/svn_test/repository/db/revs/1 +0 -25
  149. data/test/tmp/svn_test/repository/db/revs/3 +0 -33
@@ -1,3 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__), 'algorithms')
1
+ dir = File.dirname(__FILE__)
2
2
 
3
- require 'opn_compare'
3
+ require dir + '/algorithms/opn_compare'
@@ -0,0 +1,27 @@
1
+ dir = File.dirname(__FILE__)
2
+ require dir + '/cotta'
3
+
4
+ project = dir + '/project'
5
+ require project + '/build_number_file'
6
+ require project + '/java_manifest'
7
+ require project + '/ant_driver'
8
+ require project + '/cvs_driver'
9
+ require project + '/pscp_driver'
10
+ require project + '/svn_admin_driver'
11
+ require project + '/svn_driver'
12
+ require project + '/svn_status_info'
13
+ require project + '/server_manager'
14
+ require project + '/version_number_file'
15
+ require project + '/release'
16
+ require project + '/ci'
17
+
18
+ auto = dir + '/auto'
19
+ require auto + '/classpath'
20
+ require auto + '/git'
21
+ require auto + '/java'
22
+ require auto + '/javac_ant'
23
+ require auto + '/junit_ant'
24
+ require auto + '/package_ant'
25
+ require auto + '/java_project'
26
+ require auto + '/mysql_server'
27
+ require auto + '/ruby_platform'
@@ -0,0 +1,86 @@
1
+ module BuildMaster
2
+ class ClasspathEntry
3
+ attr_reader :path
4
+
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def to_ant
10
+ " <pathelement location=\"#{@path}\"/>\n"
11
+ end
12
+
13
+ def ==(other)
14
+ other.class == ClasspathEntry and other.path == path
15
+ end
16
+ end
17
+
18
+ class ClasspathEntries
19
+ def initialize(dir)
20
+ @dir = dir
21
+ end
22
+
23
+ def to_ant
24
+ return <<RESULT
25
+ <fileset dir="#{@dir}">
26
+ <include name="**/*.jar"/>
27
+ </fileset>
28
+ RESULT
29
+ end
30
+ end
31
+
32
+ class Classpath
33
+
34
+ def initialize(root = nil)
35
+ @entries = Array.new
36
+ @root = root
37
+ end
38
+
39
+ def include?(entry)
40
+ @entries.include?(convert(entry))
41
+ end
42
+
43
+ def insert(entry)
44
+ @entries.unshift(convert(entry))
45
+ end
46
+
47
+ def add(entry)
48
+ @entries.push(convert(entry))
49
+ end
50
+
51
+ def add_all(dir)
52
+ @entries.push(ClasspathEntries.new(dir))
53
+ end
54
+
55
+ def empty?
56
+ @entries.empty?
57
+ end
58
+
59
+ def to_ant(id=nil)
60
+ return '' if empty?
61
+ result = entries_to_ant
62
+ if (not id.nil?)
63
+ result = <<RESULT
64
+ <path id="#{id}">
65
+ #{result} </path>
66
+ RESULT
67
+ end
68
+ result
69
+ end
70
+
71
+ private
72
+ def entries_to_ant
73
+ io = StringIO.new
74
+ @entries.each {|entry| io << "#{entry.to_ant}"}
75
+ io.string
76
+ end
77
+
78
+ def convert(entry)
79
+ if (entry.respond_to? :to_ant)
80
+ entry
81
+ else
82
+ ClasspathEntry.new(entry)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,38 @@
1
+ module BuildMaster
2
+ class Git
3
+ attr_reader :work_dir
4
+ def initialize(work_dir)
5
+ @work_dir = work_dir
6
+ end
7
+
8
+ def status
9
+ command('status')
10
+ end
11
+
12
+ def pull
13
+ command('pull')
14
+ end
15
+
16
+ def add(entry=nil)
17
+ path = '.'
18
+ path = entry.to_s if entry
19
+ command("add #{path}")
20
+ end
21
+
22
+ def commit(comment)
23
+ comment = comment.sub(/"/, '\""')
24
+ command("commit -m \"#{comment}\"")
25
+ end
26
+
27
+ def tag(name)
28
+ command("tag #{name}")
29
+ end
30
+
31
+ private
32
+ def command(command)
33
+ @work_dir.chdir do
34
+ @work_dir.cotta.shell("git #{command}")
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ module BuildMaster
2
+ class Java
3
+ def initialize(java_home=nil)
4
+ @home = java_home
5
+ if @home.nil?
6
+ @cotta = Cotta.new
7
+ else
8
+ @cotta = @home.cotta
9
+ end
10
+ end
11
+
12
+ def version
13
+ @cotta.shell("#{java_exe} -version")
14
+ end
15
+
16
+ private
17
+ def java_exe
18
+ exe = 'java'
19
+ exe = @home.file('bin/java') if @home
20
+ exe
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,185 @@
1
+ module BuildMaster
2
+ # Java project that knows how to compile the production and test source
3
+ class JavaProject
4
+ attr_accessor :output, :name, :target_version
5
+ attr_reader :root, :prod, :test, :output
6
+
7
+ def initialize(root)
8
+ @root = root
9
+ @prod = ProjectInfo.new(self)
10
+ @prod.classpath = Classpath.new(root)
11
+ @test = ProjectInfo.new(self)
12
+ @test.classpath = Classpath.new(root)
13
+ if block_given?
14
+ yield self
15
+ end
16
+ end
17
+
18
+ def src=(dir)
19
+ prod.src = dir
20
+ end
21
+
22
+ def src
23
+ prod.src
24
+ end
25
+
26
+ def resource=(dir)
27
+ prod.resource = dir
28
+ end
29
+
30
+ def resource
31
+ prod.resource
32
+ end
33
+
34
+ def output=(dir)
35
+ @output = dir(dir)
36
+ @prod.output=@output.dir('prod')
37
+ @test.output=@output.dir('test')
38
+ end
39
+
40
+ # Specifies that the current project uses the entry
41
+ # The entry can be one of the three things:
42
+ # It can be another JavaProject, in which case it will be added as a classpath element.
43
+ # In this case, the project output and its classpath will be part of the current project
44
+ # classpath. It can also be a CottaDirectory or CottaFile, in which case it will be added
45
+ # to the classpath. It can also be a path string, in which case it will be converted to
46
+ # CottaFile or CottaDirectory based on whether or not the extname is empty
47
+ def uses(*entries)
48
+ add_entry(@prod, entries)
49
+ end
50
+
51
+ def uses_files_in(*dirs)
52
+ dirs.each {|dir| @prod.classpath.add_all(dir(dir))}
53
+ end
54
+
55
+ def tests_with(*entries)
56
+ add_entry(@test, entries)
57
+ end
58
+
59
+ def tests_with_files_in(*dirs)
60
+ dirs.each {|dir| @test.classpath.add_all(dir(dir))}
61
+ end
62
+
63
+ def classpath
64
+ @prod.classpath
65
+ end
66
+
67
+ def add_project(project)
68
+ @prod.classpath.add project
69
+ end
70
+
71
+ def javac(buildfile = nil)
72
+ javac = JavacAnt.new(prod.output, buildfile)
73
+ javac.target_version = target_version
74
+ javac.src = prod.src
75
+ javac.classpath.add prod.classpath unless prod.classpath.empty?
76
+ javac.resource = prod.resource if prod.resource
77
+ result = nil
78
+ if (test.src.nil?)
79
+ result = [javac]
80
+ else
81
+ javac_test = JavacAnt.new(test.output, buildfile)
82
+ javac_test.target_version = target_version
83
+ javac_test.src = test.src
84
+ javac_test.resource = test.resource if test.resource
85
+ javac_test.classpath.add prod.output
86
+ javac_test.classpath.add prod.classpath unless prod.classpath.empty?
87
+ javac_test.classpath.add test.classpath unless test.classpath.empty?
88
+ result = [javac, javac_test]
89
+ end
90
+ result
91
+ end
92
+
93
+ def junit(report_dir)
94
+ junit = JUnitAnt.new(report_dir, self)
95
+ junit.classpath.add test.output
96
+ junit.classpath.add prod.output
97
+ junit.classpath.add test.classpath
98
+ junit.classpath.add prod.classpath
99
+ junit
100
+ end
101
+
102
+ def make(buildfile = nil)
103
+ javac(buildfile).each {|javac| javac.compile}
104
+ end
105
+
106
+ def package(dir, name)
107
+ ant = PackageAnt.new(dir, name)
108
+ ant.add(prod.output, prod.src)
109
+ yield ant if block_given?
110
+ ant.run
111
+ end
112
+
113
+ def jar(file)
114
+
115
+ end
116
+
117
+ def clean
118
+ output.delete
119
+ end
120
+
121
+ def rebuild
122
+ clean
123
+ make
124
+ end
125
+
126
+ # create XML classpath element for ANT build file
127
+ def to_ant
128
+ io = StringIO.new
129
+ io << ClasspathEntry.new(prod.output).to_ant
130
+ io << classpath.to_ant
131
+ io.string
132
+ end
133
+
134
+ def dir(path)
135
+ if (path.class == String)
136
+ @root.dir(path)
137
+ else
138
+ path
139
+ end
140
+ end
141
+
142
+ def file(path)
143
+ if (path.class == String)
144
+ @root.file(path)
145
+ else
146
+ path
147
+ end
148
+ end
149
+
150
+ private
151
+ def guess_entry(entry)
152
+ path = Pathname.new(entry)
153
+ if (path.extname.empty?)
154
+ dir(entry)
155
+ else
156
+ file(entry)
157
+ end
158
+ end
159
+
160
+ def add_entry(target, entries)
161
+ entries.each do |entry|
162
+ if (entry.class == String)
163
+ entry = guess_entry(entry)
164
+ end
165
+ target.classpath.add(entry)
166
+ end
167
+ end
168
+ end
169
+
170
+ class ProjectInfo
171
+ attr_accessor :src, :classpath, :output, :resource
172
+
173
+ def initialize(project)
174
+ @project = project
175
+ end
176
+
177
+ def src=(source)
178
+ @src = @project.dir(source)
179
+ end
180
+
181
+ def resource=(resource)
182
+ @resource = @project.dir(resource)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,64 @@
1
+ module BuildMaster
2
+ # Javac Ant driver.
3
+ # This class utilize ANT to perform the javac tasks
4
+ class JavacAnt
5
+ attr_reader :output_dir, :classpath
6
+ attr_accessor :src, :resource, :target_version
7
+
8
+ def initialize(output_dir, buildfile = nil)
9
+ @output_dir = output_dir
10
+ @classpath = Classpath.new
11
+ if (buildfile.nil?)
12
+ @buildfile = 'buildmaster.xml'
13
+ else
14
+ @buildfile = buildfile
15
+ end
16
+ end
17
+
18
+ def compile()
19
+ output_dir.mkdirs
20
+ ant_file = output_dir.parent.file(@buildfile)
21
+ classpath_ref = 'javac'
22
+ ant_file.save <<ANT
23
+ <!-- ANT file generated by BuildMaster -->
24
+ <project name="buildmaster">
25
+ #{@classpath.to_ant(classpath_ref)}
26
+ <target name="javac">
27
+ <javac srcdir="#{src}" destdir="#{output_dir}" debug="on"#{target_attribute}>
28
+ #{to_ant_ref(classpath_ref)}
29
+ </javac>
30
+ <copy todir="#{output_dir}">
31
+ #{resource_file_set}
32
+ </copy>
33
+ </target>
34
+ </project>
35
+ ANT
36
+ AntDriver.from_file(ant_file).target("javac")
37
+ end
38
+
39
+ private
40
+ def to_ant_ref(refid)
41
+ if (@classpath.empty?)
42
+ ''
43
+ else
44
+ "<classpath refid=\"#{refid}\"/>"
45
+ end
46
+ end
47
+
48
+ def resource_file_set
49
+ if (resource.nil?)
50
+ "<fileset dir=\"#{src}\" excludes=\"**/*.java\"/>"
51
+ else
52
+ "<fileset dir=\"#{resource}\"/>"
53
+ end
54
+ end
55
+
56
+ def target_attribute
57
+ if target_version.nil?
58
+ ''
59
+ else
60
+ " target=\"#{@target_version}\""
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,226 @@
1
+ module BuildMaster
2
+ # JUnit ANT invocation
3
+ class JUnitAnt
4
+ attr_reader :report, :test, :classpath, :jvmargs, :project
5
+
6
+ def initialize(report, project = nil)
7
+ @report = report
8
+ @classpath = Classpath.new
9
+ @jvmargs = Array.new
10
+ @coverage = NilCoverage.new
11
+ @project = project
12
+ end
13
+
14
+ def target_name
15
+ 'junit-ant'
16
+ end
17
+
18
+ def test_report
19
+ report.dir('test')
20
+ end
21
+
22
+ def coverage_report
23
+ report.dir('coverage')
24
+ end
25
+
26
+ def for_test(name)
27
+ @test = JUnitAntTest.new(self, name)
28
+ self
29
+ end
30
+
31
+ def for_tests(pattern)
32
+ @test = JUnitAntBatchTest.new(self, pattern)
33
+ self
34
+ end
35
+
36
+ def with_coverage(jar)
37
+ if (jar.basename.include?('cobertura'))
38
+ @coverage = CobertunaCoverage.new(jar, project)
39
+ else
40
+ raise "do not know how to set up coverage tasks for #{jar}"
41
+ end
42
+ self
43
+ end
44
+
45
+ def generate(buildfile = nil)
46
+ if (test.nil?)
47
+ raise 'test is not specified for junit task'
48
+ end
49
+ buildfile = report.file('junit-ant.xml') unless buildfile
50
+ classpath_id = 'refid'
51
+ @coverage.modify_classpath(classpath)
52
+ buildfile.write do |file|
53
+ file.puts <<BUILD
54
+ <!-- ANT file generated by buildmaste JUnitAnt -->
55
+ <project name="junit-ant" default="junit-ant">
56
+ #{@coverage.task_def}
57
+ #{classpath.to_ant(classpath_id)}
58
+ <target name="#{target_name}">
59
+ #{@coverage.instrument_task}
60
+ <junit printsummary="yes" fork="yes" forkmode="perBatch" errorproperty="error" failureproperty="failure" haltonerror="no" haltonfailure="no">
61
+ <formatter type="xml"/>
62
+ #{@coverage.sysproperty}#{classpath_ref(classpath_id)}#{jvmarg_elements}#{test.to_ant} </junit>
63
+ <junitreport todir="#{test_report}">
64
+ <fileset dir="#{test_report}">
65
+ <include name="TEST-*.xml"/>
66
+ </fileset>
67
+ <report todir="#{test_report}" format="frames"/>
68
+ </junitreport>
69
+ #{@coverage.report_task(coverage_report)}
70
+ <fail message="test failed">
71
+ <condition>
72
+ <or>
73
+ <isset property="fail"/>
74
+ <isset property="error"/>
75
+ </or>
76
+ </condition>
77
+ </fail>
78
+ </target>
79
+ </project>
80
+ BUILD
81
+ end
82
+ buildfile
83
+ end
84
+
85
+ def run(buildfile = nil)
86
+ buildfile = generate(buildfile)
87
+ @coverage.clean_instrumented_files
88
+ test_report.mkdirs
89
+ coverage_report.mkdirs
90
+ AntDriver.new(buildfile).target(target_name)
91
+ end
92
+
93
+ private
94
+
95
+ def classpath_ref(classpath_id)
96
+ if (classpath.empty?)
97
+ ''
98
+ else
99
+ " <classpath refid=\"#{classpath_id}\"/>\n"
100
+ end
101
+ end
102
+
103
+ def jvmarg_elements
104
+ if @jvmargs.empty?
105
+ ''
106
+ else
107
+ buffer = StringIO.new
108
+ @jvmargs.each {|jvm| buffer << " <jvmarg line=\"#{jvm}\"/>\n"}
109
+ buffer.string
110
+ end
111
+ end
112
+ end
113
+
114
+ class JUnitAntTest
115
+ attr_reader :name
116
+
117
+ def initialize(junit, name)
118
+ @name = name
119
+ @junit = junit
120
+ end
121
+
122
+ def to_ant
123
+ return <<RESULT
124
+ <test name="#{name}" todir="#{@junit.test_report}"/>
125
+ RESULT
126
+ end
127
+ end
128
+
129
+ class JUnitAntBatchTest
130
+ def initialize(junit, pattern)
131
+ @junit = junit
132
+ @pattern = pattern
133
+ end
134
+
135
+ def to_ant
136
+ return <<RESULT
137
+ <batchtest fork="yes" todir="#{@junit.test_report}">
138
+ <fileset dir="#{@junit.project.test.src}">
139
+ <include name="**/#{@pattern}"/>
140
+ </fileset>
141
+ </batchtest>
142
+ RESULT
143
+ end
144
+ end
145
+
146
+ class NilCoverage
147
+ def task_def
148
+ ''
149
+ end
150
+
151
+ def modify_classpath(classpath)
152
+ end
153
+
154
+ def instrument_task
155
+ ''
156
+ end
157
+
158
+ def sysproperty
159
+ ''
160
+ end
161
+
162
+ def report_task(report_dir)
163
+ ''
164
+ end
165
+
166
+ def clean_instrumented_files
167
+ ''
168
+ end
169
+ end
170
+
171
+ class CobertunaCoverage
172
+ def initialize(jar, project)
173
+ @jar = jar
174
+ @project = project
175
+ @instrumented_dir = @project.output.dir('instrumented')
176
+ @datafile = @project.output.file('cobertuna.ser')
177
+ end
178
+
179
+ def task_def
180
+ return <<TASK_DEF
181
+ <path id="coverage">
182
+ <pathelement location="#{@jar}"/>
183
+ <fileset dir="#{@jar.parent.dir('lib')}">
184
+ <include name="**/*.jar"/>
185
+ </fileset>
186
+ </path>
187
+ <taskdef classpathref="coverage" resource="tasks.properties"/>
188
+ TASK_DEF
189
+ end
190
+
191
+ def modify_classpath(classpath)
192
+ classpath.insert @jar
193
+ classpath.insert @instrumented_dir
194
+ end
195
+
196
+ def instrument_task
197
+ return <<RESULT
198
+ <cobertura-instrument todir="#{@instrumented_dir}" datafile="#{@datafile}">
199
+ <fileset dir="#{@project.prod.output}">
200
+ <include name="**/*.class"/>
201
+ </fileset>
202
+ </cobertura-instrument>
203
+ <copy todir="#{@instrumented_dir}">
204
+ <fileset dir="#{@project.prod.output}" excludes="**/*.class"/>
205
+ </copy>
206
+ RESULT
207
+ end
208
+
209
+ def sysproperty
210
+ return <<SYSPROPERTY
211
+ <sysproperty key="net.sourceforge.cobertura.datafile" file="#{@datafile}" />
212
+ SYSPROPERTY
213
+ end
214
+
215
+ def report_task(report_dir)
216
+ return <<REPORT
217
+ <cobertura-report srcdir="#{@project.src}" destdir="#{report_dir}" datafile="#{@datafile}"/>
218
+ REPORT
219
+ end
220
+
221
+ def clean_instrumented_files
222
+ @instrumented_dir.delete
223
+ end
224
+ end
225
+
226
+ end