├── .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 | [](https://ci.jenkins.io/job/Plugins/job/ant-in-workspace-plugin/job/master)
3 | [](https://github.com/jenkinsci/ant-in-workspace-plugin/graphs/contributors)
4 | [](https://plugins.jenkins.io/ant-in-workspace-plugin)
5 | [](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 | 
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 | 
24 |
25 | # Global Configuration
26 | Configuring the global Path.
27 |
28 | 
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 |
--------------------------------------------------------------------------------