BuildMaster 1.1.9 → 1.1.12

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 (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