realityforge-buildr 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.md +3 -0
  6. data/Rakefile +50 -0
  7. data/addon/buildr/checkstyle-report.xsl +104 -0
  8. data/addon/buildr/checkstyle.rb +254 -0
  9. data/addon/buildr/git_auto_version.rb +36 -0
  10. data/addon/buildr/gpg.rb +90 -0
  11. data/addon/buildr/gwt.rb +413 -0
  12. data/addon/buildr/jacoco.rb +161 -0
  13. data/addon/buildr/pmd.rb +185 -0
  14. data/addon/buildr/single_intermediate_layout.rb +71 -0
  15. data/addon/buildr/spotbugs.rb +265 -0
  16. data/addon/buildr/top_level_generate_dir.rb +37 -0
  17. data/addon/buildr/wsgen.rb +192 -0
  18. data/bin/buildr +20 -0
  19. data/buildr.gemspec +61 -0
  20. data/lib/buildr.rb +86 -0
  21. data/lib/buildr/core/application.rb +705 -0
  22. data/lib/buildr/core/assets.rb +96 -0
  23. data/lib/buildr/core/build.rb +587 -0
  24. data/lib/buildr/core/common.rb +167 -0
  25. data/lib/buildr/core/compile.rb +599 -0
  26. data/lib/buildr/core/console.rb +124 -0
  27. data/lib/buildr/core/doc.rb +275 -0
  28. data/lib/buildr/core/environment.rb +128 -0
  29. data/lib/buildr/core/filter.rb +405 -0
  30. data/lib/buildr/core/help.rb +114 -0
  31. data/lib/buildr/core/progressbar.rb +161 -0
  32. data/lib/buildr/core/project.rb +994 -0
  33. data/lib/buildr/core/test.rb +776 -0
  34. data/lib/buildr/core/transports.rb +456 -0
  35. data/lib/buildr/core/util.rb +77 -0
  36. data/lib/buildr/ide/idea.rb +1664 -0
  37. data/lib/buildr/java/commands.rb +230 -0
  38. data/lib/buildr/java/compiler.rb +85 -0
  39. data/lib/buildr/java/custom_pom.rb +300 -0
  40. data/lib/buildr/java/doc.rb +62 -0
  41. data/lib/buildr/java/packaging.rb +393 -0
  42. data/lib/buildr/java/pom.rb +191 -0
  43. data/lib/buildr/java/test_result.rb +54 -0
  44. data/lib/buildr/java/tests.rb +111 -0
  45. data/lib/buildr/packaging/archive.rb +586 -0
  46. data/lib/buildr/packaging/artifact.rb +1113 -0
  47. data/lib/buildr/packaging/artifact_namespace.rb +1010 -0
  48. data/lib/buildr/packaging/artifact_search.rb +138 -0
  49. data/lib/buildr/packaging/package.rb +237 -0
  50. data/lib/buildr/packaging/version_requirement.rb +189 -0
  51. data/lib/buildr/packaging/zip.rb +189 -0
  52. data/lib/buildr/packaging/ziptask.rb +387 -0
  53. data/lib/buildr/version.rb +18 -0
  54. data/rakelib/release.rake +99 -0
  55. data/spec/addon/checkstyle_spec.rb +58 -0
  56. data/spec/core/application_spec.rb +576 -0
  57. data/spec/core/build_spec.rb +922 -0
  58. data/spec/core/common_spec.rb +670 -0
  59. data/spec/core/compile_spec.rb +656 -0
  60. data/spec/core/console_spec.rb +65 -0
  61. data/spec/core/doc_spec.rb +194 -0
  62. data/spec/core/extension_spec.rb +200 -0
  63. data/spec/core/project_spec.rb +736 -0
  64. data/spec/core/test_spec.rb +1131 -0
  65. data/spec/core/transport_spec.rb +452 -0
  66. data/spec/core/util_spec.rb +154 -0
  67. data/spec/ide/idea_spec.rb +1952 -0
  68. data/spec/java/commands_spec.rb +79 -0
  69. data/spec/java/compiler_spec.rb +274 -0
  70. data/spec/java/custom_pom_spec.rb +165 -0
  71. data/spec/java/doc_spec.rb +55 -0
  72. data/spec/java/packaging_spec.rb +786 -0
  73. data/spec/java/pom_spec.rb +162 -0
  74. data/spec/java/test_coverage_helper.rb +257 -0
  75. data/spec/java/tests_spec.rb +224 -0
  76. data/spec/packaging/archive_spec.rb +686 -0
  77. data/spec/packaging/artifact_namespace_spec.rb +757 -0
  78. data/spec/packaging/artifact_spec.rb +1351 -0
  79. data/spec/packaging/packaging_helper.rb +63 -0
  80. data/spec/packaging/packaging_spec.rb +690 -0
  81. data/spec/sandbox.rb +166 -0
  82. data/spec/spec_helpers.rb +420 -0
  83. data/spec/version_requirement_spec.rb +145 -0
  84. data/spec/xpath_matchers.rb +123 -0
  85. metadata +295 -0
@@ -0,0 +1,161 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ # Initial support for JaCoCo coverage reports.
18
+ module JaCoCo
19
+ class << self
20
+ def agent_spec
21
+ %w(org.jacoco:org.jacoco.agent:jar:runtime:0.8.6)
22
+ end
23
+
24
+ def dependencies
25
+ %w[
26
+ args4j:args4j:jar:2.0.28
27
+ org.jacoco:org.jacoco.report:jar:0.8.6
28
+ org.jacoco:org.jacoco.core:jar:0.8.6
29
+ org.jacoco:org.jacoco.cli:jar:0.8.6
30
+ org.ow2.asm:asm:jar:8.0.1
31
+ org.ow2.asm:asm-commons:jar:8.0.1
32
+ org.ow2.asm:asm-tree:jar:8.0.1
33
+ org.ow2.asm:asm-analysis:jar:8.0.1
34
+ org.ow2.asm:asm-util:jar:8.0.1
35
+ ]
36
+ end
37
+
38
+ def jacoco_report(execution_files, class_paths, source_paths, options = {})
39
+
40
+ xml_output_file = options[:xml_output_file]
41
+ csv_output_file = options[:csv_output_file]
42
+ html_output_directory = options[:html_output_directory]
43
+
44
+ Buildr.artifacts(self.dependencies).each { |a| a.invoke if a.respond_to?(:invoke) }
45
+
46
+ args = []
47
+ args << 'report'
48
+ args += execution_files
49
+ class_paths.each do |class_path|
50
+ args << '--classfiles' << class_path
51
+ end
52
+ args << '--csv' << csv_output_file if csv_output_file
53
+ args << '--encoding' << 'UTF-8'
54
+ args << '--html' << html_output_directory if html_output_directory
55
+ source_paths.each do |source_path|
56
+ args << '--sourcefiles' << source_path
57
+ end
58
+ args << '--xml' << xml_output_file if xml_output_file
59
+
60
+ Java::Commands.java 'org.jacoco.cli.internal.Main', *(args + [{ :classpath => Buildr.artifacts(self.dependencies), :properties => options[:properties], :java_args => options[:java_args] }])
61
+ end
62
+ end
63
+
64
+ class Config
65
+ attr_writer :enabled
66
+
67
+ def enabled?
68
+ @enabled.nil? ? true : @enabled
69
+ end
70
+
71
+ attr_accessor :destfile
72
+
73
+ attr_writer :output
74
+
75
+ def output
76
+ @output ||= 'file'
77
+ end
78
+
79
+ attr_accessor :sessionid
80
+ attr_accessor :address
81
+ attr_accessor :port
82
+ attr_accessor :classdumpdir
83
+ attr_accessor :dumponexit
84
+ attr_accessor :append
85
+ attr_accessor :exclclassloader
86
+
87
+ def includes
88
+ @includes ||= []
89
+ end
90
+
91
+ def excludes
92
+ @excludes ||= []
93
+ end
94
+
95
+ protected
96
+
97
+ def initialize(destfile)
98
+ @destfile = destfile
99
+ end
100
+ end
101
+
102
+ module ProjectExtension
103
+ include Extension
104
+
105
+ def jacoco
106
+ @jacoco ||= Buildr::JaCoCo::Config.new(project._(:reports, :jacoco, 'jacoco.cov'))
107
+ end
108
+
109
+ after_define do |project|
110
+ unless project.test.compile.target.nil? || !project.jacoco.enabled?
111
+ project.test.setup do
112
+ agent_jar = Buildr.artifacts(Buildr::JaCoCo.agent_spec).each(&:invoke).map(&:to_s).join('')
113
+ options = []
114
+ %w(destfile append exclclassloader sessionid dumponexit output address port classdumpdir).each do |option|
115
+ value = project.jacoco.send(option.to_sym)
116
+ options << "#{option}=#{value}" unless value.nil?
117
+ end
118
+ options << "includes=#{project.jacoco.includes.join(':')}" unless project.jacoco.includes.empty?
119
+ options << "excludes=#{project.jacoco.excludes.join(':')}" unless project.jacoco.excludes.empty?
120
+
121
+ agent_config = "-javaagent:#{agent_jar}=#{options.join(',')}"
122
+ existing = project.test.options[:java_args] || []
123
+ project.test.options[:java_args] = (existing.is_a?(Array) ? existing : [existing]) + [agent_config]
124
+ end
125
+ end
126
+ end
127
+ namespace 'jacoco' do
128
+ desc 'Generate JaCoCo reports.'
129
+ task 'report' do
130
+
131
+ execution_files = []
132
+ class_paths = []
133
+ source_paths = []
134
+ Buildr.projects.select { |p| p.jacoco.enabled? }.each do |project|
135
+ execution_files << project.jacoco.destfile if File.exist?(project.jacoco.destfile)
136
+ target = project.compile.target.to_s
137
+ class_paths << target.to_s if File.exist?(target)
138
+ project.compile.sources.flatten.map(&:to_s).each do |src|
139
+ source_paths << src.to_s if File.exist?(src)
140
+ end
141
+ end
142
+
143
+ project = Buildr.projects[0].root_project
144
+
145
+ options = {}
146
+ options[:xml_output_file] = project._(:reports, :jacoco, 'jacoco.xml')
147
+ options[:csv_output_file] = project._(:reports, :jacoco, 'jacoco.csv')
148
+ options[:html_output_directory] = project._(:reports, :jacoco, 'docs')
149
+
150
+ unless execution_files.empty?
151
+ Buildr::JaCoCo.jacoco_report(execution_files, class_paths, source_paths, options)
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ class Buildr::Project
160
+ include Buildr::JaCoCo::ProjectExtension
161
+ end
@@ -0,0 +1,185 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ # Provides the <code>pmd:xml</code> and <code>pmd:html</code> tasks.
18
+ #
19
+ # Require explicitly using <code>require 'buildr/pmd'</code>.
20
+ module Pmd
21
+
22
+ class << self
23
+
24
+ # The specs for requirements
25
+ def dependencies
26
+ %w(
27
+ net.sourceforge.pmd:pmd-core:jar:6.11.0
28
+ net.sourceforge.pmd:pmd-java:jar:6.11.0
29
+ net.sourceforge.pmd:pmd-java8:jar:6.11.0
30
+ jaxen:jaxen:jar:1.1.6
31
+ commons-io:commons-io:jar:2.6
32
+ com.beust:jcommander:jar:1.72
33
+ org.ow2.asm:asm:jar:7.1
34
+ com.google.code.gson:gson:jar:2.8.5
35
+ net.java.dev.javacc:javacc:jar:5.0
36
+ net.sourceforge.saxon:saxon:jar:9.1.0.8
37
+ org.apache.commons:commons-lang3:jar:3.8.1
38
+ org.antlr:antlr4-runtime:jar:4.7
39
+ )
40
+ end
41
+
42
+ def pmd(rule_set_files, format, output_file_prefix, source_paths, options = {})
43
+ dependencies = (options[:dependencies] || []) + self.dependencies
44
+ cp = Buildr.artifacts(dependencies).each(&:invoke).map(&:to_s)
45
+ (options[:rule_set_paths] || []).each {|p| cp << p}
46
+
47
+ rule_sets = rule_set_files.dup
48
+
49
+ Buildr.artifacts(options[:rule_set_artifacts] || []).each do |artifact|
50
+ a = artifact.to_s
51
+ dirname = File.dirname(a)
52
+ rule_sets << a[dirname.length + 1, a.length]
53
+ cp << File.dirname(a)
54
+ artifact.invoke
55
+ end
56
+
57
+ puts 'PMD: Analyzing source code...'
58
+ mkdir_p File.dirname(output_file_prefix)
59
+
60
+ args = []
61
+ args << '-no-cache'
62
+ args << '-shortnames'
63
+ args << '-rulesets' << rule_sets.join(',')
64
+ args << '-format' << format
65
+ args << '-reportfile' << "#{output_file_prefix}.#{format}"
66
+
67
+ files = []
68
+ source_paths.each do |src|
69
+ files += Dir["#{src}/**/*.java"] if File.directory?(src)
70
+ end
71
+ files = files.sort.uniq
72
+
73
+ Tempfile.open('pmd') do |tmp|
74
+ tmp.write files.join(',')
75
+ args << '-filelist' << tmp.path.to_s
76
+ end
77
+
78
+ begin
79
+ Java::Commands.java 'net.sourceforge.pmd.PMD', *(args + [{:classpath => cp, :properties => options[:properties], :java_args => options[:java_args]}])
80
+ rescue Exception => e
81
+ raise e if options[:fail_on_error]
82
+ end
83
+ end
84
+ end
85
+
86
+ class Config
87
+
88
+ attr_writer :enabled
89
+
90
+ def enabled?
91
+ !!@enabled
92
+ end
93
+
94
+ attr_writer :rule_set_files
95
+
96
+ def rule_set_files
97
+ @rule_set_files ||= (self.rule_set_artifacts.empty? ? %w(rulesets/java/basic.xml rulesets/java/imports.xml rulesets/java/unusedcode.xml rulesets/java/finalizers.xml rulesets/java/braces.xml) : [])
98
+ end
99
+
100
+ # Support specification of rule sets that are distributed as part of a maven repository
101
+ def rule_set_artifacts
102
+ @rule_set_artifacts ||= []
103
+ end
104
+
105
+ attr_writer :rule_set_paths
106
+
107
+ def rule_set_paths
108
+ @rule_set_paths ||= []
109
+ end
110
+
111
+ attr_writer :report_dir
112
+
113
+ def report_dir
114
+ @report_dir || project._(:reports, :pmd)
115
+ end
116
+
117
+ attr_writer :output_file_prefix
118
+
119
+ def output_file_prefix
120
+ @output_file_prefix || "#{self.report_dir}/pmd"
121
+ end
122
+
123
+ def source_paths
124
+ @source_paths ||= [self.project.compile.sources, self.project.test.compile.sources].flatten.compact
125
+ end
126
+
127
+ # An array of paths that should be excluded no matter how they are added to pmd
128
+ def exclude_paths
129
+ @source_paths ||= []
130
+ end
131
+
132
+ # An array of additional projects to scan for main and test sources
133
+ attr_writer :additional_project_names
134
+
135
+ def additional_project_names
136
+ @additional_project_names ||= []
137
+ end
138
+
139
+ def flat_source_paths
140
+ paths = source_paths.dup
141
+
142
+ self.additional_project_names.each do |project_name|
143
+ p = self.project.project(project_name)
144
+ paths << [p.compile.sources, p.test.compile.sources].flatten.compact
145
+ end
146
+
147
+ paths.flatten.select{|p|!self.exclude_paths.include?(p)}.compact
148
+ end
149
+
150
+ protected
151
+
152
+ def initialize(project)
153
+ @project = project
154
+ end
155
+
156
+ attr_reader :project
157
+ end
158
+
159
+ module ProjectExtension
160
+ include Extension
161
+
162
+ def pmd
163
+ @pmd ||= Buildr::Pmd::Config.new(project)
164
+ end
165
+
166
+ after_define do |project|
167
+ if project.pmd.enabled?
168
+ desc 'Generate pmd xml report.'
169
+ project.task('pmd:xml') do
170
+ Buildr::Pmd.pmd(project.pmd.rule_set_files, 'xml', project.pmd.output_file_prefix, project.pmd.flat_source_paths, :rule_set_paths => project.pmd.rule_set_paths, :rule_set_artifacts => project.pmd.rule_set_artifacts)
171
+ end
172
+
173
+ desc 'Generate pmd html report.'
174
+ project.task('pmd:html') do
175
+ Buildr::Pmd.pmd(project.pmd.rule_set_files, 'html', project.pmd.output_file_prefix, project.pmd.flat_source_paths, :rule_set_paths => project.pmd.rule_set_paths, :rule_set_artifacts => project.pmd.rule_set_artifacts)
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ class Buildr::Project
184
+ include Buildr::Pmd::ProjectExtension
185
+ end
@@ -0,0 +1,71 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr #nodoc
17
+ class Project #nodoc
18
+ class << self
19
+
20
+ alias :original_define :define
21
+
22
+ # Monkey patch the built-in define so that there is a single root directory for
23
+ # all of the generated artifacts within a project hierarchy.
24
+ #
25
+ def define(name, properties = nil, &block) #:yields:project
26
+
27
+ properties = properties.nil? ? {} : properties.dup
28
+
29
+ parent_name = name.split(':')[0...-1]
30
+ parent = parent_name.empty? ? nil : Buildr.application.lookup(parent_name.join(':'))
31
+
32
+ # Follow the same algorithm as in project code
33
+ if properties[:base_dir]
34
+ base_dir = properties[:base_dir]
35
+ elsif parent
36
+ base_dir = File.expand_path(name.split(':').last, parent.base_dir)
37
+ else
38
+ base_dir = Dir.pwd
39
+ end
40
+
41
+ # The top directory is the base directory of the root project
42
+ top_dir = base_dir
43
+ while parent
44
+ top_dir = parent.base_dir
45
+ parent = parent.parent
46
+ end
47
+
48
+ target_dir = "#{top_dir}/target/#{name.gsub(':', '_')}"
49
+ reports_dir = "#{top_dir}/reports/#{name.gsub(':', '_')}"
50
+ target_dir = ::Buildr::Util.relative_path(target_dir, File.expand_path(base_dir))
51
+ reports_dir = ::Buildr::Util.relative_path(reports_dir, File.expand_path(base_dir))
52
+
53
+ properties[:layout] = Buildr::Layout::Default.new unless properties[:layout]
54
+ properties[:layout][:target] = target_dir
55
+ properties[:layout][:reports] = reports_dir
56
+ properties[:layout][:target, :main] = target_dir
57
+
58
+ Project.original_define(name, properties) do
59
+ project.instance_eval &block
60
+ if top_dir == base_dir && project.iml?
61
+ project.iml.excluded_directories << "#{base_dir}/target"
62
+ project.iml.excluded_directories << "#{base_dir}/reports"
63
+ clean { rm_rf "#{base_dir}/target" }
64
+ clean { rm_rf "#{base_dir}/reports" }
65
+ end
66
+ project
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,265 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ # Provides the <code>spotbugs:html</code> and <code>spotbugs:xml</code> tasks.
18
+ # Require explicitly using <code>require "buildr/spotbugs"</code>.
19
+ module Spotbugs
20
+
21
+ class << self
22
+
23
+ # The specs for requirements
24
+ def dependencies
25
+ %w(
26
+ com.github.spotbugs:spotbugs:jar:4.2.1
27
+ com.github.spotbugs:spotbugs-annotations:jar:4.2.1
28
+ com.google.code.findbugs:jsr305:jar:3.0.2
29
+ net.jcip:jcip-annotations:jar:1.0
30
+ org.apache.bcel:bcel:jar:6.5.0
31
+ org.apache.commons:commons-lang3:jar:3.11
32
+ org.apache.commons:commons-text:jar:1.9
33
+ org.dom4j:dom4j:jar:2.1.3
34
+ org.json:json:jar:20201115
35
+ org.ow2.asm:asm:jar:9.0
36
+ org.ow2.asm:asm-analysis:jar:9.0
37
+ org.ow2.asm:asm-tree:jar:9.0
38
+ org.ow2.asm:asm-commons:jar:9.0
39
+ org.ow2.asm:asm-util:jar:9.0
40
+ org.slf4j:slf4j-api:jar:1.7.30
41
+ org.slf4j:slf4j-jdk14:jar:1.7.30
42
+ jaxen:jaxen:jar:1.2.0
43
+ net.sf.saxon:Saxon-HE:jar:10.3
44
+ )
45
+ end
46
+
47
+ def fb_contrib_dependencies
48
+ %w(com.mebigfatguy.fb-contrib:fb-contrib:jar:7.4.2.sb)
49
+ end
50
+
51
+ def spotbugs(output_file, source_paths, analyze_paths, options = {})
52
+ plugins = self.fb_contrib_dependencies
53
+ Buildr.artifacts(self.dependencies).each { |a| a.invoke if a.respond_to?(:invoke) }
54
+
55
+ args = []
56
+ args << '-textui'
57
+ packages_to_analyze = options[:packages_to_analyze] || []
58
+ if packages_to_analyze.size > 0
59
+ args << '-onlyAnalyze' << (packages_to_analyze.collect{|p| "#{p}.-"}.join(',') + ':')
60
+ end
61
+ args << '-effort:max'
62
+ args << '-medium'
63
+ args << ('html' == options[:output] ? '-html' : '-xml:withMessages')
64
+ args << '-output' << output_file
65
+ args << '-sourcepath' << source_paths.map(&:to_s).join(File::PATH_SEPARATOR)
66
+ args << '-pluginList' << Buildr.artifacts(plugins).map(&:to_s).join(File::PATH_SEPARATOR)
67
+
68
+ extra_dependencies = (options[:extra_dependencies] || []) + plugins
69
+ if 0 != extra_dependencies.size
70
+ args << '-auxclasspath' << Buildr.artifacts(extra_dependencies).each { |a| a.invoke if a.respond_to?(:invoke) }.map(&:to_s).join(File::PATH_SEPARATOR)
71
+ end
72
+ if options[:exclude_filter]
73
+ args << '-exclude' << options[:exclude_filter]
74
+ end
75
+
76
+ analyze_paths.each do |dep|
77
+ a = dep.is_a?(String) ? file(dep) : dep
78
+ a.invoke
79
+ args << a.to_s
80
+ end
81
+
82
+ mkdir_p File.dirname(output_file)
83
+
84
+ begin
85
+ Java::Commands.java 'edu.umd.cs.findbugs.LaunchAppropriateUI', *(args + [{:classpath => Buildr.artifacts(dependencies), :properties => options[:properties], :java_args => options[:java_args]}])
86
+ rescue Exception => e
87
+ puts e
88
+ raise e if options[:fail_on_error]
89
+ end
90
+ end
91
+ end
92
+
93
+ class Config
94
+
95
+ attr_accessor :enabled
96
+
97
+ def enabled?
98
+ !!@enabled
99
+ end
100
+
101
+ attr_writer :config_directory
102
+
103
+ def config_directory
104
+ @config_directory || project._(:source, :main, :etc, :spotbugs)
105
+ end
106
+
107
+ attr_writer :report_dir
108
+
109
+ def report_dir
110
+ @report_dir || project._(:reports, :spotbugs)
111
+ end
112
+
113
+ attr_writer :fail_on_error
114
+
115
+ def fail_on_error?
116
+ @fail_on_error.nil? ? false : @fail_on_error
117
+ end
118
+
119
+ attr_writer :xml_output_file
120
+
121
+ def xml_output_file
122
+ @xml_output_file || "#{self.report_dir}/spotbugs.xml"
123
+ end
124
+
125
+ attr_writer :html_output_file
126
+
127
+ def html_output_file
128
+ @html_output_file || "#{self.report_dir}/spotbugs.html"
129
+ end
130
+
131
+ attr_writer :filter_file
132
+
133
+ def filter_file
134
+ @filter_file || "#{self.config_directory}/filter.xml"
135
+ end
136
+
137
+ def properties
138
+ @properties ||= {}
139
+ end
140
+
141
+ attr_writer :java_args
142
+
143
+ def java_args
144
+ @java_args || '-server -Xss1m -Xmx1.4G -Duser.language=en -Duser.region=EN'
145
+ end
146
+
147
+ def packages_to_analyze
148
+ @packages_to_analyze ||= [self.project.java_package_name]
149
+ end
150
+
151
+ def source_paths
152
+ @source_paths ||= [self.project.compile.sources, self.project.test.compile.sources].flatten.compact
153
+ end
154
+
155
+ def analyze_paths
156
+ @analyze_path ||= [self.project.compile.target]
157
+ end
158
+
159
+ def extra_dependencies
160
+ @extra_dependencies ||= [self.project.compile.dependencies, self.project.test.compile.dependencies].flatten.compact
161
+ end
162
+
163
+ # An array of additional projects to scan for main and test sources
164
+ attr_writer :additional_project_names
165
+
166
+ def additional_project_names
167
+ @additional_project_names ||= []
168
+ end
169
+
170
+ def complete_source_paths
171
+ paths = self.source_paths.dup
172
+
173
+ self.additional_project_names.each do |project_name|
174
+ p = self.project.project(project_name)
175
+ paths << [p.compile.sources, p.test.compile.sources].flatten.compact
176
+ end
177
+
178
+ paths.flatten.compact
179
+ end
180
+
181
+ def complete_analyze_paths
182
+ paths = self.analyze_paths.dup
183
+
184
+ self.additional_project_names.each do |project_name|
185
+ paths << self.project.project(project_name).compile.target
186
+ end
187
+
188
+ paths.flatten.compact
189
+ end
190
+
191
+ def complete_extra_dependencies
192
+ deps = self.extra_dependencies.dup
193
+
194
+ self.additional_project_names.each do |project_name|
195
+ p = self.project.project(project_name)
196
+ deps << [p.compile.dependencies, p.test.compile.dependencies].flatten.compact
197
+ end
198
+
199
+ deps.flatten.compact
200
+ end
201
+
202
+ protected
203
+
204
+ def initialize(project)
205
+ @project = project
206
+ end
207
+
208
+ attr_reader :project
209
+ end
210
+
211
+ module ProjectExtension
212
+ include Extension
213
+
214
+ def spotbugs
215
+ @spotbugs ||= Buildr::Spotbugs::Config.new(project)
216
+ end
217
+
218
+ after_define do |project|
219
+ if project.spotbugs.enabled?
220
+ desc 'Generate spotbugs xml report.'
221
+ project.task('spotbugs:xml') do
222
+ puts 'Spotbugs: Analyzing source code...'
223
+ options =
224
+ {
225
+ :packages_to_analyze => project.spotbugs.packages_to_analyze,
226
+ :properties => project.spotbugs.properties,
227
+ :fail_on_error => project.spotbugs.fail_on_error?,
228
+ :extra_dependencies => project.spotbugs.complete_extra_dependencies
229
+ }
230
+ options[:exclude_filter] = project.spotbugs.filter_file if File.exist?(project.spotbugs.filter_file)
231
+ options[:output] = 'xml:withMessages'
232
+
233
+ Buildr::Spotbugs.spotbugs(project.spotbugs.xml_output_file,
234
+ project.spotbugs.complete_source_paths,
235
+ project.spotbugs.complete_analyze_paths,
236
+ options)
237
+ end
238
+
239
+ desc 'Generate spotbugs html report.'
240
+ project.task('spotbugs:html') do
241
+ puts 'Spotbugs: Analyzing source code...'
242
+ options =
243
+ {
244
+ :packages_to_analyze => project.spotbugs.packages_to_analyze,
245
+ :properties => project.spotbugs.properties,
246
+ :fail_on_error => project.spotbugs.fail_on_error?,
247
+ :extra_dependencies => project.spotbugs.complete_extra_dependencies
248
+ }
249
+ options[:exclude_filter] = project.spotbugs.filter_file if File.exist?(project.spotbugs.filter_file)
250
+ options[:output] = 'html'
251
+
252
+ Buildr::Spotbugs.spotbugs(project.spotbugs.html_output_file,
253
+ project.spotbugs.complete_source_paths,
254
+ project.spotbugs.complete_analyze_paths,
255
+ options)
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ class Buildr::Project
264
+ include Buildr::Spotbugs::ProjectExtension
265
+ end