From a5eed0d9ee59fd563a1991af1d61472b5b128436 Mon Sep 17 00:00:00 2001 From: "Andrew M. Stoltz" Date: Sun, 20 Oct 2019 15:34:35 -0500 Subject: [PATCH 1/3] Remove external dependency on ant-filesystem-tasks --- pom.xml | 18 -- .../service/CopyWithPerms.java | 157 ++++++++++++++++++ .../artifactdeployer/service/LocalCopy.java | 1 - .../service/PermissionsUtils.java | 89 ++++++++++ 4 files changed, 246 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/jenkinsci/plugins/artifactdeployer/service/CopyWithPerms.java create mode 100644 src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java diff --git a/pom.xml b/pom.xml index 5af9b2e..9b5327b 100644 --- a/pom.xml +++ b/pom.xml @@ -59,11 +59,6 @@ matrix-project 1.3 - - com.atlassian - ant-filesystem-tasks - 0.0.2 - @@ -71,19 +66,6 @@ repo.jenkins-ci.org https://repo.jenkins-ci.org/public/ - - atlassian-public - https://maven.atlassian.com/repository/public - - true - never - warn - - - true - warn - - diff --git a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/CopyWithPerms.java b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/CopyWithPerms.java new file mode 100644 index 0000000..1df1baf --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/CopyWithPerms.java @@ -0,0 +1,157 @@ +package org.jenkinsci.plugins.artifactdeployer.service; + +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.types.FilterSet; +import org.apache.tools.ant.types.FilterSetCollection; + +public class CopyWithPerms extends Copy +{ + + static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private boolean preservePermissions = true; + + public boolean isPreservePermissions() + { + return preservePermissions; + } + + public void setPreservePermissions(boolean preservePermissions) + { + this.preservePermissions = preservePermissions; + } + + /** + * Actually does the file (and possibly empty directory) copies. + * This is a good method for subclasses to override. + */ + @Override + protected void doFileOperations() { + if (fileCopyMap.size() > 0) { + log("Copying " + fileCopyMap.size() + + " file" + (fileCopyMap.size() == 1 ? "" : "s") + + " to " + destDir.getAbsolutePath()); + + Enumeration e = fileCopyMap.keys(); + while (e.hasMoreElements()) { + String fromFile = (String) e.nextElement(); + String[] toFiles = (String[]) fileCopyMap.get(fromFile); + + for (int i = 0; i < toFiles.length; i++) { + String toFile = toFiles[i]; + + if (fromFile.equals(toFile)) { + log("Skipping self-copy of " + fromFile, verbosity); + continue; + } + try { + log("Copying " + fromFile + " to " + toFile, verbosity); + + FilterSetCollection executionFilters = + new FilterSetCollection(); + if (filtering) { + executionFilters + .addFilterSet(getProject().getGlobalFilterSet()); + } + for (Enumeration filterEnum = getFilterSets().elements(); + filterEnum.hasMoreElements();) { + executionFilters + .addFilterSet((FilterSet) filterEnum.nextElement()); + } + fileUtils.copyFile(new File(fromFile), new File(toFile), + executionFilters, + getFilterChains(), forceOverwrite, + preserveLastModified, + /* append: */ false, getEncoding(), + getOutputEncoding(), getProject() + /*, getForce()*/); //ant 1.8.2 + + if (preservePermissions) { + int perms = PermissionsUtils.getPermissions(new File(fromFile)); + PermissionsUtils.setPermissions(new File(toFile), perms); + } + + } catch (IOException ioe) { + String msg = "Failed to copy " + fromFile + " to " + toFile + + " due to " + getDueTo(ioe); + File targetFile = new File(toFile); + if (targetFile.exists() && !targetFile.delete()) { + msg += " and I couldn't delete the corrupt " + toFile; + } + if (failonerror) { + throw new BuildException(msg, ioe, getLocation()); + } + log(msg, Project.MSG_ERR); + } + } + } + } + if (includeEmpty) { + Enumeration e = dirCopyMap.elements(); + int createCount = 0; + while (e.hasMoreElements()) { + String[] dirs = (String[]) e.nextElement(); + for (int i = 0; i < dirs.length; i++) { + File d = new File(dirs[i]); + if (!d.exists()) { + if (!d.mkdirs()) { + log("Unable to create directory " + + d.getAbsolutePath(), Project.MSG_ERR); + } else { + createCount++; + } + } + } + } + if (createCount > 0) { + log("Copied " + dirCopyMap.size() + + " empty director" + + (dirCopyMap.size() == 1 ? "y" : "ies") + + " to " + createCount + + " empty director" + + (createCount == 1 ? "y" : "ies") + " under " + + destDir.getAbsolutePath()); + } + } + } + + + /** + * Returns a reason for failure based on + * the exception thrown. + * If the exception is not IOException output the class name, + * output the message + * if the exception is MalformedInput add a little note. + */ + private String getDueTo(Exception ex) { + boolean baseIOException = ex.getClass() == IOException.class; + StringBuffer message = new StringBuffer(); + if (!baseIOException || ex.getMessage() == null) { + message.append(ex.getClass().getName()); + } + if (ex.getMessage() != null) { + if (!baseIOException) { + message.append(" "); + } + message.append(ex.getMessage()); + } + if (ex.getClass().getName().indexOf("MalformedInput") != -1) { + message.append(LINE_SEPARATOR); + message.append( + "This is normally due to the input file containing invalid"); + message.append(LINE_SEPARATOR); + message.append("bytes for the character encoding used : "); + message.append( + (getEncoding() == null + ? fileUtils.getDefaultEncoding() : getEncoding())); + message.append(LINE_SEPARATOR); + } + return message.toString(); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/LocalCopy.java b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/LocalCopy.java index dc1c92f..dc13a32 100644 --- a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/LocalCopy.java +++ b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/LocalCopy.java @@ -22,7 +22,6 @@ */ package org.jenkinsci.plugins.artifactdeployer.service; -import com.atlassian.ant.tasks.CopyWithPerms; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.types.FileSet; import org.jenkinsci.plugins.artifactdeployer.ArtifactDeployerException; diff --git a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java new file mode 100644 index 0000000..f82b456 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java @@ -0,0 +1,89 @@ +package org.jenkinsci.plugins.artifactdeployer.service; + +import java.io.File; +import java.io.InputStream; +import java.io.PrintStream; + +import org.jruby.ext.posix.POSIX; +import org.jruby.ext.posix.POSIX.ERRORS; +import org.jruby.ext.posix.POSIXFactory; +import org.jruby.ext.posix.POSIXHandler; + +/** + * Provides convenience methods for manipulating file permissions, as best as is achievable with the Java 6 API. + */ +public class PermissionsUtils +{ + private static POSIX posix = POSIXFactory.getPOSIX(new PermissionsUtils.AntPOSIXHandler(), true); + + public static int getPermissions(File file) + { + return posix.stat(file.getAbsolutePath()).mode() & 0777; + } + + public static void setPermissions(File file, int perms) + { + posix.chmod(file.getAbsolutePath(), perms); + } + + /** + * Minimal POSIX handler for Ant tasks. There's scope for improvement here, like redirecting warnings through the Ant + * log, failing on errors, etc... + */ + public static class AntPOSIXHandler implements POSIXHandler + { + + public File getCurrentWorkingDirectory() + { + return new File("."); + } + + public String[] getEnv() + { + return new String[]{}; + } + + public PrintStream getErrorStream() + { + return System.err; + } + + public InputStream getInputStream() + { + return System.in; + } + + public PrintStream getOutputStream() + { + return System.out; + } + + public int getPID() + { + return 0; + } + + public boolean isVerbose() + { + return false; + } + + public void unimplementedError(String message) + { + throw new RuntimeException(message); + } + + public void warn(WARNING_ID arg0, String arg1, Object... arg2) + { + System.err.println(arg0 + ": " + String.format(arg1, arg2)); + } + + + public void error(ERRORS error, String extraData) + { + System.err.println(error + ": " + extraData); + } + + } + +} From d4f705a50f4578234c233da1666641da483bde5b Mon Sep 17 00:00:00 2001 From: "Andrew M. Stoltz" Date: Thu, 12 Dec 2019 11:15:38 -0600 Subject: [PATCH 2/3] Switch from org.jruby.ext.posix.POSIX to jnr.posix.POSIX --- pom.xml | 5 ++ .../service/PermissionsUtils.java | 72 ++----------------- 2 files changed, 9 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index 9b5327b..04eaf5e 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,11 @@ matrix-project 1.3 + + com.github.jnr + jnr-posix + 3.0.45 + diff --git a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java index f82b456..adba91f 100644 --- a/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java +++ b/src/main/java/org/jenkinsci/plugins/artifactdeployer/service/PermissionsUtils.java @@ -1,20 +1,17 @@ package org.jenkinsci.plugins.artifactdeployer.service; import java.io.File; -import java.io.InputStream; -import java.io.PrintStream; -import org.jruby.ext.posix.POSIX; -import org.jruby.ext.posix.POSIX.ERRORS; -import org.jruby.ext.posix.POSIXFactory; -import org.jruby.ext.posix.POSIXHandler; +import jnr.posix.POSIX; +import jnr.posix.POSIXFactory; +import jnr.posix.util.DefaultPOSIXHandler; /** * Provides convenience methods for manipulating file permissions, as best as is achievable with the Java 6 API. */ public class PermissionsUtils { - private static POSIX posix = POSIXFactory.getPOSIX(new PermissionsUtils.AntPOSIXHandler(), true); + private static POSIX posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler(), true); public static int getPermissions(File file) { @@ -25,65 +22,4 @@ public static void setPermissions(File file, int perms) { posix.chmod(file.getAbsolutePath(), perms); } - - /** - * Minimal POSIX handler for Ant tasks. There's scope for improvement here, like redirecting warnings through the Ant - * log, failing on errors, etc... - */ - public static class AntPOSIXHandler implements POSIXHandler - { - - public File getCurrentWorkingDirectory() - { - return new File("."); - } - - public String[] getEnv() - { - return new String[]{}; - } - - public PrintStream getErrorStream() - { - return System.err; - } - - public InputStream getInputStream() - { - return System.in; - } - - public PrintStream getOutputStream() - { - return System.out; - } - - public int getPID() - { - return 0; - } - - public boolean isVerbose() - { - return false; - } - - public void unimplementedError(String message) - { - throw new RuntimeException(message); - } - - public void warn(WARNING_ID arg0, String arg1, Object... arg2) - { - System.err.println(arg0 + ": " + String.format(arg1, arg2)); - } - - - public void error(ERRORS error, String extraData) - { - System.err.println(error + ": " + extraData); - } - - } - } From 8d4dbb417161efc880359734e0fc9f5947fda2ef Mon Sep 17 00:00:00 2001 From: Mark Waite Date: Sat, 8 Oct 2022 12:35:10 -0600 Subject: [PATCH 3/3] Use most recent JNR POSIX library --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b39de1d..a1ad795 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ com.github.jnr jnr-posix - 3.0.45 + 3.1.15