buildr-iidea 0.0.2
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.
- data/LICENSE +176 -0
- data/NOTICE +16 -0
- data/README.rdoc +286 -0
- data/Rakefile +27 -0
- data/buildr-iidea.gemspec +23 -0
- data/lib/buildr/intellij_idea/idea_file.rb +86 -0
- data/lib/buildr/intellij_idea/idea_module.rb +217 -0
- data/lib/buildr/intellij_idea/idea_project.rb +98 -0
- data/lib/buildr/intellij_idea/project_extension.rb +92 -0
- data/lib/buildr_iidea.rb +5 -0
- data/spec/buildr/intellij_idea/clean_spec.rb +38 -0
- data/spec/buildr/intellij_idea/dependency_spec.rb +85 -0
- data/spec/buildr/intellij_idea/extra_modules_spec.rb +24 -0
- data/spec/buildr/intellij_idea/facet_generation_spec.rb +36 -0
- data/spec/buildr/intellij_idea/group_spec.rb +33 -0
- data/spec/buildr/intellij_idea/idea_file_generation_spec.rb +177 -0
- data/spec/buildr/intellij_idea/inform_spec.rb +28 -0
- data/spec/buildr/intellij_idea/initial_components_spec.rb +33 -0
- data/spec/buildr/intellij_idea/module_property_inheritance_spec.rb +27 -0
- data/spec/buildr/intellij_idea/project_extension_spec.rb +19 -0
- data/spec/buildr/intellij_idea/template_spec.rb +234 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +75 -0
- data/spec/xpath_matchers.rb +109 -0
- metadata +97 -0
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
gem_spec = Gem::Specification.load(File.expand_path('buildr-iidea.gemspec', File.dirname(__FILE__)))
|
7
|
+
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
9
|
+
spec.libs << 'lib' << 'spec'
|
10
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
|
15
|
+
desc "Generate RDoc documentation in rdoc/"
|
16
|
+
Rake::RDocTask.new :rdoc do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = gem_spec.name
|
19
|
+
rdoc.options = gem_spec.rdoc_options.clone
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
rdoc.rdoc_files.include gem_spec.extra_rdoc_files
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(gem_spec) do |pkg|
|
25
|
+
pkg.need_zip = true
|
26
|
+
pkg.need_tar = true
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = 'buildr-iidea'
|
3
|
+
spec.version = `git describe`.strip.split('-').first
|
4
|
+
spec.authors = ['Rhett Sutphin', 'Peter Donald']
|
5
|
+
spec.email = ["rhett@detailedbalance.net","peter@realityforge.org"]
|
6
|
+
spec.homepage = "http://github.com/rockninja/buildr-iidea"
|
7
|
+
spec.summary = "Buildr tasks to generate Intellij IDEA project files"
|
8
|
+
spec.description = <<-TEXT
|
9
|
+
This is a buildr extension that provides tasks to generate Intellij IDEA
|
10
|
+
project files. The iidea task generates the project files based on the
|
11
|
+
settings of each project and extension specific settings.
|
12
|
+
TEXT
|
13
|
+
|
14
|
+
spec.files = Dir['{lib,spec}/**/*', '*.gemspec'] +
|
15
|
+
['LICENSE', 'NOTICE', 'README.rdoc', 'Rakefile']
|
16
|
+
spec.require_paths = ['lib']
|
17
|
+
|
18
|
+
spec.has_rdoc = true
|
19
|
+
spec.extra_rdoc_files = 'README.rdoc', 'LICENSE', 'NOTICE'
|
20
|
+
spec.rdoc_options = '--title', "#{spec.name} #{spec.version}", '--main', 'README.rdoc'
|
21
|
+
|
22
|
+
spec.post_install_message = "Thanks for installing the Intellij IDEA extension for Buildr"
|
23
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Buildr
|
2
|
+
module IntellijIdea
|
3
|
+
# Abstract base class for IdeaModule and IdeaProject
|
4
|
+
class IdeaFile
|
5
|
+
DEFAULT_SUFFIX = ""
|
6
|
+
|
7
|
+
attr_reader :buildr_project
|
8
|
+
attr_writer :suffix
|
9
|
+
attr_writer :id
|
10
|
+
attr_accessor :template
|
11
|
+
|
12
|
+
def suffix
|
13
|
+
@suffix ||= DEFAULT_SUFFIX
|
14
|
+
end
|
15
|
+
|
16
|
+
def filename
|
17
|
+
buildr_project.path_to("#{name}.#{extension}")
|
18
|
+
end
|
19
|
+
|
20
|
+
def id
|
21
|
+
@id ||= buildr_project.name.split(':').last
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_component(name, attrs = {}, &xml)
|
25
|
+
self.components << create_component(name, attrs, &xml)
|
26
|
+
end
|
27
|
+
|
28
|
+
def write(f)
|
29
|
+
document.write f
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def name
|
35
|
+
"#{self.id}#{suffix}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_component(name, attrs = {})
|
39
|
+
target = StringIO.new
|
40
|
+
Builder::XmlMarkup.new(:target => target, :indent => 2).component(attrs.merge({ :name => name })) do |xml|
|
41
|
+
yield xml if block_given?
|
42
|
+
end
|
43
|
+
REXML::Document.new(target.string).root
|
44
|
+
end
|
45
|
+
|
46
|
+
def components
|
47
|
+
@components ||= self.default_components.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_document(filename)
|
51
|
+
REXML::Document.new(File.read(filename))
|
52
|
+
end
|
53
|
+
|
54
|
+
def document
|
55
|
+
if File.exist?(self.filename)
|
56
|
+
doc = load_document(self.filename)
|
57
|
+
else
|
58
|
+
doc = base_document
|
59
|
+
inject_components( doc, self.initial_components )
|
60
|
+
end
|
61
|
+
if self.template
|
62
|
+
template_doc = load_document(self.template)
|
63
|
+
REXML::XPath.each(template_doc, "//component") do |element|
|
64
|
+
inject_component(doc, element)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
inject_components( doc, self.components )
|
68
|
+
doc
|
69
|
+
end
|
70
|
+
|
71
|
+
def inject_components(doc, components)
|
72
|
+
components.each do |component|
|
73
|
+
# execute deferred components
|
74
|
+
component = component.call if Proc === component
|
75
|
+
inject_component(doc, component) if component
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# replace overridden component (if any) with specified component
|
80
|
+
def inject_component(doc, component)
|
81
|
+
doc.root.delete_element("//component[@name='#{component.attributes['name']}']")
|
82
|
+
doc.root.add_element component
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module Buildr
|
2
|
+
module IntellijIdea
|
3
|
+
class IdeaModule < IdeaFile
|
4
|
+
DEFAULT_TYPE = "JAVA_MODULE"
|
5
|
+
DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE = "M2_REPO"
|
6
|
+
MODULE_DIR_URL = "file://$MODULE_DIR$"
|
7
|
+
|
8
|
+
attr_writer :buildr_project
|
9
|
+
attr_accessor :type
|
10
|
+
attr_accessor :local_repository_env_override
|
11
|
+
attr_accessor :group
|
12
|
+
attr_reader :facets
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@type = DEFAULT_TYPE
|
16
|
+
@local_repository_env_override = DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE
|
17
|
+
@facets = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def buildr_project=(buildr_project)
|
21
|
+
@id = nil
|
22
|
+
@facets = []
|
23
|
+
@buildr_project = buildr_project
|
24
|
+
end
|
25
|
+
|
26
|
+
def extension
|
27
|
+
"iml"
|
28
|
+
end
|
29
|
+
|
30
|
+
def main_source_directories
|
31
|
+
@main_source_directories ||= [
|
32
|
+
buildr_project.compile.sources,
|
33
|
+
buildr_project.resources.sources
|
34
|
+
].flatten.compact
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_source_directories
|
38
|
+
@test_source_directories ||= [
|
39
|
+
buildr_project.test.compile.sources,
|
40
|
+
buildr_project.test.resources.sources
|
41
|
+
].flatten.compact
|
42
|
+
end
|
43
|
+
|
44
|
+
def excluded_directories
|
45
|
+
@excluded_directories ||= [
|
46
|
+
buildr_project.resources.target,
|
47
|
+
buildr_project.test.resources.target,
|
48
|
+
buildr_project.path_to(:target, :main),
|
49
|
+
buildr_project.path_to(:target, :test),
|
50
|
+
buildr_project.path_to(:reports)
|
51
|
+
].flatten.compact
|
52
|
+
end
|
53
|
+
|
54
|
+
def main_output_dir
|
55
|
+
buildr_project.compile.target || buildr_project.path_to(:target, :main, 'idea')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_output_dir
|
59
|
+
buildr_project.test.compile.target || buildr_project.path_to(:target, :test, 'idea')
|
60
|
+
end
|
61
|
+
|
62
|
+
def resources
|
63
|
+
[buildr_project.test.resources.target, buildr_project.resources.target].compact
|
64
|
+
end
|
65
|
+
|
66
|
+
def main_dependencies
|
67
|
+
buildr_project.compile.dependencies.map(&:to_s)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_dependencies
|
71
|
+
buildr_project.test.compile.dependencies.map(&:to_s) - [ buildr_project.compile.target.to_s ]
|
72
|
+
end
|
73
|
+
|
74
|
+
def base_directory
|
75
|
+
buildr_project.path_to
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_facet(name, type)
|
79
|
+
target = StringIO.new
|
80
|
+
Builder::XmlMarkup.new(:target => target, :indent => 2).facet(:name => name, :type => type) do |xml|
|
81
|
+
yield xml if block_given?
|
82
|
+
end
|
83
|
+
self.facets << REXML::Document.new(target.string).root
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
|
88
|
+
def base_document
|
89
|
+
target = StringIO.new
|
90
|
+
Builder::XmlMarkup.new(:target => target).module(:version => "4", :relativePaths => "true", :type => self.type)
|
91
|
+
REXML::Document.new(target.string)
|
92
|
+
end
|
93
|
+
|
94
|
+
def initial_components
|
95
|
+
[]
|
96
|
+
end
|
97
|
+
|
98
|
+
def default_components
|
99
|
+
[
|
100
|
+
lambda { module_root_component },
|
101
|
+
lambda { facet_component }
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
def facet_component
|
106
|
+
return nil if self.facets.empty?
|
107
|
+
fm = self.create_component("FacetManager")
|
108
|
+
self.facets.each do |facet|
|
109
|
+
fm.add_element facet
|
110
|
+
end
|
111
|
+
fm
|
112
|
+
end
|
113
|
+
|
114
|
+
def module_root_component
|
115
|
+
m2repo = Buildr::Repositories.instance.local
|
116
|
+
|
117
|
+
create_component("NewModuleRootManager", "inherit-compiler-output" => "false") do |xml|
|
118
|
+
generate_compile_output(xml)
|
119
|
+
generate_content(xml)
|
120
|
+
generate_initial_order_entries(xml)
|
121
|
+
|
122
|
+
# Note: Use the test classpath since IDEA compiles both "main" and "test" classes using the same classpath
|
123
|
+
self.test_dependencies.each do |dependency_path|
|
124
|
+
export = self.main_dependencies.include?(dependency_path)
|
125
|
+
project_for_dependency = Buildr.projects.detect do |project|
|
126
|
+
project.packages.detect { |pkg| pkg.to_s == dependency_path }
|
127
|
+
end
|
128
|
+
if project_for_dependency
|
129
|
+
if project_for_dependency.iml?
|
130
|
+
generate_project_dependency( xml, project_for_dependency.iml.name, export )
|
131
|
+
end
|
132
|
+
next
|
133
|
+
elsif dependency_path.to_s.index(m2repo) == 0
|
134
|
+
entry_path = dependency_path
|
135
|
+
unless self.local_repository_env_override.nil?
|
136
|
+
entry_path = entry_path.sub(m2repo, "$#{self.local_repository_env_override}$")
|
137
|
+
end
|
138
|
+
generate_module_lib(xml, "jar://#{entry_path}!/", export )
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
self.resources.each do |resource|
|
143
|
+
generate_module_lib(xml, "#{MODULE_DIR_URL}/#{relative(resource.to_s)}", true)
|
144
|
+
end
|
145
|
+
|
146
|
+
xml.orderEntryProperties
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def relative(path)
|
151
|
+
Util.relative_path(File.expand_path(path.to_s), self.base_directory)
|
152
|
+
end
|
153
|
+
|
154
|
+
def generate_compile_output(xml)
|
155
|
+
xml.output(:url => "#{MODULE_DIR_URL}/#{relative(self.main_output_dir.to_s)}")
|
156
|
+
xml.tag!("output-test", :url => "#{MODULE_DIR_URL}/#{relative(self.test_output_dir.to_s)}")
|
157
|
+
xml.tag!("exclude-output")
|
158
|
+
end
|
159
|
+
|
160
|
+
def generate_content(xml)
|
161
|
+
xml.content(:url => MODULE_DIR_URL) do
|
162
|
+
# Source folders
|
163
|
+
{
|
164
|
+
:main => self.main_source_directories,
|
165
|
+
:test => self.test_source_directories
|
166
|
+
}.each do |kind, directories|
|
167
|
+
directories.map { |dir| relative(dir) }.compact.sort.uniq.each do |dir|
|
168
|
+
xml.sourceFolder :url => "#{MODULE_DIR_URL}/#{dir}", :isTestSource => (kind == :test ? 'true' : 'false')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Exclude target directories
|
173
|
+
self.net_excluded_directories.sort.each do |dir|
|
174
|
+
xml.excludeFolder :url => "#{MODULE_DIR_URL}/#{dir}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def generate_initial_order_entries(xml)
|
180
|
+
xml.orderEntry :type => "sourceFolder", :forTests => "false"
|
181
|
+
xml.orderEntry :type => "inheritedJdk"
|
182
|
+
end
|
183
|
+
|
184
|
+
def generate_project_dependency(xml, other_project, export = true)
|
185
|
+
attribs = {:type => 'module', "module-name" => other_project}
|
186
|
+
attribs[:exported] = '' if export
|
187
|
+
xml.orderEntry attribs
|
188
|
+
end
|
189
|
+
|
190
|
+
def generate_module_lib(xml, path, export)
|
191
|
+
attribs = {:type => 'module-library'}
|
192
|
+
attribs[:exported] = '' if export
|
193
|
+
xml.orderEntry attribs do
|
194
|
+
xml.library do
|
195
|
+
xml.CLASSES do
|
196
|
+
xml.root :url => path
|
197
|
+
end
|
198
|
+
xml.JAVADOC
|
199
|
+
xml.SOURCES
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Don't exclude things that are subdirectories of other excluded things
|
205
|
+
def net_excluded_directories
|
206
|
+
net = []
|
207
|
+
all = self.excluded_directories.map { |dir| relative(dir.to_s) }.sort_by { |d| d.size }
|
208
|
+
all.each_with_index do |dir, i|
|
209
|
+
unless all[0 ... i].find { |other| dir =~ /^#{other}/ }
|
210
|
+
net << dir
|
211
|
+
end
|
212
|
+
end
|
213
|
+
net
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Buildr
|
2
|
+
module IntellijIdea
|
3
|
+
class IdeaProject < IdeaFile
|
4
|
+
attr_accessor :vcs
|
5
|
+
attr_accessor :extra_modules
|
6
|
+
attr_writer :jdk_version
|
7
|
+
|
8
|
+
def initialize(buildr_project)
|
9
|
+
@buildr_project = buildr_project
|
10
|
+
@vcs = detect_vcs
|
11
|
+
@extra_modules = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def jdk_version
|
15
|
+
@jdk_version ||= buildr_project.compile.options.source || "1.6"
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def extension
|
21
|
+
"ipr"
|
22
|
+
end
|
23
|
+
|
24
|
+
def detect_vcs
|
25
|
+
if File.directory?(buildr_project._('.svn'))
|
26
|
+
"svn"
|
27
|
+
elsif File.directory?(buildr_project._('.git'))
|
28
|
+
"Git"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def base_document
|
33
|
+
target = StringIO.new
|
34
|
+
Builder::XmlMarkup.new(:target => target).project(:version => "4", :relativePaths => "false")
|
35
|
+
REXML::Document.new(target.string)
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_components
|
39
|
+
[
|
40
|
+
lambda { modules_component },
|
41
|
+
vcs_component
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def initial_components
|
46
|
+
[
|
47
|
+
lambda { project_root_manager_component }
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
def project_root_manager_component
|
52
|
+
attribs = {"version" => "2",
|
53
|
+
"assert-keyword" => "true",
|
54
|
+
"jdk-15" => "true",
|
55
|
+
"project-jdk-name" => self.jdk_version,
|
56
|
+
"project-jdk-type" => "JavaSDK",
|
57
|
+
"languageLevel" => "JDK_#{self.jdk_version.gsub('.','_')}" }
|
58
|
+
create_component("ProjectRootManager",attribs) do |xml|
|
59
|
+
xml.output("url" => "file://$PROJECT_DIR$/out")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def modules_component
|
64
|
+
create_component("ProjectModuleManager") do |xml|
|
65
|
+
xml.modules do
|
66
|
+
buildr_project.projects.select { |subp| subp.iml? }.each do |subproject|
|
67
|
+
module_path = subproject.base_dir.gsub(/^#{buildr_project.base_dir}\//, '')
|
68
|
+
path = "#{module_path}/#{subproject.iml.name}.iml"
|
69
|
+
attribs = { :fileurl => "file://$PROJECT_DIR$/#{path}", :filepath => "$PROJECT_DIR$/#{path}" }
|
70
|
+
if subproject.iml.group == true
|
71
|
+
attribs[:group] = subproject.parent.name.gsub(':', '/')
|
72
|
+
elsif !subproject.iml.group.nil?
|
73
|
+
attribs[:group] = subproject.group.to_s
|
74
|
+
end
|
75
|
+
xml.module attribs
|
76
|
+
end
|
77
|
+
self.extra_modules.each do |iml_file|
|
78
|
+
xml.module :fileurl => "file://$PROJECT_DIR$/#{iml_file}",
|
79
|
+
:filepath => "$PROJECT_DIR$/#{iml_file}"
|
80
|
+
end
|
81
|
+
if buildr_project.iml?
|
82
|
+
xml.module :fileurl => "file://$PROJECT_DIR$/#{buildr_project.iml.name}.iml",
|
83
|
+
:filepath => "$PROJECT_DIR$/#{buildr_project.iml.name}.iml"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def vcs_component
|
90
|
+
if vcs
|
91
|
+
create_component("VcsDirectoryMappings") do |xml|
|
92
|
+
xml.mapping :directory => "", :vcs => vcs
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|