mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: generate gradle wrapper with WrapperGenerator in 'generateGradleWrapper' task
This commit is contained in:
@@ -44,5 +44,6 @@ dependencies {
|
||||
|
||||
implementation(libs.common.jkotlin)
|
||||
implementation(libs.common.antlr4)
|
||||
implementation(libs.google.gson)
|
||||
implementation(libs.google.java.format)
|
||||
}
|
||||
|
||||
+6
-6
@@ -23,9 +23,9 @@ import com.android.build.api.variant.AndroidComponentsExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.itsaky.androidide.plugins.tasks.AddAndroidJarToAssetsTask
|
||||
import com.itsaky.androidide.plugins.tasks.AddFileToAssetsTask
|
||||
import com.itsaky.androidide.plugins.tasks.SetupAapt2Task
|
||||
import com.itsaky.androidide.plugins.tasks.GenerateInitScriptTask
|
||||
import com.itsaky.androidide.plugins.tasks.GradleWrapperBuilderTask
|
||||
import com.itsaky.androidide.plugins.tasks.GradleWrapperGeneratorTask
|
||||
import com.itsaky.androidide.plugins.tasks.SetupAapt2Task
|
||||
import com.itsaky.androidide.plugins.util.SdkUtils.getAndroidJar
|
||||
import downloadVersion
|
||||
import org.gradle.api.Plugin
|
||||
@@ -51,8 +51,8 @@ class AndroidIDEAssetsPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(target: Project) {
|
||||
target.run {
|
||||
val wrapperBuilderTaskProvider = tasks.register("generateGradleWrapper",
|
||||
GradleWrapperBuilderTask::class.java
|
||||
val wrapperGeneratorTaskProvider = tasks.register("generateGradleWrapper",
|
||||
GradleWrapperGeneratorTask::class.java
|
||||
)
|
||||
|
||||
val androidComponentsExtension = extensions.getByType(AndroidComponentsExtension::class.java)
|
||||
@@ -76,8 +76,8 @@ class AndroidIDEAssetsPlugin : Plugin<Project> {
|
||||
|
||||
val variantNameCapitalized = variant.name.capitalized()
|
||||
|
||||
variant.sources.assets?.addGeneratedSourceDirectory(wrapperBuilderTaskProvider,
|
||||
GradleWrapperBuilderTask::outputDirectory)
|
||||
variant.sources.assets?.addGeneratedSourceDirectory(wrapperGeneratorTaskProvider,
|
||||
GradleWrapperGeneratorTask::outputDirectory)
|
||||
|
||||
variant.sources.assets?.addGeneratedSourceDirectory(addAndroidJarTaskProvider,
|
||||
AddAndroidJarToAssetsTask::outputDirectory)
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2022 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 com.itsaky.androidide.plugins.tasks;
|
||||
|
||||
import static org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources.LATEST;
|
||||
import static org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources.NIGHTLY;
|
||||
import static org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources.RELEASE_CANDIDATE;
|
||||
import static org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources.RELEASE_NIGHTLY;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.resources.TextResource;
|
||||
import org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources;
|
||||
import org.gradle.util.GradleVersion;
|
||||
|
||||
class GradleVersionResolver {
|
||||
|
||||
private TextResource latest;
|
||||
private TextResource releaseCandidate;
|
||||
private TextResource nightly;
|
||||
private TextResource releaseNightly;
|
||||
|
||||
private GradleVersion gradleVersion;
|
||||
private String gradleVersionString = GradleVersion.current().getVersion();
|
||||
|
||||
void setTextResources(TextResource latest, TextResource releaseCandidate, TextResource nightly,
|
||||
TextResource releaseNightly) {
|
||||
this.latest = latest;
|
||||
this.releaseCandidate = releaseCandidate;
|
||||
this.nightly = nightly;
|
||||
this.releaseNightly = releaseNightly;
|
||||
}
|
||||
|
||||
String resolve(String version) {
|
||||
if (version == null) {
|
||||
return GradleVersion.current().getVersion();
|
||||
}
|
||||
switch (version) {
|
||||
case LATEST:
|
||||
return getVersion(latest.asString(), version);
|
||||
case NIGHTLY:
|
||||
return getVersion(nightly.asString(), version);
|
||||
case RELEASE_NIGHTLY:
|
||||
return getVersion(releaseNightly.asString(), version);
|
||||
case RELEASE_CANDIDATE:
|
||||
return getVersion(releaseCandidate.asString(), version);
|
||||
default:
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
static String getVersion(String json, String placeHolder) {
|
||||
Type type = new TypeToken<Map<String, String>>() {
|
||||
}.getType();
|
||||
Map<String, String> map = new Gson().fromJson(json, type);
|
||||
String version = map.get("version");
|
||||
if (version == null) {
|
||||
throw new GradleException(
|
||||
"There is currently no version information available for '" + placeHolder + "'.");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
static boolean isPlaceHolder(String version) {
|
||||
return DefaultWrapperVersionsResources.PLACE_HOLDERS.contains(version);
|
||||
}
|
||||
|
||||
GradleVersion getGradleVersion() {
|
||||
if (gradleVersion == null) {
|
||||
gradleVersion = GradleVersion.version(resolve(gradleVersionString));
|
||||
}
|
||||
return gradleVersion;
|
||||
}
|
||||
|
||||
void setGradleVersionString(String gradleVersionString) {
|
||||
if (!isPlaceHolder(gradleVersionString)) {
|
||||
this.gradleVersion = GradleVersion.version(gradleVersionString);
|
||||
}
|
||||
if (this.gradleVersionString != gradleVersionString) {
|
||||
this.gradleVersionString = gradleVersionString;
|
||||
this.gradleVersion = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
-23
@@ -21,8 +21,8 @@ import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.wrapper.Wrapper
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.zip.ZipOutputStream
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class GradleWrapperBuilderTask : DefaultTask() {
|
||||
abstract class GradleWrapperGeneratorTask : DefaultTask() {
|
||||
|
||||
/**
|
||||
* The output directory.
|
||||
@@ -42,14 +42,6 @@ abstract class GradleWrapperBuilderTask : DefaultTask() {
|
||||
companion object {
|
||||
|
||||
private const val GRADLE_VERSION = "7.4.2"
|
||||
|
||||
private val GRADLE_PROPERTIES_CONTENTS = """
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@@ -63,24 +55,37 @@ abstract class GradleWrapperBuilderTask : DefaultTask() {
|
||||
destFile.delete()
|
||||
}
|
||||
|
||||
val stagingDir = File(outputDirectory, "staging")
|
||||
if (stagingDir.exists()) {
|
||||
stagingDir.deleteRecursively()
|
||||
}
|
||||
stagingDir.mkdirs()
|
||||
|
||||
// Generate the files
|
||||
val generator = IDEWrapperGenerator()
|
||||
generator.jarFile = File(stagingDir, "gradle/wrapper/gradle-wrapper.jar")
|
||||
generator.scriptFile = File(stagingDir, "gradlew")
|
||||
generator.gradleVersion = GRADLE_VERSION
|
||||
generator.distributionType = Wrapper.DistributionType.BIN
|
||||
|
||||
generator.generate(project)
|
||||
|
||||
// Archive all generated files
|
||||
ZipOutputStream(destFile.outputStream().buffered()).use { zipOut ->
|
||||
|
||||
// Add static files
|
||||
for (file in arrayOf("gradlew", "gradlew.bat", "gradle/wrapper/gradle-wrapper.jar")) {
|
||||
val fileIn = File(project.rootProject.rootDir, file)
|
||||
val entry = ZipEntry(file)
|
||||
zipOut.putNextEntry(entry)
|
||||
fileIn.inputStream().buffered().use { fileInStream ->
|
||||
fileInStream.transferTo(zipOut)
|
||||
stagingDir.walk(direction = FileWalkDirection.TOP_DOWN)
|
||||
.filter { it.isFile }
|
||||
.forEach { file ->
|
||||
val entry = ZipEntry(file.relativeTo(stagingDir).path)
|
||||
zipOut.putNextEntry(entry)
|
||||
file.inputStream().buffered().use { fileInStream ->
|
||||
fileInStream.transferTo(zipOut)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zipOut.putNextEntry(ZipEntry("gradle/wrapper/gradle-wrapper.properties"))
|
||||
zipOut.write(GRADLE_PROPERTIES_CONTENTS.toByteArray(charset = StandardCharsets.UTF_8))
|
||||
|
||||
zipOut.flush()
|
||||
}
|
||||
|
||||
destFile.setLastModified(System.currentTimeMillis())
|
||||
// finally, delete the staging directory
|
||||
stagingDir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
+474
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2022 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 com.itsaky.androidide.plugins.tasks;
|
||||
|
||||
import com.itsaky.androidide.plugins.tasks.internal.WrapperDefaults;
|
||||
import com.itsaky.androidide.plugins.tasks.internal.WrapperGenerator;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import kotlin.io.FilesKt;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Incubating;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.UncheckedIOException;
|
||||
import org.gradle.api.internal.file.FileLookup;
|
||||
import org.gradle.api.internal.file.FileOperations;
|
||||
import org.gradle.api.internal.file.FileResolver;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.options.Option;
|
||||
import org.gradle.api.tasks.options.OptionValues;
|
||||
import org.gradle.api.tasks.wrapper.Wrapper.DistributionType;
|
||||
import org.gradle.api.tasks.wrapper.Wrapper.PathBase;
|
||||
import org.gradle.api.tasks.wrapper.WrapperVersionsResources;
|
||||
import org.gradle.api.tasks.wrapper.internal.DefaultWrapperVersionsResources;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.gradle.util.internal.GUtil;
|
||||
import org.gradle.util.internal.WrapperDistributionUrlConverter;
|
||||
import org.gradle.wrapper.Download;
|
||||
import org.gradle.wrapper.Logger;
|
||||
import org.gradle.wrapper.WrapperExecutor;
|
||||
|
||||
/**
|
||||
* <p>Generates scripts (for *nix and windows) which allow you to build your project with Gradle,
|
||||
* without having to install Gradle.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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 IDEWrapperGenerator {
|
||||
|
||||
public static final String DEFAULT_DISTRIBUTION_PARENT_NAME = WrapperDefaults.DISTRIBUTION_PATH;
|
||||
|
||||
private File scriptFile = new File(WrapperDefaults.SCRIPT_PATH);
|
||||
private File jarFile = new File(WrapperDefaults.JAR_FILE_PATH);
|
||||
private String distributionPath = DEFAULT_DISTRIBUTION_PARENT_NAME;
|
||||
private PathBase distributionBase = WrapperDefaults.DISTRIBUTION_BASE;
|
||||
private String distributionUrl;
|
||||
private String distributionSha256Sum;
|
||||
private final GradleVersionResolver gradleVersionResolver = new GradleVersionResolver();
|
||||
private DistributionType distributionType = WrapperDefaults.DISTRIBUTION_TYPE;
|
||||
private String archivePath = WrapperDefaults.ARCHIVE_PATH;
|
||||
private PathBase archiveBase = WrapperDefaults.ARCHIVE_BASE;
|
||||
private final int networkTimeout = WrapperDefaults.NETWORK_TIMEOUT;
|
||||
private boolean distributionUrlConfigured = false;
|
||||
|
||||
void generate(Project project) {
|
||||
final var isOffline = project.getGradle().getStartParameter().isOffline();
|
||||
File jarFileDestination = getJarFile();
|
||||
File unixScript = getScriptFile();
|
||||
File propertiesFile = getPropertiesFile();
|
||||
Properties existingProperties =
|
||||
propertiesFile.exists() ? GUtil.loadProperties(propertiesFile) : null;
|
||||
|
||||
checkProperties(existingProperties);
|
||||
validateDistributionUrl(propertiesFile.getParentFile(), isOffline);
|
||||
|
||||
WrapperGenerator.generate(archiveBase, archivePath, distributionBase, distributionPath,
|
||||
getDistributionSha256Sum(existingProperties), propertiesFile, jarFileDestination,
|
||||
FilesKt.relativeTo(jarFileDestination, unixScript.getParentFile()).getPath(), unixScript, getBatchScript(), getDistributionUrl(),
|
||||
getValidateDistributionUrl(), networkTimeout);
|
||||
}
|
||||
|
||||
private void checkProperties(Properties existingProperties) {
|
||||
String checksumProperty = existingProperties != null ? existingProperties.getProperty(
|
||||
WrapperExecutor.DISTRIBUTION_SHA_256_SUM, null) : null;
|
||||
|
||||
if (!isCurrentVersion() && distributionSha256Sum == null && checksumProperty != null) {
|
||||
throw new GradleException(
|
||||
"gradle-wrapper.properties contains distributionSha256Sum property, but the wrapper configuration does not have one. Specify one in the wrapper task configuration or with the --gradle-distribution-sha256-sum task option");
|
||||
}
|
||||
}
|
||||
|
||||
private static final String DISTRIBUTION_URL_EXCEPTION_MESSAGE = "Test of distribution url %s failed. Please check the values set with --gradle-distribution-url and --gradle-version.";
|
||||
|
||||
private void validateDistributionUrl(File uriRoot, boolean isOffline) {
|
||||
if (distributionUrlConfigured && getValidateDistributionUrl()) {
|
||||
String url = getDistributionUrl();
|
||||
URI uri = getDistributionUri(uriRoot, url);
|
||||
if (uri.getScheme().equals("file")) {
|
||||
if (!Files.exists(Paths.get(uri).toAbsolutePath())) {
|
||||
throw new UncheckedIOException(String.format(DISTRIBUTION_URL_EXCEPTION_MESSAGE, url));
|
||||
}
|
||||
} else if (uri.getScheme().startsWith("http") && !isOffline) {
|
||||
try {
|
||||
new Download(new Logger(true), "gradlew", Download.UNKNOWN_VERSION).sendHeadRequest(uri);
|
||||
} catch (Exception e) {
|
||||
throw new UncheckedIOException(String.format(DISTRIBUTION_URL_EXCEPTION_MESSAGE, url), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static URI getDistributionUri(File uriRoot, String url) {
|
||||
try {
|
||||
return WrapperDistributionUrlConverter.convertDistributionUrl(url, uriRoot);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new GradleException("Distribution URL String cannot be parsed: " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDistributionSha256Sum(Properties existingProperties) {
|
||||
if (distributionSha256Sum != null) {
|
||||
return distributionSha256Sum;
|
||||
} else if (isCurrentVersion() && existingProperties != null) {
|
||||
return existingProperties.getProperty(WrapperExecutor.DISTRIBUTION_SHA_256_SUM, null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCurrentVersion() {
|
||||
return GradleVersion.current().equals(gradleVersionResolver.getGradleVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file to write the wrapper script to.
|
||||
*/
|
||||
|
||||
public File getScriptFile() {
|
||||
return scriptFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file to write the wrapper script to.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setScriptFile(File scriptFile) {
|
||||
this.scriptFile = scriptFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file to write the wrapper batch script to.
|
||||
*/
|
||||
|
||||
public File getBatchScript() {
|
||||
return WrapperGenerator.getBatchScript(getScriptFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file to write the wrapper jar file to.
|
||||
*/
|
||||
|
||||
public File getJarFile() {
|
||||
return this.jarFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file to write the wrapper jar file to.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setJarFile(File jarFile) {
|
||||
this.jarFile = jarFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file to write the wrapper properties to.
|
||||
*/
|
||||
|
||||
public File getPropertiesFile() {
|
||||
return WrapperGenerator.getPropertiesFile(getJarFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Wrapper versions resources.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
@Incubating
|
||||
public void setWrapperVersionsResources(WrapperVersionsResources wrapperVersionsResources) {
|
||||
DefaultWrapperVersionsResources defaultWrapperVersionsResources = (DefaultWrapperVersionsResources) wrapperVersionsResources;
|
||||
gradleVersionResolver.setTextResources(defaultWrapperVersionsResources.getLatest(),
|
||||
defaultWrapperVersionsResources.getReleaseCandidate(),
|
||||
defaultWrapperVersionsResources.getNightly(),
|
||||
defaultWrapperVersionsResources.getReleaseNightly());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gradle version for the wrapper.
|
||||
*
|
||||
* @throws GradleException if the label that can be provided via {@link #setGradleVersion(String)}
|
||||
* can not be resolved at the moment. For example, there is not a
|
||||
* `release-candidate` available at all times.
|
||||
* @see #setGradleVersion(String)
|
||||
*/
|
||||
|
||||
public String getGradleVersion() {
|
||||
return gradleVersionResolver.getGradleVersion().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. The following labels are allowed to
|
||||
* specify a version: {@code latest}, {@code release-candidate}, {@code nightly}, and
|
||||
* {@code release-nightly}
|
||||
*
|
||||
* <p>The resulting distribution url is validated before it is written to the
|
||||
* gradle-wrapper.properties file.
|
||||
*/
|
||||
@Option(option = "gradle-version", description =
|
||||
"The version of the Gradle distribution required by the wrapper. "
|
||||
+ "The following labels are allowed: latest, release-candidate, nightly, and release-nightly.")
|
||||
public void setGradleVersion(String gradleVersion) {
|
||||
distributionUrlConfigured = true;
|
||||
this.gradleVersionResolver.setGradleVersionString(gradleVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the Gradle distribution to be used by the wrapper.
|
||||
*
|
||||
* @see #setDistributionType(DistributionType)
|
||||
*/
|
||||
|
||||
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<DistributionType> getAvailableDistributionTypes() {
|
||||
return Arrays.asList(DistributionType.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to download the gradle distribution from.
|
||||
*
|
||||
* <p>If not set, the download URL is the default for the specified {@link #getGradleVersion()}.
|
||||
*
|
||||
* <p>If {@link #getGradleVersion()} is not set, will return null.
|
||||
*
|
||||
* <p>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.
|
||||
*/
|
||||
|
||||
public String getDistributionUrl() {
|
||||
if (distributionUrl != null) {
|
||||
return distributionUrl;
|
||||
}
|
||||
|
||||
return WrapperGenerator.getDistributionUrl(gradleVersionResolver.getGradleVersion(),
|
||||
distributionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to download the gradle distribution from.
|
||||
*
|
||||
* <p>If not set, the download URL is the default for the specified {@link #getGradleVersion()}.
|
||||
*
|
||||
* <p>If {@link #getGradleVersion()} is not set, will return null.
|
||||
*
|
||||
* <p>The wrapper downloads a certain distribution 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.
|
||||
*
|
||||
* <p>The distribution url is validated before it is written to the gradle-wrapper.properties
|
||||
* file.
|
||||
*/
|
||||
@Option(option = "gradle-distribution-url", description = "The URL to download the Gradle distribution from.")
|
||||
public void setDistributionUrl(String url) {
|
||||
distributionUrlConfigured = true;
|
||||
this.distributionUrl = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SHA-256 hash sum of the gradle distribution.
|
||||
*
|
||||
* <p>If not set, the hash sum of the gradle distribution is not verified.
|
||||
*
|
||||
* <p>The wrapper allows for verification of the downloaded Gradle distribution via SHA-256 hash
|
||||
* sum comparison. This increases security against targeted attacks by preventing a
|
||||
* man-in-the-middle attacker from tampering with the downloaded Gradle distribution.
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
@Nullable
|
||||
@Optional
|
||||
|
||||
public String getDistributionSha256Sum() {
|
||||
return distributionSha256Sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SHA-256 hash sum of the gradle distribution.
|
||||
*
|
||||
* <p>If not set, the hash sum of the gradle distribution is not verified.
|
||||
*
|
||||
* <p>The wrapper allows for verification of the downloaded Gradle distribution via SHA-256 hash
|
||||
* sum comparison. This increases security against targeted attacks by preventing a
|
||||
* man-in-the-middle attacker from tampering with the downloaded Gradle distribution.
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
@Option(option = "gradle-distribution-sha256-sum", description = "The SHA-256 hash sum of the gradle distribution.")
|
||||
public void setDistributionSha256Sum(@Nullable String distributionSha256Sum) {
|
||||
this.distributionSha256Sum = distributionSha256Sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* The distribution base specifies whether the unpacked wrapper distribution should be stored in
|
||||
* the project or in the gradle user home dir.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* The network timeout specifies how many ms to wait for when the wrapper is performing network
|
||||
* operations, such as downloading the wrapper jar.
|
||||
*
|
||||
* @since 7.6
|
||||
*/
|
||||
|
||||
@Incubating
|
||||
@Optional
|
||||
@Option(option = "network-timeout", description = "Timeout in ms to use when the wrapper is performing network operations.")
|
||||
public Integer getNetworkTimeout() {
|
||||
return networkTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this task will validate the distribution url that has been configured.
|
||||
*
|
||||
* @return whether this task will validate the distribution url
|
||||
* @since 8.2
|
||||
*/
|
||||
@Incubating
|
||||
|
||||
@Option(option = "validate-url", description = "Sets task to validate the configured distribution url.")
|
||||
public Boolean getValidateDistributionUrl() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Inject
|
||||
protected FileLookup getFileLookup() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins.tasks.internal;
|
||||
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.api.tasks.wrapper.Wrapper;
|
||||
import org.gradle.wrapper.Install;
|
||||
|
||||
@NonNullApi
|
||||
public class WrapperDefaults {
|
||||
public static final String SCRIPT_PATH = "gradlew";
|
||||
public static final String JAR_FILE_PATH = "gradle/wrapper/gradle-wrapper.jar";
|
||||
public static final Wrapper.DistributionType DISTRIBUTION_TYPE = Wrapper.DistributionType.BIN;
|
||||
|
||||
public static final String DISTRIBUTION_PATH = Install.DEFAULT_DISTRIBUTION_PATH;
|
||||
public static final Wrapper.PathBase DISTRIBUTION_BASE = Wrapper.PathBase.GRADLE_USER_HOME;
|
||||
public static final String ARCHIVE_PATH = DISTRIBUTION_PATH;
|
||||
public static final Wrapper.PathBase ARCHIVE_BASE = DISTRIBUTION_BASE;
|
||||
|
||||
public static final int NETWORK_TIMEOUT = 10000;
|
||||
public static final boolean VALIDATE_DISTRIBUTION_URL = true;
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.plugins.tasks.internal;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.api.UncheckedIOException;
|
||||
import org.gradle.api.internal.plugins.StartScriptGenerator;
|
||||
import org.gradle.api.tasks.wrapper.Wrapper;
|
||||
import org.gradle.api.tasks.wrapper.Wrapper.PathBase;
|
||||
import org.gradle.internal.util.PropertiesUtils;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.gradle.util.internal.DistributionLocator;
|
||||
import org.gradle.util.internal.GFileUtils;
|
||||
import org.gradle.wrapper.GradleWrapperMain;
|
||||
import org.gradle.wrapper.WrapperExecutor;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@NonNullApi
|
||||
public class WrapperGenerator {
|
||||
|
||||
public static File getPropertiesFile(File jarFileDestination) {
|
||||
return new File(jarFileDestination.getParentFile(), jarFileDestination.getName().replaceAll("\\.jar$", ".properties"));
|
||||
}
|
||||
|
||||
public static File getBatchScript(File scriptFile) {
|
||||
return new File(scriptFile.getParentFile(), scriptFile.getName().replaceFirst("(\\.[^\\.]+)?$", ".bat"));
|
||||
}
|
||||
|
||||
public static String getDistributionUrl(GradleVersion gradleVersion, Wrapper.DistributionType distributionType) {
|
||||
String distType = distributionType.name().toLowerCase(Locale.ENGLISH);
|
||||
return new DistributionLocator().getDistributionFor(gradleVersion, distType).toASCIIString();
|
||||
}
|
||||
|
||||
public static void generate(
|
||||
PathBase archiveBase, String archivePath,
|
||||
PathBase distributionBase, String distributionPath,
|
||||
@Nullable String distributionSha256Sum,
|
||||
File wrapperPropertiesOutputFile,
|
||||
File wrapperJarOutputFile, String jarFileRelativePath,
|
||||
File unixScript, File batchScript,
|
||||
@Nullable String distributionUrl,
|
||||
boolean validateDistributionUrl,
|
||||
@Nullable Integer networkTimeout
|
||||
) {
|
||||
writeProperties(wrapperPropertiesOutputFile, distributionUrl, distributionSha256Sum, distributionBase, distributionPath, archiveBase, archivePath, networkTimeout, validateDistributionUrl);
|
||||
writeWrapperJar(wrapperJarOutputFile);
|
||||
writeScripts(jarFileRelativePath, unixScript, batchScript);
|
||||
}
|
||||
|
||||
private static void writeProperties(
|
||||
File propertiesFileDestination,
|
||||
@Nullable String distributionUrl,
|
||||
@Nullable String distributionSha256Sum,
|
||||
PathBase distributionBase,
|
||||
String distributionPath,
|
||||
PathBase archiveBase,
|
||||
String archivePath,
|
||||
@Nullable Integer networkTimeout,
|
||||
boolean validateDistributionUrl
|
||||
) {
|
||||
Properties wrapperProperties = new Properties();
|
||||
wrapperProperties.put(WrapperExecutor.DISTRIBUTION_URL_PROPERTY, distributionUrl);
|
||||
if (distributionSha256Sum != null) {
|
||||
wrapperProperties.put(WrapperExecutor.DISTRIBUTION_SHA_256_SUM, distributionSha256Sum);
|
||||
}
|
||||
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);
|
||||
if (networkTimeout != null) {
|
||||
wrapperProperties.put(WrapperExecutor.NETWORK_TIMEOUT_PROPERTY, String.valueOf(networkTimeout));
|
||||
}
|
||||
wrapperProperties.put(WrapperExecutor.VALIDATE_DISTRIBUTION_URL, String.valueOf(validateDistributionUrl));
|
||||
|
||||
GFileUtils.parentMkdirs(propertiesFileDestination);
|
||||
try {
|
||||
PropertiesUtils.store(wrapperProperties, propertiesFileDestination);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeWrapperJar(File destination) {
|
||||
URL jarFileSource = Wrapper.class.getResource("/gradle-wrapper.jar");
|
||||
if (jarFileSource == null) {
|
||||
throw new GradleException("Cannot locate wrapper JAR resource.");
|
||||
}
|
||||
try (InputStream in = jarFileSource.openStream(); OutputStream out = Files.newOutputStream(destination.toPath())) {
|
||||
ByteStreams.copy(in, out);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to write wrapper JAR to " + destination, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeScripts(String jarFileRelativePath, File unixScript, File batchScript) {
|
||||
StartScriptGenerator generator = new StartScriptGenerator();
|
||||
generator.setApplicationName("Gradle");
|
||||
generator.setMainClassName(GradleWrapperMain.class.getName());
|
||||
generator.setClasspath(singletonList(jarFileRelativePath));
|
||||
generator.setOptsEnvironmentVar("GRADLE_OPTS");
|
||||
generator.setExitEnvironmentVar("GRADLE_EXIT_CONSOLE");
|
||||
generator.setAppNameSystemProperty("org.gradle.appname");
|
||||
generator.setScriptRelPath(unixScript.getName());
|
||||
generator.setDefaultJvmOpts(ImmutableList.of("-Xmx64m", "-Xms64m"));
|
||||
generator.generateUnixScript(unixScript);
|
||||
generator.generateWindowsScript(batchScript);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user