2009-06-04 8 views
4

Учитывая проект maven с родительским POM - в том числе в основном версиями плагинов и зависимостей - как я могу сгенерировать POM, который принимает информацию от родителя, помещает его в дочерний элемент и удаляет ссылку на родитель?Свертывание родительского POM в дочерний объект

В идеале это было бы сделано с помощью maven-assembly-plugin.


Update: Мне нужно это сделать автоматически, так как вручную это скучный и утомительный.

Обновление 2: Я готовлю исходный код для внешнего и хочу поставлять только один проект, а не всю семью.

+0

Я думаю, что мне что-то не хватает ... Не удалось ли это решить, разрезав и вставив элементы из родителя? – Cogsy

+0

Да, да. «Генерирующая» часть подразумевает автоматизацию :-) –

+0

почему вы не хотите ссылаться на родителя. Ссылка на родителя - это путь наименьшего сопротивления. –

ответ

4

У меня была подобная проблема некоторое время назад, вы можете избежать Maven, заменяя свойства и пути решения и т. Д., Определяя новый плагин Maven, чтобы сделать следующее.

  • Resolve каждый родитель, используя стандартный артефакт завод
  • Прочитайте каждый файл POM (без его разрешения) с помощью MavenXpp3Reader
  • Merge неразрешенных проектов
  • Написать объединенный проект в файл

Вот некоторый тестовый код, который я использовал для подтверждения процесса для себя, вам, очевидно, нужно будет обернуть его в плагин Maven и привязать его к определенной фазе вашего процесса. Разрешенный pom по умолчанию выводится в выходной каталог (т. Е. Target) с именем resolved-pom.xml, эти два свойства можно переопределить с помощью обычного подхода к настройке плагина Maven, установив свойства «outputDir» и/или «pomfileName» ,

package name.seller.rich; 

import java.io.File; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.Writer; 
import java.util.Stack; 

import org.apache.maven.artifact.Artifact; 
import org.apache.maven.artifact.resolver.ArtifactNotFoundException; 
import org.apache.maven.artifact.resolver.ArtifactResolutionException; 
import org.apache.maven.model.Model; 
import org.apache.maven.model.io.xpp3.MavenXpp3Reader; 
import org.apache.maven.plugin.AbstractMojo; 
import org.apache.maven.plugin.MojoExecutionException; 
import org.apache.maven.plugin.MojoFailureException; 
import org.apache.maven.project.MavenProject; 
import org.apache.maven.project.inheritance.ModelInheritanceAssembler; 
import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 

/** 
* @goal output-project 
* @phase process-resources 
* @requiresProject true 
*/ 
public class OutputResolvedProjectMojo extends AbstractMojo { 

    /** 
    * Used to look up overlay the parent models on the project's model. 
    * 
    * @parameter expression= 
    *   "${component.org.apache.maven.project.inheritance.ModelInheritanceAssembler}" 
    * @required 
    * @readonly 
    */ 
    private ModelInheritanceAssembler modelInheritanceAssembler; 

    /** 
    * Used to look up Artifacts in the remote repository. 
    * 
    * @parameter expression= 
    *   "${component.org.apache.maven.artifact.factory.ArtifactFactory}" 
    * @required 
    * @readonly 
    */ 
    protected org.apache.maven.artifact.factory.ArtifactFactory factory; 

    /** 
    * Used to look up Artifacts in the remote repository. 
    * 
    * @parameter expression= 
    *   "${component.org.apache.maven.artifact.resolver.ArtifactResolver}" 
    * @required 
    * @readonly 
    */ 
    protected org.apache.maven.artifact.resolver.ArtifactResolver artifactResolver; 

    /** 
    * List of Remote Repositories used by the resolver 
    * 
    * @parameter expression="${project.remoteArtifactRepositories}" 
    * @readonly 
    * @required 
    */ 
    protected java.util.List remoteRepos; 

    /** 
    * Location of the local repository. 
    * 
    * @parameter expression="${localRepository}" 
    * @readonly 
    * @required 
    */ 
    protected org.apache.maven.artifact.repository.ArtifactRepository local; 

    /** 
    * @parameter expression="${project}" 
    * @required 
    * @readonly 
    */ 
    private MavenProject mavenProject; 

    /** 
    * The directory to output the resolved project to. 
    * 
    * @parameter expression="${project.build.directory}" 
    */ 
    private File outputDir; 

    /** 
    * The directory to output the resolved project to. 
    * 
    * @parameter expression="resolved-pom.xml" 
    */ 
    private String pomfileName; 

    public void execute() throws MojoExecutionException, MojoFailureException { 
     MavenProject parentProject = mavenProject.getParent(); 

     // get the unresolved project by reading the file 
     MavenProject bareProject = readBareProject(mavenProject.getFile()); 

     Stack hierarchy = new Stack(); 
     hierarchy.push(bareProject); 

     try { 
      while (parentProject != null) { 

       try { 
        // get Maven to resolve the parent artifact (download if 
        // needed) 
        Artifact pomArtifact = this.factory.createArtifact(
          parentProject.getGroupId(), parentProject 
            .getArtifactId(), parentProject 
            .getVersion(), "", "pom"); 

        artifactResolver.resolve(pomArtifact, this.remoteRepos, 
          this.local); 

        // get the file from the local repository and read the bare 
        // project 
        File parentPomFile = pomArtifact.getFile(); 

        parentProject = readBareProject(parentPomFile); 

        hierarchy.push(parentProject); 

        parentProject = parentProject.getParent(); 
       } catch (ArtifactResolutionException e) { 
        getLog().error("can't resolve parent pom", e); 
       } catch (ArtifactNotFoundException e) { 
        getLog().error("can't resolve parent pom", e); 
       } 
      } 

      // merge each model starting with the oldest ancestors 
      MavenProject currentParent = (MavenProject) hierarchy.pop(); 
      MavenProject currentProject = null; 
      while (hierarchy.size() != 0) { 
       currentProject = (MavenProject) hierarchy.pop(); 
       modelInheritanceAssembler.assembleModelInheritance(
         currentProject.getModel(), currentParent.getModel()); 
       currentParent = currentProject; 
      } 

      // spit the merged model to the output file. 
      Writer writer = getWriter(outputDir, pomfileName); 

      if (writer != null) { 
       currentProject.writeModel(writer); 
       writer.close(); 
      } 
     } catch (IOException e) { 
      getLog().error("can't write resolved pom", e); 
     } 

    } 

    /** 
    * Creates and returns a writer for outputting the project to a pom file. 
    * 
    * @param logDir 
    *   the directory to output the file to. 
    * @param logFileName 
    *   name of the log file 
    * @return the writer. 
    * @throws IOException 
    *    if the writer cannot be created. 
    */ 
    private Writer getWriter(final File logDir, final String logFileName) 
      throws IOException { 
     if (!logDir.exists()) { 
      logDir.mkdirs(); 
     } 

     File pomLog = new File(logDir, logFileName); 

     if (!pomLog.exists()) { 
      pomLog.createNewFile(); 
     } 

     return new FileWriter(pomLog); 
    } 

    /** 
    * Read the mavenProject without resolving any inherited settings. 
    * 
    * @return the MavenProject for the project's POM 
    * @throws MojoExecutionException 
    *    if the POM can't be parsed. 
    */ 
    MavenProject readBareProject(final File file) { 
     MavenXpp3Reader reader = new MavenXpp3Reader(); 
     Model model = null; 
     try { 
      model = reader.read(new FileReader(file)); 
     } catch (IOException e) { 
      getLog().error("can't read pom file", e); 
     } catch (XmlPullParserException e) { 
      getLog().error("can't read pom file", e); 
     } 

     return new MavenProject(model); 
    } 
} 
+0

Это здорово, спасибо! Я попробую, как только смогу. –

+0

Вы, сэр, блестящие. –

1

Если вы не хотите родителя, вы можете попробовать шаблон спецификации (Билль материалов) и выбрать этот pom для импорта в разделе управления зависимостями.

Поскольку вы не хотите ссылаться ни на что другое, вам нужно будет создать приложение для разбора xml от «родителей», а затем записать их в целевой файл pom в разделе зависимостей. Я не думаю, что есть какой-либо плагин, чтобы делать то, что вы хотите, поскольку он, похоже, противоречит самому ядру того, как maven должен вам помочь. Весь смысл maven заключается в том, что вы можете включать все ваши зависимости с использованием наследования или импортировать их с областью импорта.

Другой вариант, но я думаю, что вы его исключили, заключается в том, чтобы сохранить ваш разблокируемый POM-файл отдельно. Хотя я думаю, что вам может быть легче с этим, если вы ссылаетесь на LATEST или SNAPSHOTS, а затем используете плагин release, чтобы разрешить их выпущенным версиям.

+0

Обновлено описание: Я готовлю исходный код для внешнего и хочу поставлять только один проект, а не всю семью. Мне нужно, чтобы он не зависел от других артефактов. –

2

Будет mvn help:effective-pom делать то, что вам нужно? Вы можете отправить вывод в файл с -Doutput=new-pom.xml.

+2

Это полезно, спасибо. К сожалению, все пути преобразуются в абсолютные. –