| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with this |
| # work for additional information regarding copyright ownership. The ASF |
| # licenses this file to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| module Buildr #:nodoc: |
| module Generate #:nodoc: |
| |
| task 'generate' do |
| |
| header = "To use Buildr you need a buildfile. Do you want me to create one?" |
| options = {} |
| if Generate.has_eclipse_project? |
| options["From eclipse .project files"] = Proc.new { Generate.from_eclipse(Dir.pwd).join("\n") } |
| end |
| if File.exist?('pom.xml') |
| options["From Maven2 POM file"] = Proc.new { Generate.from_maven2_pom('pom.xml').join("\n") } |
| end |
| options["From directory structure"] = Proc.new { Generate.from_directory(Dir.pwd).join("\n") } |
| options["Skip"]= nil |
| script = Buildr::Console.present_menu(header, options) |
| if script |
| buildfile = File.expand_path(Buildr::Application::DEFAULT_BUILDFILES.first) |
| File.open(buildfile, "w") { |file| file.write script } |
| puts "Created #{buildfile}" |
| end |
| end |
| |
| class << self |
| |
| def compatibility_option(path) |
| # compile.options.target = '1.5' |
| end |
| |
| def get_project_natures(projectFile) |
| return nil unless File.exists?(projectFile) |
| File.open(projectFile) do |f| |
| root = REXML::Document.new(f).root |
| return nil if root == nil |
| natures = root.elements.collect("natures/nature") { |n| n.text } |
| return natures if natures |
| end |
| return nil |
| end |
| |
| def get_build_property(path, propertyName) |
| propertiesFile = File.join(path, 'build.properties') |
| return nil unless File.exists?(propertiesFile) |
| inhalt = Hash.from_java_properties(File.read(propertiesFile)) |
| binDef = inhalt[propertyName] |
| end |
| |
| def has_eclipse_project? |
| candidates = Dir.glob("**/.project", File::FNM_DOTMATCH) |
| return false if candidates.size == 0 |
| candidates.find { |x| get_project_natures(x) } |
| return candidates.size > 0 |
| end |
| |
| |
| HEADER = "# Generated by Buildr #{Buildr::VERSION}, change to your liking\n\n" |
| |
| def getEclipseBuildfileHeader(path, name) |
| x = <<-EOF |
| #{"require 'buildr/scala'\n" if Dir.glob(path + "/**/*.scala").size > 0} |
| #{"require 'buildr/groovy'\n" if Dir.glob(path + "/**/*.groovy").size > 0} |
| # Version number for this release |
| VERSION_NUMBER = "1.0.0" |
| # Group identifier for your projects |
| GROUP = "#{name}" |
| COPYRIGHT = "" |
| |
| # Specify Maven 2.0 remote repositories here, like this: |
| repositories.remote << "https://repo1.maven.org/maven2" |
| |
| desc "The #{name.capitalize} project" |
| define "#{name}" do |
| |
| project.version = VERSION_NUMBER |
| project.group = GROUP |
| manifest["Implementation-Vendor"] = COPYRIGHT |
| EOF |
| return x |
| end |
| |
| def setLayout(source=nil, output = nil) |
| script = "" |
| if source |
| source = source.sub(/\/$/, '') # remove trailing / |
| script += <<-EOF |
| layout[:source, :main, :java] = "#{source}" |
| layout[:source, :main, :scala] = "#{source}" |
| EOF |
| end |
| if output |
| output = output.sub(/\/$/, '') # remove trailing / |
| script += <<-EOF |
| layout[:target, :main] = "#{output}" |
| layout[:target, :main, :java] = "#{output}" |
| layout[:target, :main, :scala] = "#{output}" |
| EOF |
| end |
| return script |
| end |
| |
| # tries to read as much information as needed at the moment from an existing Eclipse workspace |
| # Here are some links to the relevant information |
| # * http://help.eclipse.org/juno/index.jsp?topic=/org.eclipse.pde.doc.user/reference/pde_feature_generating_build.htm |
| # * http://wiki.eclipse.org/FAQ_What_is_the_plug-in_manifest_file_%28plugin.xml%29%3F |
| # * http://help.eclipse.org/juno/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/bundle_manifest.html |
| # * http://help.eclipse.org/juno/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/plugin_manifest.html |
| # * http://help.eclipse.org/juno/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_compilation_env.htm |
| def from_eclipse(path = Dir.pwd, root = true) |
| # We need two passes to be able to determine the dependencies correctly |
| Dir.chdir(path) do |
| name = File.basename(path) |
| dot_projects = [] |
| mf = nil # avoid reloading manifest |
| if root |
| @@allProjects = Hash.new |
| @@topDir = File.expand_path(Dir.pwd) |
| script = HEADER.split("\n") |
| script << "require 'buildr/ide/eclipse'" |
| header = getEclipseBuildfileHeader(path, name) |
| script += header.split("\n") |
| script << " # you may see hints about which jars are missing and should resolve them correctly" |
| script << " # dependencies << 'junit should be commented out and replace by correct ARTIFACT definition. Eg" |
| script << " # dependencies << 'junit:junit:jar:4.11'" |
| script << setLayout('src', 'bin') # default values for eclipse |
| dot_projects = Dir.glob('**/.project', File::FNM_DOTMATCH).find_all { |dot_project| get_project_natures(dot_project) } |
| dot_projects.sort.each { |dot_project| from_eclipse(File.dirname(dot_project), false) } if dot_projects |
| else |
| # Skip fragments. Buildr cannot handle it without the help of buildr4osgi |
| return [""] if File.exists?('fragment.xml') |
| projectName = name |
| version = "" |
| mfName = File.join('META-INF', 'MANIFEST.MF') |
| if File.exists?(mfName) |
| mf = Packaging::Java::Manifest.parse(IO.readlines(mfName).join('')) |
| if mf.main['Bundle-SymbolicName'] |
| projectName = mf.main['Bundle-SymbolicName'].split(';')[0] |
| bundleVersion = mf.main['Bundle-Version'] |
| version = ", :version => \"#{bundleVersion}\"" unless "1.0.0".eql?(bundleVersion) |
| end |
| end |
| # in the first run we just want to know that we exist |
| unless @@allProjects[projectName] |
| @@allProjects[projectName] = Dir.pwd |
| return |
| end |
| base_dir = "" |
| unless File.join(@@topDir, projectName).eql?(File.expand_path(Dir.pwd)) |
| base_dir = ", :base_dir => \"#{File.expand_path(Dir.pwd).sub(@@topDir+File::SEPARATOR, '')}\"" |
| end |
| script = [%{define "#{projectName}"#{version}#{base_dir} do}] |
| end |
| natures = get_project_natures('.project') |
| if natures && natures.index('org.eclipse.pde.PluginNature') |
| script << " package(:jar)" |
| end |
| script << " dependencies ||= []" |
| if mf && mf.main['Require-Bundle'] |
| mf.main['Require-Bundle'].split(',').each do |
| |bundle| |
| requiredName = bundle.split(';')[0] |
| if @@allProjects.has_key?(requiredName) |
| script << " dependencies << projects(\"#{requiredName}\")" |
| else |
| script << " # dependencies << '#{requiredName}'" |
| end |
| end |
| end |
| script << " compile.with dependencies # Add more classpath dependencies" if Dir.glob(File.join('src', '**', '*.java')).size > 0 |
| script << " resources" if File.exist?("rsc") |
| sourceProp = get_build_property('.', 'source..') |
| outputProp = get_build_property('.', 'output..') |
| if (sourceProp && !/src\/+/.match(sourceProp)) or (outputProp && !/bin\/+/.match(outputProp)) |
| setLayout(sourceProp, outputProp) # default values are overridden in this project |
| end |
| unless dot_projects.empty? |
| script << "" |
| dot_projects.sort.each do |dot_project| |
| next if File.dirname(File.expand_path(dot_project)).eql?(File.expand_path(Dir.pwd)) |
| next unless get_project_natures(dot_project) |
| script << from_eclipse(File.dirname(dot_project), false).flatten.map { |line| " " + line } << "" |
| end |
| end |
| script << "end\n\n" |
| script.flatten |
| end |
| end |
| |
| def from_directory(path = Dir.pwd, root = true) |
| Dir.chdir(path) do |
| name = File.basename(path) |
| if root |
| script = HEADER.split("\n") |
| header = getEclipseBuildfileHeader(path, name) |
| script += header.split("\n") |
| else |
| script = [ %{define "#{name}" do} ] |
| end |
| script << " compile.with # Add classpath dependencies" if File.exist?("src/main/java") |
| script << " resources" if File.exist?("src/main/resources") |
| script << " test.compile.with # Add classpath dependencies" if File.exist?("src/test/java") |
| script << " test.resources" if File.exist?("src/test/resources") |
| if File.exist?("src/main/webapp") |
| script << " package(:war)" |
| elsif File.exist?("src/main/java") |
| script << " package(:jar)" |
| end |
| dirs = FileList["*"].exclude("src", "target", "report"). |
| select { |file| File.directory?(file) && File.exist?(File.join(file, "src")) } |
| unless dirs.empty? |
| script << "" |
| dirs.sort.each do |dir| |
| script << from_directory(dir, false).flatten.map { |line| " " + line } << "" |
| end |
| end |
| script << "end" |
| script.flatten |
| end |
| end |
| |
| def from_maven2_pom(path = 'pom.xml', root = true) |
| pom = Buildr::POM.load(path) |
| project = pom.project |
| |
| artifactId = project['artifactId'].first |
| description = project['name'] || "The #{artifactId} project" |
| project_name = File.basename(Dir.pwd) |
| |
| if root |
| script = HEADER.split("\n") |
| |
| settings_file = ENV["M2_SETTINGS"] || File.join(ENV['HOME'], ".m2/settings.xml") |
| settings = XmlSimple.xml_in(IO.read(settings_file)) if File.exists?(settings_file) |
| |
| if settings |
| proxy = settings['proxies'].first['proxy'].find { |proxy| |
| proxy["active"].nil? || proxy["active"].to_s =~ /true/ |
| } rescue nil |
| |
| if proxy |
| url = %{#{proxy["protocol"].first}://#{proxy["host"].first}:#{proxy["port"].first}} |
| exclude = proxy["nonProxyHosts"].to_s.gsub("|", ",") if proxy["nonProxyHosts"] |
| script << "options.proxy.http = '#{url}'" |
| script << "options.proxy.exclude << '#{exclude}'" if exclude |
| script << '' |
| # In addition, we need to use said proxies to download artifacts. |
| Buildr.options.proxy.http = url |
| Buildr.options.proxy.exclude << exclude if exclude |
| end |
| end |
| |
| repositories = project["repositories"].first["repository"].select { |repository| |
| legacy = repository["layout"].to_s =~ /legacy/ |
| !legacy |
| } rescue nil |
| repositories = [{"name" => "Standard maven2 repository", "url" => "https://repo1.maven.org/maven2"}] if repositories.nil? || repositories.empty? |
| repositories.each do |repository| |
| name, url = repository["name"], repository["url"] |
| script << "# #{name}" |
| script << "repositories.remote << '#{url}'" |
| # In addition we need to use said repositores to download artifacts. |
| Buildr.repositories.remote << url.to_s |
| end |
| script << "" |
| else |
| script = [] |
| end |
| |
| script << "desc '#{description}'" |
| script << "define '#{project_name}' do" |
| |
| groupId = project['groupId'] |
| script << " project.group = '#{groupId}'" if groupId |
| |
| version = project['version'] |
| script << " project.version = '#{version}'" if version |
| |
| #get plugins configurations |
| plugins = project['build'].first['plugins'].first['plugin'] rescue {} |
| if plugins |
| compile_plugin = plugins.find{|pl| (pl['groupId'].nil? or pl['groupId'].first == 'org.apache.maven.plugins') and pl['artifactId'].first == 'maven-compiler-plugin'} |
| if compile_plugin |
| source = compile_plugin.first['configuration'].first['source'] rescue nil |
| target = compile_plugin.first['configuration'].first['target'] rescue nil |
| |
| script << " compile.options.source = '#{source}'" if source |
| script << " compile.options.target = '#{target}'" if target |
| end |
| end |
| |
| compile_dependencies = pom.dependencies |
| dependencies = compile_dependencies.sort.map{|d| "'#{d}'"}.join(', ') |
| script << " compile.with #{dependencies}" unless dependencies.empty? |
| |
| test_dependencies = (pom.dependencies(['test']) - compile_dependencies).reject{|d| d =~ /^junit:junit:jar:/ } |
| #check if we have testng |
| use_testng = test_dependencies.find{|d| d =~ /^org.testng:testng:jar:/} |
| if use_testng |
| script << " test.using :testng" |
| test_dependencies = pom.dependencies(['test']).reject{|d| d =~ /^org.testng:testng:jar:/ } |
| end |
| |
| test_dependencies = test_dependencies.sort.map{|d| "'#{d}'"}.join(', ') |
| script << " test.with #{test_dependencies}" unless test_dependencies.empty? |
| |
| packaging = project['packaging'] ? project['packaging'].first : 'jar' |
| if %w(jar war).include?(packaging) |
| script << " package :#{packaging}, :id => '#{artifactId}'" |
| end |
| |
| modules = project['modules'].first['module'] rescue nil |
| if modules |
| script << "" |
| modules.each do |mod| |
| script << from_maven2_pom(File.join(File.dirname(path), mod, 'pom.xml'), false).flatten.map { |line| " " + line } << "" |
| end |
| end |
| script << "end" |
| script.flatten |
| end |
| |
| end |
| end |
| end |