This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push: new dc6d48ce00 [MNG-8330] Enforce attached artifacts to have the same GAV than their project (#1838) dc6d48ce00 is described below commit dc6d48ce00c3ebc0579079cadc93ae6175ed183b Author: Guillaume Nodet <gno...@gmail.com> AuthorDate: Thu Oct 24 13:52:48 2024 +0200 [MNG-8330] Enforce attached artifacts to have the same GAV than their project (#1838) --- .../apache/maven/api/services/ProjectManager.java | 35 +++++++++++-- .../impl/DefaultModelVersionParserTest.java | 35 +++++++++++++ .../maven/internal/impl/DefaultProjectManager.java | 27 ++++++++++ .../internal/impl/DefaultProjectManagerTest.java | 60 ++++++++++++++++++++++ 4 files changed, 154 insertions(+), 3 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java index 594434f517..bb208030c1 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectManager.java @@ -71,7 +71,16 @@ public interface ProjectManager extends Service { */ Collection<ProducedArtifact> getAllArtifacts(Project project); - default void attachArtifact(Session session, Project project, Path path) { + /** + * Attaches an artifact to the project using the given file path. The artifact type will be + * determined from the file extension. + * + * @param session the current build session + * @param project the project to attach the artifact to + * @param path the path to the artifact file + * @throws IllegalArgumentException if the session, project or path is null + */ + default void attachArtifact(@Nonnull Session session, @Nonnull Project project, @Nonnull Path path) { String name = path.getFileName().toString(); int dot = name.lastIndexOf('.'); String ext = dot >= 1 ? name.substring(dot + 1) : ""; @@ -80,13 +89,33 @@ public interface ProjectManager extends Service { attachArtifact(project, artifact, path); } - default void attachArtifact(Session session, Project project, String type, Path path) { + /** + * Attaches an artifact to the project with an explicitly specified type. + * + * @param session the current build session + * @param project the project to attach the artifact to + * @param type the type of the artifact (e.g., "jar", "war", "sources") + * @param path the path to the artifact file + * @throws IllegalArgumentException if the session, project, type or path is null + * @see org.apache.maven.api.Type + */ + default void attachArtifact( + @Nonnull Session session, @Nonnull Project project, @Nonnull String type, @Nonnull Path path) { ProducedArtifact artifact = session.createProducedArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null, null, type); attachArtifact(project, artifact, path); } - void attachArtifact(Project project, ProducedArtifact artifact, Path path); + /** + * Attaches a produced artifact to the project at the specified path. This is the base method + * that the other attachArtifact methods delegate to. + * + * @param project the project to attach the artifact to + * @param artifact the produced artifact to attach + * @param path the path to the artifact file + * @throws IllegalArgumentException if the project, artifact or path is null + */ + void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact artifact, @Nonnull Path path); /** * Obtain an immutable list of compile source roots for the given project and scope. diff --git a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/DefaultModelVersionParserTest.java b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/DefaultModelVersionParserTest.java new file mode 100644 index 0000000000..4c240b33a8 --- /dev/null +++ b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/DefaultModelVersionParserTest.java @@ -0,0 +1,35 @@ +/* + * 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. + */ +package org.apache.maven.internal.impl; + +import org.apache.maven.api.Version; +import org.eclipse.aether.util.version.GenericVersionScheme; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class DefaultModelVersionParserTest { + + @Test + void parseVersion() { + Version v = new DefaultModelVersionParser(new GenericVersionScheme()).parseVersion(""); + assertNotNull(v); + assertEquals("", v.asString()); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 1998bc2d7a..526bae16dd 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; @@ -93,6 +94,32 @@ public class DefaultProjectManager implements ProjectManager { @Override public void attachArtifact(Project project, ProducedArtifact artifact, Path path) { + nonNull(project, "project"); + nonNull(artifact, "artifact"); + nonNull(path, "path"); + if (artifact.getGroupId().isEmpty() + || artifact.getArtifactId().isEmpty() + || artifact.getBaseVersion().asString().isEmpty()) { + artifact = session.createProducedArtifact( + artifact.getGroupId().isEmpty() ? project.getGroupId() : artifact.getGroupId(), + artifact.getArtifactId().isEmpty() ? project.getArtifactId() : artifact.getArtifactId(), + artifact.getBaseVersion().asString().isEmpty() + ? session.parseVersion(project.getVersion()).asString() + : artifact.getBaseVersion().asString(), + artifact.getClassifier(), + artifact.getExtension(), + null); + } + if (!Objects.equals(project.getGroupId(), artifact.getGroupId()) + || !Objects.equals(project.getArtifactId(), artifact.getArtifactId()) + || !Objects.equals( + project.getVersion(), artifact.getBaseVersion().asString())) { + throw new IllegalArgumentException( + "The produced artifact must have the same groupId/artifactId/version than the project it is attached to. Expecting " + + project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion() + + " but received " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + + artifact.getBaseVersion()); + } getMavenProject(project) .addAttachedArtifact(RepositoryUtils.toArtifact( ((DefaultProject) project).getSession().toArtifact(artifact))); diff --git a/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java new file mode 100644 index 0000000000..63cd868adb --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -0,0 +1,60 @@ +/* + * 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. + */ +package org.apache.maven.internal.impl; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.maven.api.ProducedArtifact; +import org.apache.maven.api.Project; +import org.apache.maven.api.services.ArtifactManager; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.util.version.GenericVersionScheme; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +class DefaultProjectManagerTest { + + @Test + void attachArtifact() { + InternalMavenSession session = Mockito.mock(InternalMavenSession.class); + ArtifactManager artifactManager = Mockito.mock(ArtifactManager.class); + MavenProject mavenProject = new MavenProject(); + Project project = new DefaultProject(session, mavenProject); + ProducedArtifact artifact = Mockito.mock(ProducedArtifact.class); + Path path = Paths.get(""); + DefaultVersionParser versionParser = + new DefaultVersionParser(new DefaultModelVersionParser(new GenericVersionScheme())); + DefaultProjectManager projectManager = new DefaultProjectManager(session, artifactManager); + + mavenProject.setGroupId("myGroup"); + mavenProject.setArtifactId("myArtifact"); + mavenProject.setVersion("1.0-SNAPSHOT"); + when(artifact.getGroupId()).thenReturn("myGroup"); + when(artifact.getArtifactId()).thenReturn("myArtifact"); + when(artifact.getBaseVersion()).thenReturn(versionParser.parseVersion("1.0-SNAPSHOT")); + projectManager.attachArtifact(project, artifact, path); + + when(artifact.getArtifactId()).thenReturn("anotherArtifact"); + assertThrows(IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, path)); + } +}