├── .gitignore ├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ └── jenkins-security-scan.yml ├── src ├── site │ └── resources │ │ ├── global_config.png │ │ ├── project_config_1.png │ │ └── project_config_2.png └── main │ ├── resources │ ├── org │ │ └── jenkinsci │ │ │ └── plugins │ │ │ └── ant_in_workspace │ │ │ ├── AntInWorkspaceBuildWrapper │ │ │ ├── help-info.html │ │ │ └── config.jelly │ │ │ ├── AntInWorkspace │ │ │ ├── help-antWorkspaceFolder.html │ │ │ ├── global.jelly │ │ │ └── config.groovy │ │ │ └── AntInWorkspaceJobPropertyInfo │ │ │ ├── help-antInWorkspace.html │ │ │ └── config.jelly │ └── index.jelly │ └── java │ └── org │ └── jenkinsci │ └── plugins │ └── ant_in_workspace │ ├── AntInWorkspaceJobPropertyInfo.java │ ├── AntInWorkspaceBuildWrapper.java │ └── AntInWorkspace.java ├── Jenkinsfile ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | .settings 3 | .classpath 4 | .project 5 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/ant-in-workspace-plugin-developers 2 | -------------------------------------------------------------------------------- /src/site/resources/global_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/ant-in-workspace-plugin/master/src/site/resources/global_config.png -------------------------------------------------------------------------------- /src/site/resources/project_config_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/ant-in-workspace-plugin/master/src/site/resources/project_config_1.png -------------------------------------------------------------------------------- /src/site/resources/project_config_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/ant-in-workspace-plugin/master/src/site/resources/project_config_2.png -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceBuildWrapper/help-info.html: -------------------------------------------------------------------------------- 1 |
2 |

Help Me! I dont know where this is displayed?

3 |
-------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | Plugin extends official Ant Plugin. Allows to use an Ant that is located in the Workspace. 4 |
5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceBuildWrapper/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspace/help-antWorkspaceFolder.html: -------------------------------------------------------------------------------- 1 |
2 | Define the directory inside the $WORKSPACE of the current build, where the ANT is located, i.E. DailyBuild/ant-1.7.1-patched/ 3 |
4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: / 5 | schedule: 6 | interval: monthly 7 | - package-ecosystem: github-actions 8 | directory: / 9 | schedule: 10 | interval: monthly 11 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceJobPropertyInfo/help-antInWorkspace.html: -------------------------------------------------------------------------------- 1 |
2 |

If your job should not make use of the global configuration of 3 | the AntInWorkspace plugin, you can define a custom path here on job 4 | level.

5 |
-------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceJobPropertyInfo/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspace/global.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | * See the documentation for more options: 3 | * https://github.com/jenkins-infra/pipeline-library/ 4 | */ 5 | buildPlugin( 6 | forkCount: '1C', // run this number of tests in parallel for faster feedback. If the number terminates with a 'C', the value will be multiplied by the number of available CPU cores 7 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests 8 | configurations: [ 9 | [platform: 'linux', jdk: 21], 10 | [platform: 'windows', jdk: 17], 11 | ]) 12 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [ opened, synchronize, reopened ] 9 | workflow_dispatch: 10 | 11 | permissions: 12 | security-events: write 13 | contents: read 14 | actions: read 15 | 16 | jobs: 17 | security-scan: 18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 19 | with: 20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceJobPropertyInfo.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.ant_in_workspace; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.annotation.CheckForNull; 6 | 7 | import org.kohsuke.stapler.DataBoundConstructor; 8 | 9 | import hudson.Extension; 10 | import hudson.model.Describable; 11 | import hudson.model.Descriptor; 12 | import jenkins.model.Jenkins; 13 | 14 | /** 15 | * 16 | * This is the Class that contains the per-Job configuration for the AntInWorkspace Plugin. 17 | * 18 | * @author stephan.watermeyer, Diebold Nixdorf 19 | */ 20 | public class AntInWorkspaceJobPropertyInfo implements Describable, Serializable { 21 | 22 | private static final long serialVersionUID = -4107653406524142161L; 23 | 24 | String antInWorkspace; 25 | 26 | @DataBoundConstructor 27 | public AntInWorkspaceJobPropertyInfo(@CheckForNull String antInWorkspace) { 28 | this.antInWorkspace = antInWorkspace; 29 | } 30 | 31 | public String getAntInWorkspace() { 32 | return antInWorkspace; 33 | } 34 | 35 | public void setAntInWorkspace(String antInWorkspace) { 36 | this.antInWorkspace = antInWorkspace; 37 | } 38 | 39 | @Override 40 | public Descriptor getDescriptor() { 41 | return Jenkins.getActiveInstance().getDescriptorByType(DescriptorImpl.class); 42 | } 43 | 44 | @Extension 45 | public static class DescriptorImpl extends Descriptor { 46 | @Override 47 | public String getDisplayName() { 48 | return "AntInWorkspaceJobPropertyInfo"; 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspace/config.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2011, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package org.jenkinsci.plugins.ant_in_workspace.AntInWorkspace; 25 | 26 | f=namespace(lib.FormTagLib) 27 | 28 | if (descriptor.installations.length != 0) { 29 | f.entry(title:_("Ant Version")) { 30 | select(class:"setting-input",name:"ant.antName") { 31 | option(value:"(Default)", _("Default")) 32 | descriptor.installations.each { 33 | f.option(selected:it.name==instance?.ant?.name, value:it.name, it.name) 34 | } 35 | } 36 | } 37 | } 38 | 39 | f.entry(title:_("Targets"),field:"targets") { 40 | f.expandableTextbox() 41 | } 42 | 43 | f.advanced { 44 | f.entry(title:_("Build File"),field:"buildFile") { 45 | f.expandableTextbox() 46 | } 47 | f.entry(title:_("Properties"),field:"properties") { 48 | f.expandableTextbox() 49 | } 50 | f.entry(title:_("Java Options"),field:"antOpts") { 51 | f.expandableTextbox() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspaceBuildWrapper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.ant_in_workspace; 2 | 3 | import java.io.IOException; 4 | import java.io.Serializable; 5 | import java.util.Map; 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | import org.kohsuke.stapler.DataBoundConstructor; 12 | 13 | import hudson.Extension; 14 | import hudson.Launcher; 15 | import hudson.model.AbstractBuild; 16 | import hudson.model.AbstractProject; 17 | import hudson.model.BuildListener; 18 | import hudson.tasks.BuildWrapper; 19 | import hudson.tasks.BuildWrapperDescriptor; 20 | 21 | /** 22 | * 23 | * This class is the Job Configuration. If the Job has this option enabled, the path for AntInWorkspace can be customized. 24 | * 25 | * @author stephan.watermeyer, Diebold Nixdorf 26 | */ 27 | public class AntInWorkspaceBuildWrapper extends BuildWrapper implements Serializable { 28 | 29 | /** Environment Variable that is set if there is a Job-specific AntInWorkspace defined */ 30 | public static final String ENV_VAR_CUSTOM_ANT_IN_WORKSPACE = "CUSTOM_ANT_IN_WORKSPACE"; 31 | 32 | private static final long serialVersionUID = -4674143417274553383L; 33 | 34 | private static final Logger LOGGER = Logger.getLogger(AntInWorkspaceBuildWrapper.class.getName()); 35 | 36 | AntInWorkspaceJobPropertyInfo info; 37 | 38 | @DataBoundConstructor 39 | public AntInWorkspaceBuildWrapper(@Nonnull AntInWorkspaceJobPropertyInfo info) { 40 | this.info = info; 41 | } 42 | 43 | public AntInWorkspaceJobPropertyInfo getInfo() { 44 | return info; 45 | } 46 | 47 | /* 48 | * This method is invoked only, if the Job has a "AntInWorkspace" configured. This means we have to put the path for 49 | * the defined AntInWorkspace to the environment variables. If the Job hasnt configured a custom AntInWorkspace, this method is not invoked. 50 | */ 51 | @Override 52 | public Environment setUp(@Nonnull AbstractBuild build, final @Nonnull Launcher launcher, 53 | final @Nonnull BuildListener listener) throws IOException, InterruptedException { 54 | return new Environment() { 55 | 56 | @Override 57 | public void buildEnvVars(Map env) { 58 | LOGGER.log(Level.FINE, "put CUSTOM_ANT_IN_WORKSPACE: " + getInfo().getAntInWorkspace()); 59 | env.put(ENV_VAR_CUSTOM_ANT_IN_WORKSPACE, getInfo().getAntInWorkspace()); 60 | } 61 | }; 62 | } 63 | 64 | @Extension 65 | public static final class DescriptorImpl extends BuildWrapperDescriptor { 66 | 67 | @Override 68 | public boolean isApplicable(AbstractProject item) { 69 | return true; 70 | } 71 | 72 | @Override 73 | public String getDisplayName() { 74 | return "Custom Ant in Workspace"; 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jenkins Plugin - Ant In Workspace 2 | [![Build Status](https://ci.jenkins.io/job/Plugins/job/ant-in-workspace-plugin/job/master/badge/icon)](https://ci.jenkins.io/job/Plugins/job/ant-in-workspace-plugin/job/master) 3 | [![Contributors](https://img.shields.io/github/contributors/jenkinsci/ant-in-workspace-plugin.svg)](https://github.com/jenkinsci/ant-in-workspace-plugin/graphs/contributors) 4 | [![Jenkins Plugin](https://img.shields.io/jenkins/plugin/v/ant-in-workspace.svg)](https://plugins.jenkins.io/ant-in-workspace-plugin) 5 | [![Jenkins Plugin Installs](https://img.shields.io/jenkins/plugin/i/ant-in-workspace.svg?color=blue)](https://plugins.jenkins.io/ant-in-workspace-plugin) 6 | 7 | Allows users to configure an ANT based build that utilizes an Ant that is located in the workspace. 8 | 9 | # What is this? 10 | This Plugin extends the official Jenkins Ant Plugin. It provides a new Builder based on Ant that has disabled the functionality to choose between different Ant versions. But it will allow to use an Ant version that is available in the workspace. 11 | 12 | This is to allow (legacy) builds to use a special Ant that is checked into the SCM. When building the Job this special Ant version is returned and file-permissions (+x) are set. It is possible to configure the path to Ant in a global AntInWorkspace parameter or a per-Job parameter. 13 | 14 | # Example 15 | We are using this because we are using a special/patched Ant version for building our software. This Ant is checked-in into the SCM and so we have to check it out, make it executable (on Unix) and use it to build the software. As our software is used in multiple customer projects, there is an option to define the path to the Ant installation on a per-Job level or globally in Jenkins. 16 | 17 | # Configuration Example 18 | ## Project Configuration - Path per Job 19 | ![Alt text](/src/site/resources/project_config_2.png?raw=true "Example Project Configuration") 20 | 21 | ## Project Configuration - Ant Plugin vs. Ant-In-Workspace Plugin 22 | Default Ant-Plugin lets you choose between various Ant versions. Ant-In-Workspace Plugin will choose either the globally configured Ant or the project wise configured one. 23 | ![Alt text](/src/site/resources/project_config_1.png?raw=true "Example Project Configuration") 24 | 25 | # Global Configuration 26 | Configuring the global Path. 27 | 28 | ![Alt text](/src/site/resources/global_config.png?raw=true "Example Project Configuration") 29 | 30 | # Continuous Delivery 31 | https://ci.jenkins.io/job/Plugins/job/ant-in-workspace-plugin/ 32 | 33 | # Technical Shortcuts 34 | ``` 35 | curl -kv --no-proxy 192.168.56.101:8080 http://192.168.56.101:8080/pluginManager/uploadPlugin -u admin:admin -F file=@target/ant-in-workspace.hpi 36 | curl -kv --no-proxy 192.168.56.102:8080 http://192.168.56.102:8080/safeRestart -F Submit=Yes -X POST 37 | ``` 38 | ## Authors 39 | Stephan Watermeyer 40 | 41 | ## License 42 | Licensed under the [MIT License (MIT)](https://github.com/heremaps/buildrotator-plugin/blob/master/LICENSE). 43 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.jenkins-ci.plugins 7 | plugin 8 | 5.26 9 | 10 | 11 | 12 | ant-in-workspace 13 | 1.2.3-SNAPSHOT 14 | hpi 15 | 16 | Ant In Workspace 17 | Plugin extends official Ant Plugin. Allows to use an Ant that is located in the Workspace. 18 | https://github.com/jenkinsci/ant-in-workspace-plugin/blob/master/README.md 19 | 20 | 21 | scm:git:git@github.com:jenkinsci/ant-in-workspace-plugin.git 22 | scm:git:git@github.com:jenkinsci/ant-in-workspace-plugin.git 23 | https://github.com/jenkinsci/${project.artifactId}-plugin 24 | ant-in-workspace-0.0.1 25 | 26 | 27 | 28 | UTF-8 29 | UTF-8 30 | 31 | 2.479 32 | ${jenkins.baseline}.3 33 | 608.v67378e9d3db_1 34 | 35 | 36 | 37 | 38 | io.jenkins.tools.bom 39 | bom-${jenkins.baseline}.x 40 | 5054.v620b_5d2b_d5e6 41 | pom 42 | import 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.jenkins-ci.plugins 50 | ant 51 | 52 | 53 | 54 | 55 | org.jenkins-ci.plugins.workflow 56 | workflow-step-api 57 | true 58 | 59 | 60 | org.jenkins-ci.plugins.workflow 61 | workflow-job 62 | true 63 | 64 | 65 | org.jenkins-ci.plugins.workflow 66 | workflow-aggregator 67 | ${workflow.version} 68 | test 69 | 70 | 71 | org.jenkins-ci.plugins.workflow 72 | workflow-step-api 73 | tests 74 | test 75 | 76 | 77 | org.jenkins-ci.plugins 78 | script-security 79 | 80 | 81 | 82 | 83 | 84 | 85 | MIT License 86 | http://opensource.org/licenses/MIT 87 | 88 | 89 | 90 | 91 | 92 | repo.jenkins-ci.org 93 | https://repo.jenkins-ci.org/public/ 94 | 95 | 96 | 97 | 98 | 99 | repo.jenkins-ci.org 100 | https://repo.jenkins-ci.org/public/ 101 | 102 | 103 | 104 | 105 | 106 | 107 | 109 | 110 | org.eclipse.m2e 111 | lifecycle-mapping 112 | 1.0.0 113 | 114 | 115 | 116 | 117 | 118 | 119 | org.jenkins-ci.tools 120 | 121 | 122 | maven-hpi-plugin 123 | 124 | 125 | [1.74,) 126 | 127 | 128 | validate 129 | 130 | resolve-test-dependencies 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/ant_in_workspace/AntInWorkspace.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.ant_in_workspace; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.logging.Level; 6 | import java.util.logging.Logger; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | import org.jenkinsci.Symbol; 11 | import org.kohsuke.stapler.DataBoundConstructor; 12 | import org.kohsuke.stapler.StaplerRequest2; 13 | 14 | import hudson.AbortException; 15 | import hudson.Extension; 16 | import hudson.FilePath; 17 | import hudson.Launcher; 18 | import hudson.model.AbstractBuild; 19 | import hudson.model.BuildListener; 20 | import hudson.remoting.VirtualChannel; 21 | import hudson.tasks.Ant; 22 | import net.sf.json.JSONObject; 23 | 24 | /** 25 | * 26 | * Jenkins plugin to provide the Ant from the current Workspace.
27 | * This is to support projects, that must use a specific version of Ant that is 28 | * (checked-in with the source code and is) available in the current workspace. 29 | * With this plugin you can use the checked-in Ant for building the current 30 | * project.
31 | * The plugin allows to configure a global path for the AntInWorkspace or a 32 | * per-Job configuration. 33 | * 34 | * @author stephan.watermeyer, Diebold Nixdorf 35 | */ 36 | public class AntInWorkspace extends Ant { 37 | 38 | private static final Logger LOGGER = Logger.getLogger(AntInWorkspace.class.getName()); 39 | 40 | /** Used to store the Workspace Directory on "perform" */ 41 | private String mPathToAnt; 42 | 43 | @DataBoundConstructor 44 | public AntInWorkspace(String targets, String antName, String antOpts, String buildFile, String properties) { 45 | super(targets, antName, antOpts, buildFile, properties); 46 | } 47 | 48 | @Override 49 | public DescriptorImpl getDescriptor() { 50 | return (DescriptorImpl) super.getDescriptor(); 51 | } 52 | 53 | /** 54 | * Return the Ant from super or if not defined the Ant from the workspace. 55 | */ 56 | public AntInstallation getAnt() { 57 | AntInstallation retVal = super.getAnt(); 58 | if (retVal != null) { 59 | LOGGER.log(Level.INFO, "use Ant from super: " + retVal.getHome()); 60 | } else if (mPathToAnt == null) { 61 | LOGGER.log(Level.INFO, "Path to Ant is not set. Cannot use Ant from workspace."); 62 | } else { 63 | LOGGER.log(Level.INFO, "use Ant from workspace: " + mPathToAnt); 64 | retVal = new AntInstallation("Ant In Workspace", mPathToAnt, null); 65 | } 66 | return retVal; 67 | } 68 | 69 | @Override 70 | public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { 71 | 72 | // Evaluate if the Job has a custom AntInWorkspace directory set. 73 | final String antInWorkspace; 74 | if (build.getEnvironment(listener).containsKey(AntInWorkspaceBuildWrapper.ENV_VAR_CUSTOM_ANT_IN_WORKSPACE)) { 75 | antInWorkspace = build.getEnvironment(listener).get(AntInWorkspaceBuildWrapper.ENV_VAR_CUSTOM_ANT_IN_WORKSPACE); 76 | } else { 77 | antInWorkspace = getDescriptor().getAntWorkspaceFolder(); 78 | } 79 | 80 | final FilePath toCheck = build.getWorkspace(); 81 | if (toCheck == null) { 82 | return false; 83 | } 84 | final String workspace = appendSeparatorIfNecessary(toCheck.getRemote()); 85 | 86 | // Important to store this into member variable 87 | mPathToAnt = workspace + antInWorkspace; 88 | 89 | final AntInstallation ant = getAnt(); 90 | if (ant != null && launcher.isUnix()) { 91 | validateAndMakeAntExecutable(build.getWorkspace(), ant); 92 | } 93 | return super.perform(build, launcher, listener); 94 | } 95 | 96 | void validateAndMakeAntExecutable(final FilePath pWorkspace, @Nonnull final AntInstallation pAnt) throws AbortException { 97 | final hudson.FilePath pathToAntBinary; 98 | final String pathToAntInWorkspace = pAnt.getHome() + "/bin/ant"; 99 | if ( pWorkspace != null && pWorkspace.isRemote()) { 100 | LOGGER.log(Level.FINE, "searching ANT on remote node"); 101 | final VirtualChannel channel = pWorkspace.getChannel(); 102 | pathToAntBinary = new hudson.FilePath(channel, pathToAntInWorkspace); 103 | } else { 104 | LOGGER.log(Level.FINE, "searching ANT on master"); 105 | pathToAntBinary = new hudson.FilePath(new File(pathToAntInWorkspace)); 106 | } 107 | 108 | try { 109 | if (!pathToAntBinary.exists()) { 110 | throw new AbortException("Ant does not exist in Workspace: " + pathToAntBinary.getRemote()); 111 | } 112 | 113 | LOGGER.log(Level.FINE, "Change file permissions: " + pathToAntBinary.getRemote()); 114 | pathToAntBinary.chmod(0755); 115 | } catch(AbortException e) { 116 | // just throw 117 | throw e; 118 | } catch (IOException e) { 119 | LOGGER.log(Level.WARNING, "failed to use ant", e); 120 | throw new AbortException("Unable to make Ant executable (IO Error): " + pathToAntBinary.getRemote()); 121 | } catch (InterruptedException e) { 122 | LOGGER.log(Level.WARNING, "failed to use ant2", e); 123 | throw new AbortException("Unable to make Ant executable (Interrupt): " + pathToAntBinary.getRemote()); 124 | } 125 | } 126 | 127 | @Extension 128 | @Symbol("antws") 129 | public static class DescriptorImpl extends Ant.DescriptorImpl { 130 | 131 | private String antWorkspaceFolder; 132 | 133 | public String getDisplayName() { 134 | return "Invoke Ant In Workspace"; 135 | } 136 | 137 | /** 138 | * No Choices should be given. We choose automatically the Ant from the 139 | * Workspace. 140 | */ 141 | public AntInstallation[] getInstallations() { 142 | return new AntInstallation[] {}; 143 | } 144 | 145 | @Override 146 | public boolean configure(StaplerRequest2 staplerRequest, JSONObject json) throws FormException { 147 | antWorkspaceFolder = json.getString("antWorkspaceFolder"); 148 | antWorkspaceFolder = appendSeparatorIfNecessary(antWorkspaceFolder); 149 | save(); 150 | return true; 151 | } 152 | 153 | public String getAntWorkspaceFolder() { 154 | if (antWorkspaceFolder == null) { 155 | LOGGER.log(Level.INFO, "Ant in Workspace is not configured. Return default: ''"); 156 | antWorkspaceFolder = ""; 157 | } 158 | return antWorkspaceFolder; 159 | } 160 | 161 | } 162 | 163 | /** 164 | * Checks if the given argument has and ending file separator. 165 | * 166 | * @param pPath 167 | * the path to check 168 | * @return the modified path 169 | */ 170 | static String appendSeparatorIfNecessary(String pPath) { 171 | String retVal = pPath; 172 | if (retVal != null && retVal.endsWith("/") == false) { 173 | retVal += "/"; 174 | } 175 | return retVal; 176 | } 177 | } 178 | --------------------------------------------------------------------------------