Падение родительского ПОМ на ребенка - PullRequest
6 голосов
/ 04 июня 2009

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

В идеале это должно быть сделано с помощью подключаемого модуля maven-assembly.


Обновление : мне нужно сделать это автоматически, так как вручную это скучно и утомительно.

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

Ответы [ 3 ]

4 голосов
/ 16 июня 2009

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

  • Разрешить каждого родителя, используя стандартную фабрику артефактов
  • Чтение каждого файла pom (без разрешения) с помощью MavenXpp3Reader
  • Слияние нерешенных проектов
  • Запишите объединенный проект в файл

Вот некоторый тестовый код, который я использовал, чтобы доказать этот процесс для себя, вам, очевидно, нужно обернуть это в плагин 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);
    }
}
2 голосов
/ 05 июня 2009

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

1 голос
/ 04 июня 2009

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

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

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

...