diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java new file mode 100644 index 000000000..d3df0584f --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java @@ -0,0 +1,642 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.android.ide.eclipse.adt.internal.wizards.exportgradle; + +import static com.android.SdkConstants.GRADLE_LATEST_VERSION; +import static com.android.SdkConstants.GRADLE_PLUGIN_LATEST_VERSION; +import static com.android.SdkConstants.GRADLE_PLUGIN_NAME; +import static com.android.tools.lint.checks.GradleDetector.APP_PLUGIN_ID; +import static com.android.tools.lint.checks.GradleDetector.LIB_PLUGIN_ID; + +import com.android.SdkConstants; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.sdk.ProjectState; +import com.android.ide.eclipse.adt.internal.sdk.Sdk; +import com.android.ide.eclipse.adt.io.IFolderWrapper; +import com.android.io.IAbstractFile; +import com.android.sdklib.io.FileOp; +import com.android.xml.AndroidManifest; +import com.google.common.base.Charsets; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.io.Closeables; +import com.google.common.io.Files; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +/** + * Creates build.gradle and settings.gradle files for a set of projects. + * <p> + * Based on {@link org.eclipse.ant.internal.ui.datatransfer.BuildFileCreator} + */ +public class BuildFileCreator { + static final String BUILD_FILE = "build.gradle"; //$NON-NLS-1$ + static final String SETTINGS_FILE = "settings.gradle"; //$NON-NLS-1$ + private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ + private static final String GRADLE_WRAPPER_LOCATION = + "tools/templates/gradle/wrapper"; //$NON-NLS-1$ + static final String PLUGIN_CLASSPATH = + "classpath '" + GRADLE_PLUGIN_NAME + GRADLE_PLUGIN_LATEST_VERSION + "'"; //$NON-NLS-1$ + static final String MAVEN_REPOSITORY = "jcenter()"; //$NON-NLS-1$ + + private static final String[] GRADLE_WRAPPER_FILES = new String[] { + "gradlew", //$NON-NLS-1$ + "gradlew.bat", //$NON-NLS-1$ + "gradle/wrapper/gradle-wrapper.jar", //$NON-NLS-1$ + "gradle/wrapper/gradle-wrapper.properties" //$NON-NLS-1$ + }; + + private static final Comparator<IFile> FILE_COMPARATOR = new Comparator<IFile>() { + @Override + public int compare(IFile o1, IFile o2) { + return o1.toString().compareTo(o2.toString()); + } + }; + + private final GradleModule mModule; + private final StringBuilder mBuildFile = new StringBuilder(); + + /** + * Create buildfile for the projects. + * + * @param shell parent instance for dialogs + * @return project names for which buildfiles were created + * @throws InterruptedException thrown when user cancels task + */ + public static void createBuildFiles( + @NonNull ProjectSetupBuilder builder, + @NonNull Shell shell, + @NonNull IProgressMonitor pm) { + + File gradleLocation = new File(Sdk.getCurrent().getSdkOsLocation(), GRADLE_WRAPPER_LOCATION); + SubMonitor localmonitor = null; + + try { + // See if we have a Gradle wrapper in the SDK templates directory. If so, we can copy + // it over. + boolean hasGradleWrapper = true; + for (File wrapperFile : getGradleWrapperFiles(gradleLocation)) { + if (!wrapperFile.exists()) { + hasGradleWrapper = false; + } + } + + Collection<GradleModule> modules = builder.getModules(); + boolean multiModules = modules.size() > 1; + + // determine files to create/change + List<IFile> files = new ArrayList<IFile>(); + + // add the build.gradle file for all modules. + for (GradleModule module : modules) { + // build.gradle file + IFile file = module.getProject().getFile(BuildFileCreator.BUILD_FILE); + files.add(file); + } + + // get the commonRoot for all modules. If only one module, this returns the path + // of the project. + IPath commonRoot = builder.getCommonRoot(); + + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IPath workspaceLocation = workspaceRoot.getLocation(); + + IPath relativePath = commonRoot.makeRelativeTo(workspaceLocation); + // if makeRelativePath to returns the same path, then commonRoot is not in the + // workspace. + boolean rootInWorkspace = !relativePath.equals(commonRoot); + // we only care if the root is a workspace project. if it's the workspace folder itself, + // then the files won't be handled by the workspace. + rootInWorkspace = rootInWorkspace && relativePath.segmentCount() > 0; + + File settingsFile = new File(commonRoot.toFile(), SETTINGS_FILE); + + // more than one modules -> generate settings.gradle + if (multiModules && rootInWorkspace) { + + // Locate the settings.gradle file and add it to the changed files list + IPath settingsGradle = Path.fromOSString(settingsFile.getAbsolutePath()); + + // different path, means commonRoot is inside the workspace, which means we have + // to add settings.gradle and wrapper files to the list of files to add. + IFile iFile = workspaceRoot.getFile(settingsGradle); + if (iFile != null) { + files.add(iFile); + } + } + + // Gradle wrapper files + if (hasGradleWrapper && rootInWorkspace) { + // See if there already wrapper files there and only mark nonexistent ones for + // creation. + for (File wrapperFile : getGradleWrapperFiles(commonRoot.toFile())) { + if (!wrapperFile.exists()) { + IPath path = Path.fromOSString(wrapperFile.getAbsolutePath()); + IFile file = workspaceRoot.getFile(path); + files.add(file); + } + } + } + + ExportStatus status = new ExportStatus(); + builder.setStatus(status); + + // Trigger checkout of changed files + Set<IFile> confirmedFiles = validateEdit(files, status, shell); + + if (status.hasError()) { + return; + } + + // Now iterate over all the modules and generate the build files. + localmonitor = SubMonitor.convert(pm, ExportMessages.PageTitle, + confirmedFiles.size()); + List<String> projectSettingsPath = Lists.newArrayList(); + for (GradleModule currentModule : modules) { + IProject moduleProject = currentModule.getProject(); + + IFile file = moduleProject.getFile(BuildFileCreator.BUILD_FILE); + if (!confirmedFiles.contains(file)) { + continue; + } + + localmonitor.setTaskName(NLS.bind(ExportMessages.FileStatusMessage, + moduleProject.getName())); + + ProjectState projectState = Sdk.getProjectState(moduleProject); + BuildFileCreator instance = new BuildFileCreator(currentModule, shell); + if (projectState != null) { + // This is an Android project + if (!multiModules) { + instance.appendBuildScript(); + } + instance.appendHeader(projectState.isLibrary()); + instance.appendDependencies(); + instance.startAndroidTask(projectState); + //instance.appendDefaultConfig(); + instance.createAndroidSourceSets(); + instance.finishAndroidTask(); + } else { + // This is a plain Java project + instance.appendJavaHeader(); + instance.createJavaSourceSets(); + } + + try { + // Write the build file + String buildfile = instance.mBuildFile.toString(); + InputStream is = + new ByteArrayInputStream(buildfile.getBytes("UTF-8")); //$NON-NLS-1$ + if (file.exists()) { + file.setContents(is, true, true, null); + } else { + file.create(is, true, null); + } + } catch (Exception e) { + status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, + file.getLocation().toFile()); + status.setErrorMessage(e.getMessage()); + return; + } + + if (localmonitor.isCanceled()) { + return; + } + localmonitor.worked(1); + + // get the project path to add it to the settings.gradle. + projectSettingsPath.add(currentModule.getPath()); + } + + // write the settings file. + if (multiModules) { + try { + writeGradleSettingsFile(settingsFile, projectSettingsPath); + } catch (IOException e) { + status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, settingsFile); + status.setErrorMessage(e.getMessage()); + return; + } + File mainBuildFile = new File(commonRoot.toFile(), BUILD_FILE); + try { + writeRootBuildGradle(mainBuildFile); + } catch (IOException e) { + status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, mainBuildFile); + status.setErrorMessage(e.getMessage()); + return; + } + } + + // finally write the wrapper + // TODO check we can based on where it is + if (hasGradleWrapper) { + copyGradleWrapper(gradleLocation, commonRoot.toFile(), status); + if (status.hasError()) { + return; + } + } + + } finally { + if (localmonitor != null && !localmonitor.isCanceled()) { + localmonitor.done(); + } + if (pm != null) { + pm.done(); + } + } + } + + /** + * @param GradleModule create buildfile for this project + * @param shell parent instance for dialogs + */ + private BuildFileCreator(GradleModule module, Shell shell) { + mModule = module; + } + + /** + * Return the files that comprise the Gradle wrapper as a collection of {@link File} instances. + * @param root + * @return + */ + private static List<File> getGradleWrapperFiles(File root) { + List<File> files = new ArrayList<File>(GRADLE_WRAPPER_FILES.length); + for (String file : GRADLE_WRAPPER_FILES) { + files.add(new File(root, file)); + } + return files; + } + + /** + * Copy the Gradle wrapper files from one directory to another. + */ + private static void copyGradleWrapper(File from, File to, ExportStatus status) { + for (String file : GRADLE_WRAPPER_FILES) { + File dest = new File(to, file); + try { + File src = new File(from, file); + dest.getParentFile().mkdirs(); + new FileOp().copyFile(src, dest); + + if (src.getName().equals(GRADLE_PROPERTIES)) { + updateGradleDistributionUrl(GRADLE_LATEST_VERSION, dest); + } + dest.setExecutable(src.canExecute()); + status.addFileStatus(ExportStatus.FileStatus.OK, dest); + } catch (IOException e) { + status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, dest); + return; + } + } + } + + /** + * Outputs boilerplate buildscript information common to all Gradle build files. + */ + private void appendBuildScript() { + appendBuildScript(mBuildFile); + } + + /** + * Outputs boilerplate header information common to all Gradle build files. + */ + private static void appendBuildScript(StringBuilder builder) { + builder.append("buildscript {\n"); //$NON-NLS-1$ + builder.append(" repositories {\n"); //$NON-NLS-1$ + builder.append(" " + MAVEN_REPOSITORY + "\n"); //$NON-NLS-1$ + builder.append(" }\n"); //$NON-NLS-1$ + builder.append(" dependencies {\n"); //$NON-NLS-1$ + builder.append(" " + PLUGIN_CLASSPATH + "\n"); //$NON-NLS-1$ + builder.append(" }\n"); //$NON-NLS-1$ + builder.append("}\n"); //$NON-NLS-1$ + } + + /** + * Outputs boilerplate header information common to all Gradle build files. + */ + private void appendHeader(boolean isLibrary) { + if (isLibrary) { + mBuildFile.append("apply plugin: '").append(LIB_PLUGIN_ID).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + mBuildFile.append("apply plugin: '").append(APP_PLUGIN_ID).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + mBuildFile.append("\n"); //$NON-NLS-1$ + } + + /** + * Outputs a block which sets up library and project dependencies. + */ + private void appendDependencies() { + mBuildFile.append("dependencies {\n"); //$NON-NLS-1$ + + // first the local jars. + // TODO: Fix + mBuildFile.append(" compile fileTree(dir: 'libs', include: '*.jar')\n"); //$NON-NLS-1$ + + for (GradleModule dep : mModule.getDependencies()) { + mBuildFile.append(" compile project('" + dep.getPath() + "')\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + mBuildFile.append("}\n"); //$NON-NLS-1$ + mBuildFile.append("\n"); //$NON-NLS-1$ + } + + /** + * Outputs the beginning of an Android task in the build file. + */ + private void startAndroidTask(ProjectState projectState) { + int buildApi = projectState.getTarget().getVersion().getApiLevel(); + String toolsVersion = projectState.getTarget().getBuildToolInfo().getRevision().toString(); + mBuildFile.append("android {\n"); //$NON-NLS-1$ + mBuildFile.append(" compileSdkVersion " + buildApi + "\n"); //$NON-NLS-1$ + mBuildFile.append(" buildToolsVersion \"" + toolsVersion + "\"\n"); //$NON-NLS-1$ + mBuildFile.append("\n"); //$NON-NLS-1$ + + try { + IJavaProject javaProject = BaseProjectHelper.getJavaProject(projectState.getProject()); + // otherwise we check source compatibility + String source = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); + if (JavaCore.VERSION_1_7.equals(source)) { + mBuildFile.append( + " compileOptions {\n" + //$NON-NLS-1$ + " sourceCompatibility JavaVersion.VERSION_1_7\n" + //$NON-NLS-1$ + " targetCompatibility JavaVersion.VERSION_1_7\n" + //$NON-NLS-1$ + " }\n" + //$NON-NLS-1$ + "\n"); //$NON-NLS-1$ + } + } catch (CoreException e) { + // Ignore compliance level, go with default + } + } + + /** + * Outputs a sourceSets block to the Android task that locates all of the various source + * subdirectories in the project. + */ + private void createAndroidSourceSets() { + IFolderWrapper projectFolder = new IFolderWrapper(mModule.getProject()); + IAbstractFile mManifestFile = AndroidManifest.getManifest(projectFolder); + if (mManifestFile == null) { + return; + } + List<String> srcDirs = new ArrayList<String>(); + for (IClasspathEntry entry : mModule.getJavaProject().readRawClasspath()) { + if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE || + SdkConstants.FD_GEN_SOURCES.equals(entry.getPath().lastSegment())) { + continue; + } + IPath path = entry.getPath().removeFirstSegments(1); + srcDirs.add("'" + path.toOSString() + "'"); //$NON-NLS-1$ + } + + String srcPaths = Joiner.on(",").join(srcDirs); + + mBuildFile.append(" sourceSets {\n"); //$NON-NLS-1$ + mBuildFile.append(" main {\n"); //$NON-NLS-1$ + mBuildFile.append(" manifest.srcFile '" + SdkConstants.FN_ANDROID_MANIFEST_XML + "'\n"); //$NON-NLS-1$ + mBuildFile.append(" java.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" resources.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" aidl.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" renderscript.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" res.srcDirs = ['res']\n"); //$NON-NLS-1$ + mBuildFile.append(" assets.srcDirs = ['assets']\n"); //$NON-NLS-1$ + mBuildFile.append(" }\n"); //$NON-NLS-1$ + mBuildFile.append("\n"); //$NON-NLS-1$ + mBuildFile.append(" // Move the tests to tests/java, tests/res, etc...\n"); //$NON-NLS-1$ + mBuildFile.append(" instrumentTest.setRoot('tests')\n"); //$NON-NLS-1$ + if (srcDirs.contains("'src'")) { + mBuildFile.append("\n"); //$NON-NLS-1$ + mBuildFile.append(" // Move the build types to build-types/<type>\n"); //$NON-NLS-1$ + mBuildFile.append(" // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...\n"); //$NON-NLS-1$ + mBuildFile.append(" // This moves them out of them default location under src/<type>/... which would\n"); //$NON-NLS-1$ + mBuildFile.append(" // conflict with src/ being used by the main source set.\n"); //$NON-NLS-1$ + mBuildFile.append(" // Adding new build types or product flavors should be accompanied\n"); //$NON-NLS-1$ + mBuildFile.append(" // by a similar customization.\n"); //$NON-NLS-1$ + mBuildFile.append(" debug.setRoot('build-types/debug')\n"); //$NON-NLS-1$ + mBuildFile.append(" release.setRoot('build-types/release')\n"); //$NON-NLS-1$ + } + mBuildFile.append(" }\n"); //$NON-NLS-1$ + } + + /** + * Outputs the completion of the Android task in the build file. + */ + private void finishAndroidTask() { + mBuildFile.append("}\n"); //$NON-NLS-1$ + } + + /** + * Outputs a boilerplate header for non-Android projects + */ + private void appendJavaHeader() { + mBuildFile.append("apply plugin: 'java'\n"); //$NON-NLS-1$ + } + + /** + * Outputs a sourceSets block for non-Android projects to locate the source directories. + */ + private void createJavaSourceSets() { + List<String> dirs = new ArrayList<String>(); + for (IClasspathEntry entry : mModule.getJavaProject().readRawClasspath()) { + if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) { + continue; + } + IPath path = entry.getPath().removeFirstSegments(1); + dirs.add("'" + path.toOSString() + "'"); //$NON-NLS-1$ + } + + String srcPaths = Joiner.on(",").join(dirs); + + mBuildFile.append("sourceSets {\n"); //$NON-NLS-1$ + mBuildFile.append(" main.java.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" main.resources.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$ + mBuildFile.append(" test.java.srcDirs = ['tests/java']\n"); //$NON-NLS-1$ + mBuildFile.append(" test.resources.srcDirs = ['tests/resources']\n"); //$NON-NLS-1$ + mBuildFile.append("}\n"); //$NON-NLS-1$ + } + + /** + * Merges the new subproject dependencies into the settings.gradle file if it already exists, + * and creates one if it does not. + * @throws IOException + */ + private static void writeGradleSettingsFile(File settingsFile, List<String> projectPaths) + throws IOException { + StringBuilder contents = new StringBuilder(); + for (String path : projectPaths) { + contents.append("include '").append(path).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + Files.write(contents.toString(), settingsFile, Charsets.UTF_8); + } + + private static void writeRootBuildGradle(File buildFile) throws IOException { + StringBuilder sb = new StringBuilder( + "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n"); + + appendBuildScript(sb); + + Files.write(sb.toString(), buildFile, Charsets.UTF_8); + } + + /** + * Request write access to given files. Depending on the version control + * plug-in opens a confirm checkout dialog. + * + * @param shell + * parent instance for dialogs + * @return <code>IFile</code> objects for which user confirmed checkout + * @throws CoreException + * thrown if project is under version control, but not connected + */ + static Set<IFile> validateEdit( + @NonNull List<IFile> files, + @NonNull ExportStatus exportStatus, + @NonNull Shell shell) { + Set<IFile> confirmedFiles = new TreeSet<IFile>(FILE_COMPARATOR); + if (files.size() == 0) { + return confirmedFiles; + } + IStatus status = (files.get(0)).getWorkspace().validateEdit( + files.toArray(new IFile[files.size()]), shell); + if (status.isMultiStatus() && status.getChildren().length > 0) { + for (int i = 0; i < status.getChildren().length; i++) { + IStatus statusChild = status.getChildren()[i]; + if (statusChild.isOK()) { + confirmedFiles.add(files.get(i)); + } else { + exportStatus.addFileStatus( + ExportStatus.FileStatus.VCS_FAILURE, + files.get(i).getLocation().toFile()); + } + } + } else if (status.isOK()) { + confirmedFiles.addAll(files); + } + if (status.getSeverity() == IStatus.ERROR) { + // not possible to checkout files: not connected to version + // control plugin or hijacked files and made read-only, so + // collect error messages provided by validator and re-throw + StringBuffer message = new StringBuffer(status.getPlugin() + ": " //$NON-NLS-1$ + + status.getMessage() + NEWLINE); + if (status.isMultiStatus()) { + for (int i = 0; i < status.getChildren().length; i++) { + IStatus statusChild = status.getChildren()[i]; + message.append(statusChild.getMessage() + NEWLINE); + } + } + String s = message.toString(); + exportStatus.setErrorMessage(s); + } + + return confirmedFiles; + } + + // ------------------------------------------------------------------------------- + // Fix gradle wrapper version. This code is from GradleUtil in the Studio plugin: + // ------------------------------------------------------------------------------- + + private static final String GRADLE_PROPERTIES = "gradle-wrapper.properties"; + private static final String GRADLEW_PROPERTIES_PATH = + "gradle" + File.separator + "wrapper" + File.separator + GRADLE_PROPERTIES; + private static final String GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME = "distributionUrl"; + + @NonNull + private static File getGradleWrapperPropertiesFilePath(@NonNull File projectRootDir) { + return new File(projectRootDir, GRADLEW_PROPERTIES_PATH); + } + + @Nullable + public static File findWrapperPropertiesFile(@NonNull File projectRootDir) { + File wrapperPropertiesFile = getGradleWrapperPropertiesFilePath(projectRootDir); + return wrapperPropertiesFile.isFile() ? wrapperPropertiesFile : null; + } + + private static boolean updateGradleDistributionUrl( + @NonNull String gradleVersion, + @NonNull File propertiesFile) throws IOException { + Properties properties = loadGradleWrapperProperties(propertiesFile); + String gradleDistributionUrl = getGradleDistributionUrl(gradleVersion, false); + String property = properties.getProperty(GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME); + if (property != null + && (property.equals(gradleDistributionUrl) || property + .equals(getGradleDistributionUrl(gradleVersion, true)))) { + return false; + } + properties.setProperty(GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME, gradleDistributionUrl); + FileOutputStream out = null; + try { + out = new FileOutputStream(propertiesFile); + properties.store(out, null); + return true; + } finally { + Closeables.close(out, true); + } + } + + @NonNull + private static Properties loadGradleWrapperProperties(@NonNull File propertiesFile) + throws IOException { + Properties properties = new Properties(); + FileInputStream fileInputStream = null; + try { + fileInputStream = new FileInputStream(propertiesFile); + properties.load(fileInputStream); + return properties; + } finally { + Closeables.close(fileInputStream, true); + } + } + + @NonNull + private static String getGradleDistributionUrl(@NonNull String gradleVersion, + boolean binOnly) { + String suffix = binOnly ? "bin" : "all"; + return String.format("https://services.gradle.org/distributions/gradle-%1$s-" + suffix + + ".zip", gradleVersion); + } +} |