将父POM分解为子 [英] Collapsing parent POM into the child
问题描述
给出一个带有父POM的Maven项目-主要包括插件和依赖项版本-我如何生成一个POM,该POM从父中获取信息,将其放入子中并删除对父的引用?
Given a maven project with a parent POM - including mostly plugin and dependency versions - how can I generate a POM which takes the information from the parent, places it into the child and removes the reference to the parent?
理想情况下,这可以通过maven-assembly-plugin完成.
Ideally this would be done with the maven-assembly-plugin.
更新:我需要自动完成此操作,因为手动操作既乏味又乏味.
Update: I need this done automatically, since manually it's boring and tedious.
更新2 :我正在为外部代码准备源代码,并且只希望交付一个项目,而不是整个家庭.
Update 2: I'm preparing the source code for an external and want to deliver only one project, not the whole family.
推荐答案
前段时间我遇到了类似的问题,可以通过定义新的Maven插件来执行以下操作,从而避免使用Maven替换属性和解析路径等.
I had a similar issue a while back, you can avoid Maven substituting for the properties and resolving paths etc. by defining a new Maven plugin to do the following.
- 使用标准工件工厂解析每个父母
- 使用MavenXpp3Reader读取每个pom文件(无需解析)
- 合并未解决的项目
- 将合并的项目写入文件
这是一些我用来为自己证明过程的测试代码,您显然需要将其包装在Maven插件中并将其绑定到过程的某个阶段.默认情况下,已解析的pom输出到名称为resolve-pom.xml的输出目录(即目标),这两个属性可以通过设置"outputDir"和/或"pomfileName"属性用常规的Maven插件配置方法覆盖.
Here is some test code I used to prove the process for myself, you'd obviously need to wrap this up in a Maven plugin and bind that to some phase of your process. The resolved pom is output to the output directory (i.e. target) with the name resolved-pom.xml by default, these two properties can be overridden with the usual Maven plugin configuration approach by setting the "outputDir" and/or "pomfileName" properties.
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);
}
}
这篇关于将父POM分解为子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!