You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/10/13 21:49:49 UTC
(maven-dependency-plugin) branch agent/mdep-446-dest-file-name-cli created (now fc0e56cb)
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a change to branch agent/mdep-446-dest-file-name-cli
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git
at fc0e56cb [MDEP-446] Accept destFileName in the artifact parameter of copy
This branch includes the following new commits:
new fc0e56cb [MDEP-446] Accept destFileName in the artifact parameter of copy
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(maven-dependency-plugin) 01/01: [MDEP-446] Accept destFileName in the artifact parameter of copy
Posted by sl...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch agent/mdep-446-dest-file-name-cli
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git
commit fc0e56cb757f0c6e3a6951b3a2190c939979d095
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Tue Oct 13 23:31:09 2026 +0200
[MDEP-446] Accept destFileName in the artifact parameter of copy
---
.../copy-cli-dest-file-name/invoker.properties | 18 ++++++++++
src/it/projects/copy-cli-dest-file-name/pom.xml | 32 +++++++++++++++++
.../copy-cli-dest-file-name/test.properties | 18 ++++++++++
.../projects/copy-cli-dest-file-name/verify.groovy | 21 ++++++++++++
.../AbstractFromConfigurationMojo.java | 40 ++++++++++------------
.../dependency/fromConfiguration/CopyMojo.java | 7 ++--
.../dependency/fromConfiguration/UnpackMojo.java | 5 +--
.../dependency/fromConfiguration/TestCopyMojo.java | 32 +++++++++++++++++
8 files changed, 147 insertions(+), 26 deletions(-)
diff --git a/src/it/projects/copy-cli-dest-file-name/invoker.properties b/src/it/projects/copy-cli-dest-file-name/invoker.properties
new file mode 100644
index 00000000..c8bd0f7f
--- /dev/null
+++ b/src/it/projects/copy-cli-dest-file-name/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:copy
diff --git a/src/it/projects/copy-cli-dest-file-name/pom.xml b/src/it/projects/copy-cli-dest-file-name/pom.xml
new file mode 100644
index 00000000..1f36e14b
--- /dev/null
+++ b/src/it/projects/copy-cli-dest-file-name/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins.dependency.its</groupId>
+ <artifactId>copy-cli-dest-file-name</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+</project>
\ No newline at end of file
diff --git a/src/it/projects/copy-cli-dest-file-name/test.properties b/src/it/projects/copy-cli-dest-file-name/test.properties
new file mode 100644
index 00000000..914691d2
--- /dev/null
+++ b/src/it/projects/copy-cli-dest-file-name/test.properties
@@ -0,0 +1,18 @@
+# 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.
+
+artifact=org.apache.maven.its.dependency:a1:1.0.0:jar::renamed.jar
diff --git a/src/it/projects/copy-cli-dest-file-name/verify.groovy b/src/it/projects/copy-cli-dest-file-name/verify.groovy
new file mode 100644
index 00000000..b7c8c368
--- /dev/null
+++ b/src/it/projects/copy-cli-dest-file-name/verify.groovy
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+assert new File( basedir, 'target/dependency/renamed.jar' ).isFile()
+assert !new File( basedir, 'target/dependency/a1-1.0.0.jar' ).exists()
diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java
index 0fe60cbd..2c80f071 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java
@@ -347,36 +347,32 @@ public abstract class AbstractFromConfigurationMojo extends AbstractDependencyMo
}
/**
- * @param artifact the artifact
+ * @param artifact the artifact, in the form {@code groupId:artifactId:version[:packaging[:classifier[:destFileName]]]}
* @throws MojoFailureException in case of an error
*/
public void setArtifact(String artifact) throws MojoFailureException {
if (artifact != null) {
- String packaging = "jar";
- String classifier;
- String[] tokens = StringUtils.split(artifact, ":");
- if (tokens.length < 3 || tokens.length > 5) {
+ // keep empty tokens, so that an empty classifier can precede a destFileName
+ String[] tokens = StringUtils.splitPreserveAllTokens(artifact, ":");
+ if (tokens.length < 3
+ || tokens.length > 6
+ || StringUtils.isEmpty(tokens[0])
+ || StringUtils.isEmpty(tokens[1])
+ || StringUtils.isEmpty(tokens[2])) {
throw new MojoFailureException("Invalid artifact, "
- + "you must specify groupId:artifactId:version[:packaging[:classifier]] " + artifact);
- }
- String groupId = tokens[0];
- String artifactId = tokens[1];
- String version = tokens[2];
- if (tokens.length >= 4) {
- packaging = tokens[3];
- }
- if (tokens.length == 5) {
- classifier = tokens[4];
- } else {
- classifier = null;
+ + "you must specify groupId:artifactId:version[:packaging[:classifier[:destFileName]]] "
+ + artifact);
}
ArtifactItem artifactItem = new ArtifactItem();
- artifactItem.setGroupId(groupId);
- artifactItem.setArtifactId(artifactId);
- artifactItem.setVersion(version);
- artifactItem.setType(packaging);
- artifactItem.setClassifier(classifier);
+ artifactItem.setGroupId(tokens[0]);
+ artifactItem.setArtifactId(tokens[1]);
+ artifactItem.setVersion(tokens[2]);
+ artifactItem.setType(tokens.length >= 4 && !tokens[3].isEmpty() ? tokens[3] : "jar");
+ artifactItem.setClassifier(tokens.length >= 5 && !tokens[4].isEmpty() ? tokens[4] : null);
+ if (tokens.length == 6 && !tokens[5].isEmpty()) {
+ artifactItem.setDestFileName(tokens[5]);
+ }
setArtifactItems(Collections.singletonList(artifactItem));
}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
index 644c6121..15e48042 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
@@ -80,8 +80,11 @@ public class CopyMojo extends AbstractFromConfigurationMojo {
private boolean useBaseVersion = false;
/**
- * The artifact to copy from command line. A string of the form groupId:artifactId:version[:packaging[:classifier]].
- * Use {@link #artifactItems} within the POM configuration.
+ * The artifact to copy from command line. A string of the form
+ * <code>groupId:artifactId:version[:packaging[:classifier[:destFileName]]]</code>. The optional
+ * <code>destFileName</code> (since 3.12.0) is the name of the copied file; leave the classifier empty to give a
+ * <code>destFileName</code> without one, as in <code>g:a:1.0:jar::renamed.jar</code>. Use {@link #artifactItems}
+ * within the POM configuration.
*/
@SuppressWarnings("unused") // marker-field, setArtifact(String) does the magic
@Parameter(property = "artifact")
diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java
index 005299cd..551f8327 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java
@@ -98,8 +98,9 @@ public class UnpackMojo extends AbstractFromConfigurationMojo {
/**
* The artifact to unpack from command line. A string of the form
- * <code>groupId:artifactId:version[:packaging[:classifier]]</code>. Use {@link #artifactItems} within the POM
- * configuration.
+ * <code>groupId:artifactId:version[:packaging[:classifier]]</code>. The goal shares the parser of
+ * <code>dependency:copy</code>, which also accepts a trailing <code>:destFileName</code>; unpack ignores it. Use
+ * {@link #artifactItems} within the POM configuration.
*/
@SuppressWarnings("unused") // marker-field, setArtifact(String) does the magic
@Parameter(property = "artifact")
diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java
index 019116e8..f6a6f638 100644
--- a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java
+++ b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java
@@ -35,6 +35,7 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory;
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
import org.apache.maven.project.MavenProject;
@@ -45,6 +46,7 @@ import org.junit.jupiter.api.io.TempDir;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.AssertionsKt.assertNull;
@@ -113,6 +115,36 @@ class TestCopyMojo {
assertEquals("e", item.getClassifier());
}
+ @Test
+ @InjectMojo(goal = "copy")
+ @MojoParameter(name = "artifact", value = "a:b:c:d:e:f.jar")
+ void testSetArtifactWithDestFileName(CopyMojo mojo) {
+ ArtifactItem item = mojo.getArtifactItems().get(0);
+ assertEquals("a", item.getGroupId());
+ assertEquals("b", item.getArtifactId());
+ assertEquals("c", item.getVersion());
+ assertEquals("d", item.getType());
+ assertEquals("e", item.getClassifier());
+ assertEquals("f.jar", item.getDestFileName());
+ }
+
+ @Test
+ @InjectMojo(goal = "copy")
+ @MojoParameter(name = "artifact", value = "a:b:c:d::f.jar")
+ void testSetArtifactWithDestFileNameWithoutClassifier(CopyMojo mojo) {
+ ArtifactItem item = mojo.getArtifactItems().get(0);
+ assertEquals("d", item.getType());
+ assertNull(item.getClassifier());
+ assertEquals("f.jar", item.getDestFileName());
+ }
+
+ @Test
+ @InjectMojo(goal = "copy")
+ void testSetArtifactWithTooManyTokens(CopyMojo mojo) {
+ MojoFailureException e = assertThrows(MojoFailureException.class, () -> mojo.setArtifact("a:b:c:d:e:f.jar:g"));
+ assertTrue(e.getMessage().contains("groupId:artifactId:version[:packaging[:classifier[:destFileName]]]"));
+ }
+
@Test
@InjectMojo(goal = "copy")
void testGetArtifactItems(CopyMojo mojo) throws Exception {