From 1e0472f2e59d037bdde38ccde38897e04d89e206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Wed, 19 Apr 2023 01:27:13 +0200 Subject: [PATCH] extract FilesCollector --- .../maven/plugins/gpg/FilesCollector.java | 178 ++++++++++++++++++ .../plugins/gpg/GpgSignAttachedMojo.java | 140 ++------------ .../maven/plugins/gpg/SigningBundle.java | 55 ------ 3 files changed, 192 insertions(+), 181 deletions(-) create mode 100644 src/main/java/org/apache/maven/plugins/gpg/FilesCollector.java delete mode 100644 src/main/java/org/apache/maven/plugins/gpg/SigningBundle.java diff --git a/src/main/java/org/apache/maven/plugins/gpg/FilesCollector.java b/src/main/java/org/apache/maven/plugins/gpg/FilesCollector.java new file mode 100644 index 0000000..7283acf --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/gpg/FilesCollector.java @@ -0,0 +1,178 @@ +/* + * 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.plugins.gpg; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.SelectorUtils; + +/** + * Collects project artifact, the POM, and attached artifacts to be signed. + * + * @since 3.1.0 + */ +public class FilesCollector { + private final MavenProject project; + + private static final String DEFAULT_EXCLUDES[] = + new String[] {"**/*.md5", "**/*.sha1", "**/*.sha256", "**/*.sha512", "**/*.asc"}; + + private final String[] excludes; + + private final Log log; + + public FilesCollector(MavenProject project, String[] excludes, Log log) { + this.project = project; + this.log = log; + if (excludes == null || excludes.length == 0) { + this.excludes = DEFAULT_EXCLUDES; + return; + } + String newExcludes[] = new String[excludes.length]; + for (int i = 0; i < excludes.length; i++) { + String pattern; + pattern = excludes[i].trim().replace('/', File.separatorChar).replace('\\', File.separatorChar); + if (pattern.endsWith(File.separator)) { + pattern += "**"; + } + newExcludes[i] = pattern; + } + this.excludes = newExcludes; + } + + public List collect() throws MojoExecutionException, MojoFailureException { + List items = new ArrayList<>(); + + if (!"pom".equals(project.getPackaging())) { + // ---------------------------------------------------------------------------- + // Project artifact + // ---------------------------------------------------------------------------- + + Artifact artifact = project.getArtifact(); + + File file = artifact.getFile(); + + if (file != null && file.isFile()) { + items.add(new Item(file, artifact.getArtifactHandler().getExtension())); + } else if (project.getAttachedArtifacts().isEmpty()) { + throw new MojoFailureException("The project artifact has not been assembled yet. " + + "Please do not invoke this goal before the lifecycle phase \"package\"."); + } else { + log.debug("Main artifact not assembled, skipping signature generation"); + } + } + + // ---------------------------------------------------------------------------- + // POM + // ---------------------------------------------------------------------------- + + File pomToSign = + new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".pom"); + + try { + FileUtils.copyFile(project.getFile(), pomToSign); + } catch (IOException e) { + throw new MojoExecutionException("Error copying POM for signing.", e); + } + + items.add(new Item(pomToSign, "pom")); + + // ---------------------------------------------------------------------------- + // Attached artifacts + // ---------------------------------------------------------------------------- + + for (Artifact artifact : project.getAttachedArtifacts()) { + File file = artifact.getFile(); + + if (isExcluded(artifact)) { + log.debug("Skipping generation of signature for excluded " + file); + continue; + } + + items.add(new Item( + file, + artifact.getClassifier(), + artifact.getArtifactHandler().getExtension())); + } + + return items; + } + + /** + * Tests whether or not a name matches against at least one exclude pattern. + * + * @param artifact The artifact to match. Must not be null. + * @return true when the name matches against at least one exclude pattern, or false + * otherwise. + */ + protected boolean isExcluded(Artifact artifact) { + final Path projectBasePath = project.getBasedir().toPath(); + final Path artifactPath = artifact.getFile().toPath(); + final String relativeArtifactPath = + projectBasePath.relativize(artifactPath).toString(); + + for (String exclude : excludes) { + if (SelectorUtils.matchPath(exclude, relativeArtifactPath)) { + return true; + } + } + + return false; + } + + public static class Item { + private final File file; + + private final String classifier; + + private final String extension; + + public Item(File file, String classifier, String extension) { + this.file = file; + this.classifier = classifier; + this.extension = extension; + } + + public Item(File file, String extension) { + this(file, null, extension); + } + + public File getFile() { + return file; + } + + public String getClassifier() { + return classifier; + } + + public String getExtension() { + return extension; + } + } +} diff --git a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java index f441dd4..8dda2c6 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java @@ -19,12 +19,8 @@ package org.apache.maven.plugins.gpg; import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; -import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; @@ -33,8 +29,6 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; -import org.codehaus.plexus.util.FileUtils; -import org.codehaus.plexus.util.SelectorUtils; /** * Sign project artifact, the POM, and attached artifacts with GnuPG for deployment. @@ -46,9 +40,6 @@ @Mojo(name = "sign", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true) public class GpgSignAttachedMojo extends AbstractGpgMojo { - private static final String DEFAULT_EXCLUDES[] = - new String[] {"**/*.md5", "**/*.sha1", "**/*.sha256", "**/*.sha512", "**/*.asc"}; - /** * Skip doing the gpg signing. */ @@ -57,7 +48,7 @@ public class GpgSignAttachedMojo extends AbstractGpgMojo { /** * A list of files to exclude from being signed. Can contain Ant-style wildcards and double wildcards. The default - * excludes are **/*.md5 **/*.sha1 **/*.sha256 **/*.sha512 **/*.asc. + * excludes are **/*.md5 **/*.sha1 **/*.sha256 **/*.sha512 **/*.asc. * * @since 1.0-alpha-4 */ @@ -91,135 +82,32 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } - if (excludes == null || excludes.length == 0) { - excludes = DEFAULT_EXCLUDES; - } - String newExcludes[] = new String[excludes.length]; - for (int i = 0; i < excludes.length; i++) { - String pattern; - pattern = excludes[i].trim().replace('/', File.separatorChar).replace('\\', File.separatorChar); - if (pattern.endsWith(File.separator)) { - pattern += "**"; - } - newExcludes[i] = pattern; - } - excludes = newExcludes; + // ---------------------------------------------------------------------------- + // Collect files to sign + // ---------------------------------------------------------------------------- - AbstractGpgSigner signer = newSigner(project); + FilesCollector collector = new FilesCollector(project, excludes, getLog()); + List items = collector.collect(); // ---------------------------------------------------------------------------- - // What we need to generateSignatureForArtifact here + // Sign collected files and attach all the signatures // ---------------------------------------------------------------------------- + AbstractGpgSigner signer = newSigner(project); signer.setOutputDirectory(ascDirectory); signer.setBuildDirectory(new File(project.getBuild().getDirectory())); signer.setBaseDirectory(project.getBasedir()); - List signingBundles = new ArrayList<>(); - - if (!"pom".equals(project.getPackaging())) { - // ---------------------------------------------------------------------------- - // Project artifact - // ---------------------------------------------------------------------------- - - Artifact artifact = project.getArtifact(); - - File file = artifact.getFile(); - - if (file != null && file.isFile()) { - getLog().debug("Generating signature for " + file); + for (FilesCollector.Item item : items) { + getLog().debug("Generating signature for " + item.getFile()); - File projectArtifactSignature = signer.generateSignatureForArtifact(file); + File signature = signer.generateSignatureForArtifact(item.getFile()); - if (projectArtifactSignature != null) { - signingBundles.add( - new SigningBundle(artifact.getArtifactHandler().getExtension(), projectArtifactSignature)); - } - } else if (project.getAttachedArtifacts().isEmpty()) { - throw new MojoFailureException("The project artifact has not been assembled yet. " - + "Please do not invoke this goal before the lifecycle phase \"package\"."); - } else { - getLog().debug("Main artifact not assembled, skipping signature generation"); - } - } - - // ---------------------------------------------------------------------------- - // POM - // ---------------------------------------------------------------------------- - - File pomToSign = - new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".pom"); - - try { - FileUtils.copyFile(project.getFile(), pomToSign); - } catch (IOException e) { - throw new MojoExecutionException("Error copying POM for signing.", e); - } - - getLog().debug("Generating signature for " + pomToSign); - - File pomSignature = signer.generateSignatureForArtifact(pomToSign); - - if (pomSignature != null) { - signingBundles.add(new SigningBundle("pom", pomSignature)); - } - - // ---------------------------------------------------------------------------- - // Attached artifacts - // ---------------------------------------------------------------------------- - - for (Object o : project.getAttachedArtifacts()) { - Artifact artifact = (Artifact) o; - - File file = artifact.getFile(); - - if (isExcluded(artifact)) { - getLog().debug("Skipping generation of signature for excluded " + file); - continue; - } - - getLog().debug("Generating signature for " + file); - - File signature = signer.generateSignatureForArtifact(file); - - if (signature != null) { - signingBundles.add(new SigningBundle( - artifact.getArtifactHandler().getExtension(), artifact.getClassifier(), signature)); - } - } - - // ---------------------------------------------------------------------------- - // Attach all the signatures - // ---------------------------------------------------------------------------- - - for (SigningBundle bundle : signingBundles) { projectHelper.attachArtifact( project, - bundle.getExtension() + AbstractGpgSigner.SIGNATURE_EXTENSION, - bundle.getClassifier(), - bundle.getSignature()); - } - } - - /** - * Tests whether or not a name matches against at least one exclude pattern. - * - * @param artifact The artifact to match. Must not be null. - * @return true when the name matches against at least one exclude pattern, or false - * otherwise. - */ - protected boolean isExcluded(Artifact artifact) { - final Path projectBasePath = project.getBasedir().toPath(); - final Path artifactPath = artifact.getFile().toPath(); - final String relativeArtifactPath = - projectBasePath.relativize(artifactPath).toString(); - - for (String exclude : excludes) { - if (SelectorUtils.matchPath(exclude, relativeArtifactPath)) { - return true; - } + item.getExtension() + AbstractGpgSigner.SIGNATURE_EXTENSION, + item.getClassifier(), + signature); } - - return false; } } diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigningBundle.java b/src/main/java/org/apache/maven/plugins/gpg/SigningBundle.java deleted file mode 100644 index be43592..0000000 --- a/src/main/java/org/apache/maven/plugins/gpg/SigningBundle.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.plugins.gpg; - -import java.io.File; - -/** @author Jason van Zyl */ -public class SigningBundle { - - private String extension; - - private String classifier; - - private File signature; - - public SigningBundle(String extension, File signature) { - this.extension = extension; - - this.signature = signature; - } - - public SigningBundle(String extension, String classifier, File signature) { - this.extension = extension; - this.classifier = classifier; - this.signature = signature; - } - - public String getExtension() { - return extension; - } - - public File getSignature() { - return signature; - } - - public String getClassifier() { - return classifier; - } -}