org.gradle.api.tasks.wrapper.Wrapper Maven / Gradle / Ivy
Show all versions of gradle-api Show documentation
/*
* Copyright 2010 the original author or authors.
*
* Licensed 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.gradle.api.tasks.wrapper;
import com.google.common.io.ByteStreams;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.internal.file.FileLookup;
import org.gradle.api.internal.file.FileResolver;
import org.gradle.api.internal.plugins.StartScriptGenerator;
import org.gradle.api.internal.tasks.options.Option;
import org.gradle.api.internal.tasks.options.OptionValues;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.IoActions;
import org.gradle.internal.UncheckedException;
import org.gradle.util.DistributionLocator;
import org.gradle.util.GUtil;
import org.gradle.util.GradleVersion;
import org.gradle.util.WrapUtil;
import org.gradle.wrapper.GradleWrapperMain;
import org.gradle.wrapper.Install;
import org.gradle.wrapper.WrapperExecutor;
import javax.inject.Inject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Generates scripts (for *nix and windows) which allow you to build your project with Gradle, without having to
* install Gradle.
*
*
When a user executes a wrapper script the first time, the script downloads and installs the appropriate Gradle
* distribution and runs the build against this downloaded distribution. Any installed Gradle distribution is ignored
* when using the wrapper scripts.
*
*
The scripts generated by this task are intended to be committed to your version control system. This task also
* generates a small {@code gradle-wrapper.jar} bootstrap JAR file and properties file which should also be committed to
* your VCS. The scripts delegates to this JAR.
*/
public class Wrapper extends DefaultTask {
public static final String DEFAULT_DISTRIBUTION_PARENT_NAME = Install.DEFAULT_DISTRIBUTION_PATH;
/**
* Specifies the Gradle distribution type.
*/
public enum DistributionType {
/**
* binary-only Gradle distribution without sources and documentation
*/
BIN,
/**
* complete Gradle distribution with binaries, sources and documentation
*/
ALL
}
/**
* Specifies how the wrapper path should be interpreted.
*/
public enum PathBase {
PROJECT, GRADLE_USER_HOME
}
private Object scriptFile;
private Object jarFile;
private String distributionPath;
private PathBase distributionBase = PathBase.GRADLE_USER_HOME;
private String distributionUrl;
private GradleVersion gradleVersion;
private DistributionType distributionType = DistributionType.BIN;
private String archivePath;
private PathBase archiveBase = PathBase.GRADLE_USER_HOME;
private final DistributionLocator locator = new DistributionLocator();
public Wrapper() {
scriptFile = "gradlew";
jarFile = "gradle/wrapper/gradle-wrapper.jar";
distributionPath = DEFAULT_DISTRIBUTION_PARENT_NAME;
archivePath = DEFAULT_DISTRIBUTION_PARENT_NAME;
gradleVersion = GradleVersion.current();
}
@Inject
protected FileLookup getFileLookup() {
throw new UnsupportedOperationException();
}
@TaskAction
void generate() {
File jarFileDestination = getJarFile();
File unixScript = getScriptFile();
FileResolver resolver = getFileLookup().getFileResolver(unixScript.getParentFile());
String jarFileRelativePath = resolver.resolveAsRelativePath(jarFileDestination);
writeProperties(getPropertiesFile());
writeWrapperTo(jarFileDestination);
StartScriptGenerator generator = new StartScriptGenerator();
generator.setApplicationName("Gradle");
generator.setMainClassName(GradleWrapperMain.class.getName());
generator.setClasspath(WrapUtil.toList(jarFileRelativePath));
generator.setOptsEnvironmentVar("GRADLE_OPTS");
generator.setExitEnvironmentVar("GRADLE_EXIT_CONSOLE");
generator.setAppNameSystemProperty("org.gradle.appname");
generator.setScriptRelPath(unixScript.getName());
generator.generateUnixScript(unixScript);
generator.generateWindowsScript(getBatchScript());
}
private void writeWrapperTo(File destination) {
InputStream gradleWrapperJar = Wrapper.class.getResourceAsStream("/gradle-wrapper.jar");
if (gradleWrapperJar == null) {
throw new GradleException("Cannot locate wrapper JAR resource.");
}
ZipInputStream zipInputStream = null;
ZipOutputStream zipOutputStream = null;
try {
zipInputStream = new ZipInputStream(gradleWrapperJar);
zipOutputStream = new ZipOutputStream(new FileOutputStream(destination));
for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream.getNextEntry()) {
zipOutputStream.putNextEntry(entry);
if (!entry.isDirectory()) {
ByteStreams.copy(zipInputStream, zipOutputStream);
}
zipOutputStream.closeEntry();
}
addBuildReceipt(zipOutputStream);
} catch (IOException e) {
throw UncheckedException.throwAsUncheckedException(e);
} finally {
IoActions.closeQuietly(zipInputStream);
IoActions.closeQuietly(zipOutputStream);
}
}
private void addBuildReceipt(ZipOutputStream zipOutputStream) throws IOException {
ZipEntry buildReceipt = new ZipEntry("build-receipt.properties");
zipOutputStream.putNextEntry(buildReceipt);
String contents = "versionNumber=" + GradleVersion.current().getVersion();
zipOutputStream.write(contents.getBytes(StandardCharsets.ISO_8859_1));
zipOutputStream.closeEntry();
}
private void writeProperties(File propertiesFileDestination) {
Properties wrapperProperties = new Properties();
wrapperProperties.put(WrapperExecutor.DISTRIBUTION_URL_PROPERTY, getDistributionUrl());
wrapperProperties.put(WrapperExecutor.DISTRIBUTION_BASE_PROPERTY, distributionBase.toString());
wrapperProperties.put(WrapperExecutor.DISTRIBUTION_PATH_PROPERTY, distributionPath);
wrapperProperties.put(WrapperExecutor.ZIP_STORE_BASE_PROPERTY, archiveBase.toString());
wrapperProperties.put(WrapperExecutor.ZIP_STORE_PATH_PROPERTY, archivePath);
GUtil.saveProperties(wrapperProperties, propertiesFileDestination);
}
/**
* Returns the file to write the wrapper script to.
*/
@OutputFile
public File getScriptFile() {
return getProject().file(scriptFile);
}
/**
* The file to write the wrapper script to.
*/
public void setScriptFile(Object scriptFile) {
this.scriptFile = scriptFile;
}
/**
* Returns the file to write the wrapper batch script to.
*/
@OutputFile
public File getBatchScript() {
File scriptFile = getScriptFile();
return new File(scriptFile.getParentFile(), scriptFile.getName().replaceFirst("(\\.[^\\.]+)?$", ".bat"));
}
/**
* Returns the file to write the wrapper jar file to.
*/
@OutputFile
public File getJarFile() {
return getProject().file(jarFile);
}
/**
* The file to write the wrapper jar file to.
*/
public void setJarFile(Object jarFile) {
this.jarFile = jarFile;
}
/**
* Returns the file to write the wrapper properties to.
*/
@OutputFile
public File getPropertiesFile() {
File jarFileDestination = getJarFile();
return new File(jarFileDestination.getParentFile(), jarFileDestination.getName().replaceAll("\\.jar$",
".properties"));
}
/**
* Returns the path where the gradle distributions needed by the wrapper are unzipped. The path is relative to the
* distribution base directory
*
* @see #setDistributionPath(String)
*/
@Input
public String getDistributionPath() {
return distributionPath;
}
/**
* Sets the path where the gradle distributions needed by the wrapper are unzipped. The path is relative to the
* distribution base directory
*
* @see #setDistributionPath(String)
*/
public void setDistributionPath(String distributionPath) {
this.distributionPath = distributionPath;
}
/**
* Returns the gradle version for the wrapper.
*
* @see #setGradleVersion(String)
*/
@Input
public String getGradleVersion() {
return gradleVersion.getVersion();
}
/**
* The version of the gradle distribution required by the wrapper. This is usually the same version of Gradle you
* use for building your project.
*/
@Option(option = "gradle-version", description = "The version of the Gradle distribution required by the wrapper.")
public void setGradleVersion(String gradleVersion) {
this.gradleVersion = GradleVersion.version(gradleVersion);
}
/**
* Returns the type of the Gradle distribution to be used by the wrapper.
*
* @see #setDistributionType(DistributionType)
*/
@Input
public DistributionType getDistributionType() {
return distributionType;
}
/**
* The type of the Gradle distribution to be used by the wrapper. By default, this is {@link DistributionType#BIN},
* which is the binary-only Gradle distribution without documentation.
*
* @see DistributionType
*/
@Option(option = "distribution-type", description = "The type of the Gradle distribution to be used by the wrapper.")
public void setDistributionType(DistributionType distributionType) {
this.distributionType = distributionType;
}
/**
* The list of available gradle distribution types.
*/
@OptionValues("distribution-type")
public List getAvailableDistributionTypes() {
return Arrays.asList(DistributionType.values());
}
/**
* The URL to download the gradle distribution from.
*
* If not set, the download URL is the default for the specified {@link #getGradleVersion()}.
*
*
If {@link #getGradleVersion()} is not set, will return null.
*
*
The wrapper downloads a certain distribution only once and caches it. If your distribution base is the
* project, you might submit the distribution to your version control system. That way no download is necessary at
* all. This might be in particular interesting, if you provide a custom gradle snapshot to the wrapper, because you
* don't need to provide a download server then.
*/
@Input
public String getDistributionUrl() {
if (distributionUrl != null) {
return distributionUrl;
} else if (gradleVersion != null) {
return locator.getDistributionFor(gradleVersion, distributionType.name().toLowerCase(Locale.ENGLISH)).toString();
} else {
return null;
}
}
/**
* The URL to download the gradle distribution from.
*
*
If not set, the download URL is the default for the specified {@link #getGradleVersion()}.
*
*
If {@link #getGradleVersion()} is not set, will return null.
*
*
The wrapper downloads a certain distribution only once and caches it. If your distribution base is the
* project, you might submit the distribution to your version control system. That way no download is necessary at
* all. This might be in particular interesting, if you provide a custom gradle snapshot to the wrapper, because you
* don't need to provide a download server then.
*/
@Option(option = "gradle-distribution-url", description = "The URL to download the Gradle distribution from.")
public void setDistributionUrl(String url) {
this.distributionUrl = url;
}
/**
* The distribution base specifies whether the unpacked wrapper distribution should be stored in the project or in
* the gradle user home dir.
*/
@Input
public PathBase getDistributionBase() {
return distributionBase;
}
/**
* The distribution base specifies whether the unpacked wrapper distribution should be stored in the project or in
* the gradle user home dir.
*/
public void setDistributionBase(PathBase distributionBase) {
this.distributionBase = distributionBase;
}
/**
* Returns the path where the gradle distributions archive should be saved (i.e. the parent dir). The path is
* relative to the archive base directory.
*/
@Input
public String getArchivePath() {
return archivePath;
}
/**
* Set's the path where the gradle distributions archive should be saved (i.e. the parent dir). The path is relative
* to the parent dir specified with {@link #getArchiveBase()}.
*/
public void setArchivePath(String archivePath) {
this.archivePath = archivePath;
}
/**
* The archive base specifies whether the unpacked wrapper distribution should be stored in the project or in the
* gradle user home dir.
*/
@Input
public PathBase getArchiveBase() {
return archiveBase;
}
/**
* The archive base specifies whether the unpacked wrapper distribution should be stored in the project or in the
* gradle user home dir.
*/
public void setArchiveBase(PathBase archiveBase) {
this.archiveBase = archiveBase;
}
}