|
7 | 7 | import java.nio.file.FileVisitResult; |
8 | 8 | import java.nio.file.Files; |
9 | 9 | import java.nio.file.Path; |
| 10 | +import java.nio.file.Paths; |
10 | 11 | import java.nio.file.SimpleFileVisitor; |
| 12 | +import java.nio.file.StandardCopyOption; |
11 | 13 | import java.nio.file.attribute.BasicFileAttributes; |
12 | 14 | import java.util.Arrays; |
13 | 15 | import java.util.Set; |
|
33 | 35 | import io.github.project.classport.commons.ClassportInfo; |
34 | 36 | import io.github.project.classport.commons.Utility; |
35 | 37 |
|
36 | | -@Mojo(name = "embed", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) |
| 38 | +@Mojo(name = "embed", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) |
37 | 39 | public class EmbeddingMojo |
38 | 40 | extends AbstractMojo { |
39 | 41 | /** |
@@ -93,10 +95,6 @@ private String getArtifactLongId(Artifact a) { |
93 | 95 | + ":" + a.getVersion(); |
94 | 96 | } |
95 | 97 |
|
96 | | - private void embedDirectory(Artifact a) throws IOException, MojoExecutionException { |
97 | | - embedDirectory(a, a.getFile()); |
98 | | - } |
99 | | - |
100 | 98 | private void embedDirectory(Artifact a, File dirToWalk) throws IOException, MojoExecutionException { |
101 | 99 | ClassportInfo metadata = getMetadata(a); |
102 | 100 | AnnotationConstantPool acp = new AnnotationConstantPool(metadata); |
@@ -125,45 +123,84 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO |
125 | 123 | }); |
126 | 124 | } |
127 | 125 |
|
| 126 | + /** |
| 127 | + * Root directory (shared by all modules) where embedded artefacts are written |
| 128 | + * in Maven-repository layout. |
| 129 | + * We keep the name "classport-files" to maintain backward compatibility with the previous version of the plugin. |
| 130 | + */ |
| 131 | + private File getAggregatedRepoRoot() { |
| 132 | + File topLevelBaseDir = session.getTopLevelProject().getBasedir(); |
| 133 | + return new File(topLevelBaseDir, "classport-files"); |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * Destination path (jar) inside the aggregated repository for the given |
| 138 | + * artifact. |
| 139 | + */ |
| 140 | + private File getRepoPathForArtifact(Artifact artifact, File repoRoot) { |
| 141 | + String groupPath = artifact.getGroupId().replace('.', File.separatorChar); |
| 142 | + File baseDir = Paths.get(repoRoot.getAbsolutePath(), groupPath, artifact.getArtifactId(), artifact.getVersion()).toFile(); |
| 143 | + String classifierPart = artifact.getClassifier() != null ? "-" + artifact.getClassifier() : ""; |
| 144 | + String extension = artifact.getArtifactHandler().getExtension(); |
| 145 | + return Paths.get(baseDir.getAbsolutePath(), artifact.getArtifactId() + "-" + artifact.getVersion() + classifierPart + "." + extension).toFile(); |
| 146 | + } |
| 147 | + |
| 148 | + /** |
| 149 | + * Copy an artifact into the aggregated repository and embed metadata into the |
| 150 | + * copy, leaving the original (e.g. ~/.m2) untouched. |
| 151 | + */ |
| 152 | + private void embedArtifactIntoRepo(Artifact artifact, File repoRoot) |
| 153 | + throws IOException, MojoExecutionException { |
| 154 | + File artifactFile = artifact.getFile(); |
| 155 | + if (artifactFile == null || !artifactFile.exists()) { |
| 156 | + getLog().warn("Artifact file not found for " + artifact + " (file: " |
| 157 | + + (artifactFile != null ? artifactFile.getAbsolutePath() : "null") + ")"); |
| 158 | + return; |
| 159 | + } |
| 160 | + |
| 161 | + if (artifactFile.isDirectory()) { |
| 162 | + getLog().info(String.format("%s is a directory (most likely target/classes). We don't embed it again since it was already embedded in reactor.", artifactFile.getAbsolutePath())); |
| 163 | + return; |
| 164 | + } |
| 165 | + |
| 166 | + File destJar = getRepoPathForArtifact(artifact, repoRoot); |
| 167 | + destJar.getParentFile().mkdirs(); |
| 168 | + |
| 169 | + Files.copy(artifactFile.toPath(), destJar.toPath(), StandardCopyOption.REPLACE_EXISTING); |
| 170 | + |
| 171 | + ClassportInfo meta = getMetadata(artifact); |
| 172 | + File tempJar = new File(destJar.getParent(), destJar.getName() + ".tmp"); |
| 173 | + JarHelper pkgr = new JarHelper(destJar, tempJar, true); |
| 174 | + pkgr.embed(meta); |
| 175 | + |
| 176 | + Files.delete(destJar.toPath()); |
| 177 | + Files.move(tempJar.toPath(), destJar.toPath(), StandardCopyOption.REPLACE_EXISTING); |
| 178 | + |
| 179 | + getLog().info("Embedded artifact into aggregated repo: " + destJar.getAbsolutePath()); |
| 180 | + } |
| 181 | + |
| 182 | + @Override |
128 | 183 | public void execute() throws MojoExecutionException, MojoFailureException { |
129 | 184 | Set<Artifact> dependencyArtifacts = project.getArtifacts(); |
130 | 185 |
|
131 | | - // Each module gets its own classport directory |
132 | | - File localrepoRoot = new File(project.getBasedir() + "/classport-files"); |
133 | | - localrepoRoot.mkdir(); |
| 186 | + // Shared repository for all modules |
| 187 | + File aggregatedRepoRoot = getAggregatedRepoRoot(); |
| 188 | + aggregatedRepoRoot.mkdirs(); |
134 | 189 |
|
135 | | - getLog().info("Processing project class files"); |
| 190 | + getLog().info("Embedding metadata into compiled classes for module: " + project.getArtifactId()); |
136 | 191 | try { |
137 | 192 | embedDirectory(project.getArtifact(), classesDirectory); |
| 193 | + getLog().info("Successfully embedded metadata in compiled classes"); |
138 | 194 | } catch (IOException e) { |
139 | | - getLog().error("Failed to embed annotations in project class files: " + e); |
| 195 | + getLog().error("Failed to embed annotations in project class files: " + e.getMessage(), e); |
| 196 | + throw new MojoExecutionException("Failed to embed annotations in project class files", e); |
140 | 197 | } |
141 | 198 |
|
142 | 199 | getLog().info("Processing dependencies"); |
143 | 200 | for (Artifact artifact : dependencyArtifacts) { |
144 | 201 | try { |
145 | | - ClassportInfo meta = getMetadata(artifact); |
146 | | - String artefactPath = getArtefactPath(artifact, true); |
147 | | - File artefactFullPath = new File(localrepoRoot + "/" + artefactPath); |
148 | | - getLog().debug("Embedding metadata for " + artifact); |
149 | | - if (artifact.getFile().isFile()) { |
150 | | - JarHelper pkgr = new JarHelper(artifact.getFile(), |
151 | | - artefactFullPath, |
152 | | - /* overwrite target if exists? */ true); |
153 | | - pkgr.embed(meta); |
154 | | - |
155 | | - // Also copy POMs to classport dir |
156 | | - File pomFile = new File(artifact.getFile().getAbsolutePath().replace(".jar", ".pom")); |
157 | | - File pomDestFile = new File(artefactFullPath.getAbsolutePath().replace(".jar", ".pom")); |
158 | | - if (pomFile.isFile() && !pomDestFile.exists()) |
159 | | - Files.copy(Path.of(pomFile.getAbsolutePath()), |
160 | | - Path.of(pomDestFile.getAbsolutePath())); |
161 | | - } else if (artifact.getFile().isDirectory()) { |
162 | | - embedDirectory(artifact); |
163 | | - } else { |
164 | | - getLog().warn("Skipping " + artifact.getArtifactId() |
165 | | - + " since it does not seem to reside in either a file nor a directory"); |
166 | | - } |
| 202 | + System.out.println("Embedding artifact: " + artifact.getArtifactId()); |
| 203 | + embedArtifactIntoRepo(artifact, aggregatedRepoRoot); |
167 | 204 | } catch (IOException e) { |
168 | 205 | getLog().error("Failed to embed metadata for " + artifact + ": " + e); |
169 | 206 | } |
@@ -194,30 +231,4 @@ private ClassportInfo getMetadata(Artifact artifact) throws IOException, MojoExe |
194 | 231 | .collect(Collectors.toList()).toArray(String[]::new)); |
195 | 232 | } |
196 | 233 |
|
197 | | - /** |
198 | | - * Get an artefact's path relative to the repository root. |
199 | | - * If resolveSnapshotVersion is true, we get the specific snapshot |
200 | | - * version instead of just "-SNAPSHOT". This may default to true |
201 | | - * in the future, as this seems to be Maven's default behaviour. |
202 | | - * |
203 | | - * TODO: Get the regular path (~/.m2/repository/...) and remove the |
204 | | - * m2/repo-part instead? |
205 | | - * |
206 | | - * @see <a href="https://maven.apache.org/repositories/layout.html">Maven |
207 | | - * docs on repository structure</a> |
208 | | - */ |
209 | | - private String getArtefactPath(Artifact a, boolean resolveSnapshotVersion) { |
210 | | - String classifier = a.getClassifier(); |
211 | | - if (classifier == null) |
212 | | - classifier = ""; |
213 | | - else |
214 | | - classifier = "-" + classifier; |
215 | | - |
216 | | - return String.format("%s/%s/%s/%s-%s%s.%s", |
217 | | - a.getGroupId().replace('.', '/'), |
218 | | - a.getArtifactId(), |
219 | | - a.getBaseVersion(), // This seems to always be the base version |
220 | | - a.getArtifactId(), (resolveSnapshotVersion ? a.getVersion() : a.getBaseVersion()), classifier, |
221 | | - "jar" /* TODO support more extensions */); |
222 | | - } |
223 | 234 | } |
0 commit comments