From 8e995252f6b04d79635c6ccee8ce352bdee3a50b Mon Sep 17 00:00:00 2001 From: Centril Date: Thu, 13 Nov 2014 21:55:45 +0100 Subject: [PATCH 01/10] .gitingore: intellij stuff. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6ef76cf..54ca370 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ local.properties .idea build *.iml +*.ipr +*.iws classes From 0b9cca8b23376b8cddcbef66fe4ab4d9861979b0 Mon Sep 17 00:00:00 2001 From: Centril Date: Thu, 13 Nov 2014 22:28:41 +0100 Subject: [PATCH 02/10] moved SdkManagerPlugin.[isOfflineBuild, hasAndroidPlugin] -> internal.Util.* + added javadocs for em --- .../sdkmanager/SdkManagerPlugin.groovy | 18 +++-------- .../sdkmanager/internal/Util.groovy | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 src/main/groovy/com/jakewharton/sdkmanager/internal/Util.groovy diff --git a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy index fedd392..ca55828 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy @@ -1,11 +1,11 @@ package com.jakewharton.sdkmanager -import com.android.build.gradle.AppPlugin -import com.android.build.gradle.LibraryPlugin import com.jakewharton.sdkmanager.internal.PackageResolver import com.jakewharton.sdkmanager.internal.SdkResolver -import com.jakewharton.sdkmanager.internal.System + import java.util.concurrent.TimeUnit + +import static com.jakewharton.sdkmanager.internal.Util.* import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.logging.Logger @@ -45,19 +45,11 @@ class SdkManagerPlugin implements Plugin { } } - def time(String name, Closure task) { + def time( String name, Closure task ) { long before = java.lang.System.nanoTime() task.run() long after = java.lang.System.nanoTime() - long took = TimeUnit.NANOSECONDS.toMillis(after - before) + long took = TimeUnit.NANOSECONDS.toMillis( after - before ) log.info "$name took $took ms." } - - static def hasAndroidPlugin(Project project) { - return project.plugins.hasPlugin(AppPlugin) || project.plugins.hasPlugin(LibraryPlugin) - } - - static def isOfflineBuild(Project project) { - return project.getGradle().getStartParameter().isOffline() - } } diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/Util.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/Util.groovy new file mode 100644 index 0000000..f333da6 --- /dev/null +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/Util.groovy @@ -0,0 +1,32 @@ +package com.jakewharton.sdkmanager.internal + +import com.android.build.gradle.AppPlugin +import com.android.build.gradle.LibraryPlugin +import org.gradle.api.Project + +/** + * {@link Util} contains a set of utilities + * for the {@link com.jakewharton.sdkmanager.SdkManagerPlugin}. + */ +class Util { + /** + * Checks if a given {@link Project} has had an android plugin applied to it. + * This can be either the {@link AppPlugin} or {@link LibraryPlugin}. + * + * @param project the plugin to check. + * @return true if it had an android plugin applied to it, otherwise false. + */ + static def hasAndroidPlugin( Project project ) { + return project.plugins.hasPlugin( AppPlugin ) || project.plugins.hasPlugin( LibraryPlugin ) + } + + /** + * Checks if the build is in an offline mode. + * + * @param project Any gradle {@link Project}. + * @return true if the build is being done offline. + */ + static def isOfflineBuild( Project project ) { + return project.getGradle().getStartParameter().isOffline() + } +} From 6188dd000da5ab1a5c27304f6897cf81a822441b Mon Sep 17 00:00:00 2001 From: Centril Date: Thu, 13 Nov 2014 22:34:30 +0100 Subject: [PATCH 03/10] added groovydoc to SdkManagerPlugin. --- .../com/jakewharton/sdkmanager/SdkManagerPlugin.groovy | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy index ca55828..4cb0180 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy @@ -12,6 +12,9 @@ import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.gradle.api.tasks.StopExecutionException +/** + * {@link SdkManagerPlugin} is the gradle {@link Plugin} class. + */ class SdkManagerPlugin implements Plugin { final Logger log = Logging.getLogger SdkManagerPlugin @@ -45,6 +48,13 @@ class SdkManagerPlugin implements Plugin { } } + /** + * Executes task closure and logs the + * time it took for it to run in nanoseconds. + * + * @param name the human readable name of the task. + * @param task the task closure to run. + */ def time( String name, Closure task ) { long before = java.lang.System.nanoTime() task.run() From cde71f2e91d57e62626b61c0beeada16cdb94de6 Mon Sep 17 00:00:00 2001 From: Centril Date: Thu, 13 Nov 2014 22:44:01 +0100 Subject: [PATCH 04/10] added groovydoc to AndroidCommand. --- .../sdkmanager/internal/AndroidCommand.groovy | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/AndroidCommand.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/AndroidCommand.groovy index 6bc69a9..31a5338 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/internal/AndroidCommand.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/AndroidCommand.groovy @@ -6,7 +6,16 @@ import org.gradle.api.logging.Logging import static com.android.SdkConstants.FD_TOOLS import static com.android.SdkConstants.androidCmdName +/** + * {@link AndroidCommand} runs commands against the Android SDK Manager. + */ interface AndroidCommand { + /** + * Runs an update command with the given filter. + * + * @param filter the filter to use. + * @return the exit value of the update command. + */ int update(String filter); static final class Real implements AndroidCommand { From eb1f5ede345407f81e982d0b2da13cb904f29c4c Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 01:36:37 +0100 Subject: [PATCH 05/10] added groovydoc to SdkResolver. --- .../sdkmanager/internal/SdkResolver.groovy | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkResolver.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkResolver.groovy index 811a4fb..a24badc 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkResolver.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkResolver.groovy @@ -11,7 +11,22 @@ import static com.android.SdkConstants.PLATFORM_WINDOWS import static com.android.SdkConstants.SDK_DIR_PROPERTY import static com.android.SdkConstants.currentPlatform +/** + * {@link SdkResolver} resolves the android SDK and stores the + * path of the local copy downloaded in the file: local.properties. + * The SDK is only downloaded if it is not found. + */ class SdkResolver { + /** + * Resolve the SDK given a gradle {@link Project} + * for which a local.properties file will written to + * its root if it is not already present. This file + * contains the same path as the File instance returned + * by {@link #resolve(org.gradle.api.Project)}. + * + * @param project the gradle {@link Project}. + * @return the SDK path as a {@link File}. + */ static File resolve(Project project) { boolean isWindows = currentPlatform() == PLATFORM_WINDOWS return new SdkResolver(project, new System.Real(), new Downloader.Real(), isWindows).resolve() @@ -26,6 +41,14 @@ class SdkResolver { final File localProperties final boolean isWindows + /** + * Constructs a SdkResolver. + * + * @param project the gradle {@link Project}. + * @param system An instance of {@link System}. + * @param downloader An instance of {@link Downloader}. + * @param isWindows if true, the current platform is Windows. + */ SdkResolver(Project project, System system, Downloader downloader, boolean isWindows) { this.project = project this.system = system @@ -38,6 +61,10 @@ class SdkResolver { localProperties = new File(project.rootDir, FN_LOCAL_PROPERTIES) } + /** + * Resolves the file. + * @see #resolve(org.gradle.api.Project) + */ File resolve() { // Check for existing local.properties file and the SDK it points to. if (localProperties.exists()) { @@ -88,6 +115,11 @@ class SdkResolver { return userAndroid } + /** + * Downloads the android SDK. + * + * @param target the path where the SDK should be downloaded to. + */ def downloadSdk(File target) { log.lifecycle 'Android SDK not found. Downloading...' @@ -98,6 +130,11 @@ class SdkResolver { writeLocalProperties target.absolutePath } + /** + * Writes the path of the downloaded android sdk to a local.properties file. + * + * @param path the path of the downloaded android sdk. + */ def writeLocalProperties(String path) { if (isWindows) { // Escape Windows file separators when writing as a path. From e703d6386df8c941c2407b00523c8ce0b1d45091 Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 01:48:14 +0100 Subject: [PATCH 06/10] added groovydoc to Downloader & SdkDownload. --- .../sdkmanager/internal/Downloader.groovy | 13 ++++++++++ .../sdkmanager/internal/SdkDownload.groovy | 26 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/Downloader.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/Downloader.groovy index 9fe1e81..21d83ff 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/internal/Downloader.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/Downloader.groovy @@ -1,8 +1,21 @@ package com.jakewharton.sdkmanager.internal +/** + * {@link Downloader} is an interface used to + * download an android SDK to a specific destination. + */ interface Downloader { + /** + * Download an android SDK to dest. + * + * @param dest the location to store SDK in. + */ void download(File dest) + /** + * The actual implementation of the {@link Downloader}. + * Simply delegates to {@link SdkDownload}. + */ static final class Real implements Downloader { @Override void download(File dest) { SdkDownload.get().download(dest) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkDownload.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkDownload.groovy index 3eb875d..ea2e730 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkDownload.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/SdkDownload.groovy @@ -13,12 +13,19 @@ import static org.rauschig.jarchivelib.ArchiveFormat.TAR import static org.rauschig.jarchivelib.ArchiveFormat.ZIP import static org.rauschig.jarchivelib.CompressionType.GZIP -/** Manages platform-specific SDK downloads. */ +/** + * {@link SdkDownload} manages platform-specific SDK downloads. + */ enum SdkDownload { WINDOWS('windows','zip'), LINUX('linux', 'tgz'), DARWIN('macosx', 'zip'); + /** + * Returns the platform specific instance of {@SdkDownload}. + * + * @return an instance of {@SdkDownload}. + */ static SdkDownload get() { switch (currentPlatform()) { case PLATFORM_WINDOWS: @@ -36,12 +43,22 @@ enum SdkDownload { final String suffix final String ext + /** + * Constructs an instance given a suffix and extension. + * + * @param suffix The suffix to use in the download URL, e.g: the OS. + * @param ext The extension of the file to download. + */ SdkDownload(String suffix, String ext) { this.suffix = suffix this.ext = ext } - /** Download the SDK to {@code temp} and extract to {@code dest}. */ + /** + * Downloads the SDK to {@code temp} and extracts to {@code dest}. + * + * @param dest the location to extract SDK to. + */ void download(File dest) { def url = "http://dl.google.com/android/android-sdk_r23-$suffix.$ext" log.debug "Downloading SDK from $url." @@ -64,6 +81,11 @@ enum SdkDownload { temp.delete() } + /** + * Returns an archiver for the used extension/format. + * + * @return the archiver. + */ def getArchiver() { switch (ext) { case 'zip': From 1e1826056f379f95abcf536d7e34c6bed92a9cfa Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 03:13:43 +0100 Subject: [PATCH 07/10] SdkResolverTest: fixed local.properties on Windows. --- .../sdkmanager/internal/SdkResolverTest.groovy | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test/groovy/com/jakewharton/sdkmanager/internal/SdkResolverTest.groovy b/src/test/groovy/com/jakewharton/sdkmanager/internal/SdkResolverTest.groovy index 68c5916..fb83c66 100644 --- a/src/test/groovy/com/jakewharton/sdkmanager/internal/SdkResolverTest.groovy +++ b/src/test/groovy/com/jakewharton/sdkmanager/internal/SdkResolverTest.groovy @@ -1,5 +1,4 @@ package com.jakewharton.sdkmanager.internal - import com.jakewharton.sdkmanager.FixtureName import com.jakewharton.sdkmanager.TemporaryFixture import com.jakewharton.sdkmanager.util.FakeSystem @@ -14,6 +13,8 @@ import org.junit.Test import static com.android.SdkConstants.ANDROID_HOME_ENV import static com.android.SdkConstants.FN_LOCAL_PROPERTIES import static com.android.SdkConstants.SDK_DIR_PROPERTY +import static com.android.SdkConstants.currentPlatform +import static com.android.SdkConstants.PLATFORM_WINDOWS import static org.fest.assertions.api.Assertions.assertThat import static org.fest.assertions.api.Assertions.failBecauseExceptionWasNotThrown @@ -25,6 +26,7 @@ class SdkResolverTest { FakeSystem system RecordingDownloader downloader SdkResolver sdkResolver + boolean isWindows @Before public void setUp() { project = ProjectBuilder.builder() @@ -35,11 +37,18 @@ class SdkResolverTest { system = new FakeSystem() system.properties.put 'user.home', fixture.root.absolutePath + isWindows = currentPlatform() == PLATFORM_WINDOWS + downloader = new RecordingDownloader() - sdkResolver = new SdkResolver(project, system, downloader, false) + + sdkResolver = new SdkResolver(project, system, downloader, isWindows) } def writeLocalProperties(String path) { + if ( isWindows ) { + path = path.replace "\\", "\\\\" + } + localProperties.withOutputStream { it << "$SDK_DIR_PROPERTY=$path" } From 438462d7093065705bbf4defcc01244750dae29a Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 03:28:04 +0100 Subject: [PATCH 08/10] Moved implementation of SdkManagerPlugin -> SdkManagerAction (standalone). --- .../sdkmanager/SdkManagerAction.groovy | 67 +++++++++++++++++++ .../sdkmanager/SdkManagerPlugin.groovy | 56 +--------------- 2 files changed, 69 insertions(+), 54 deletions(-) create mode 100644 src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy diff --git a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy new file mode 100644 index 0000000..d1d5088 --- /dev/null +++ b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy @@ -0,0 +1,67 @@ +package com.jakewharton.sdkmanager + +import com.jakewharton.sdkmanager.internal.PackageResolver +import com.jakewharton.sdkmanager.internal.SdkResolver +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging +import org.gradle.api.tasks.StopExecutionException + +import java.util.concurrent.TimeUnit + +import static com.jakewharton.sdkmanager.internal.Util.hasAndroidPlugin +import static com.jakewharton.sdkmanager.internal.Util.isOfflineBuild + +/** + * {@link SdkManagerAction} is the standalone + * {@link org.gradle.api.Action} implementation in this plugin. + */ +class SdkManagerAction implements Action { + final Logger log = Logging.getLogger SdkManagerPlugin + @Override + void execute( Project project ) { + if ( hasAndroidPlugin( project ) ) { + throw new StopExecutionException( + "Must be applied before 'android' or 'android-library' plugin." ) + } + + if ( isOfflineBuild( project ) ) { + log.debug 'Offline build. Skipping package resolution.' + return + } + + // Eager resolve the SDK and local.properties pointer. + def sdk + time "SDK resolve", { + sdk = SdkResolver.resolve project + } + + // Defer resolving SDK package dependencies until after the model is finalized. + project.afterEvaluate { + if ( !hasAndroidPlugin( project ) ) { + log.debug 'No Android plugin detecting. Skipping package resolution.' + return + } + + time "Package resolve", { + PackageResolver.resolve project, sdk + } + } + } + + /** + * Executes task closure and logs the + * time it took for it to run in nanoseconds. + * + * @param name the human readable name of the task. + * @param task the task closure to run. + */ + def time( String name, Closure task ) { + long before = java.lang.System.nanoTime() + task.run() + long after = java.lang.System.nanoTime() + long took = TimeUnit.NANOSECONDS.toMillis( after - before ) + log.info "$name took $took ms." + } +} diff --git a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy index 4cb0180..cea8458 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerPlugin.groovy @@ -1,65 +1,13 @@ package com.jakewharton.sdkmanager -import com.jakewharton.sdkmanager.internal.PackageResolver -import com.jakewharton.sdkmanager.internal.SdkResolver - -import java.util.concurrent.TimeUnit - -import static com.jakewharton.sdkmanager.internal.Util.* import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.logging.Logger -import org.gradle.api.logging.Logging -import org.gradle.api.tasks.StopExecutionException /** - * {@link SdkManagerPlugin} is the gradle {@link Plugin} class. + * {@link SdkManagerPlugin} is the gradle plugin class. */ class SdkManagerPlugin implements Plugin { - final Logger log = Logging.getLogger SdkManagerPlugin - @Override void apply(Project project) { - if (hasAndroidPlugin(project)) { - throw new StopExecutionException( - "Must be applied before 'android' or 'android-library' plugin.") - } - - if (isOfflineBuild(project)) { - log.debug 'Offline build. Skipping package resolution.' - return - } - - // Eager resolve the SDK and local.properties pointer. - def sdk - time "SDK resolve", { - sdk = SdkResolver.resolve project - } - - // Defer resolving SDK package dependencies until after the model is finalized. - project.afterEvaluate { - if (!hasAndroidPlugin(project)) { - log.debug 'No Android plugin detecting. Skipping package resolution.' - return - } - - time "Package resolve", { - PackageResolver.resolve project, sdk - } - } - } - - /** - * Executes task closure and logs the - * time it took for it to run in nanoseconds. - * - * @param name the human readable name of the task. - * @param task the task closure to run. - */ - def time( String name, Closure task ) { - long before = java.lang.System.nanoTime() - task.run() - long after = java.lang.System.nanoTime() - long took = TimeUnit.NANOSECONDS.toMillis( after - before ) - log.info "$name took $took ms." + new SdkManagerAction().execute( project ) } } From a01e2d951ce1fb16cb3f1a477587b4d9b3071205 Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 04:27:45 +0100 Subject: [PATCH 09/10] Plugin now works for non-android projects, only resolves parts that don't require android closure. + Groovydoc --- .../sdkmanager/SdkManagerAction.groovy | 5 - .../internal/PackageResolver.groovy | 108 +++++++++++++++++- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy index d1d5088..2d2ed23 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/SdkManagerAction.groovy @@ -39,11 +39,6 @@ class SdkManagerAction implements Action { // Defer resolving SDK package dependencies until after the model is finalized. project.afterEvaluate { - if ( !hasAndroidPlugin( project ) ) { - log.debug 'No Android plugin detecting. Skipping package resolution.' - return - } - time "Package resolve", { PackageResolver.resolve project, sdk } diff --git a/src/main/groovy/com/jakewharton/sdkmanager/internal/PackageResolver.groovy b/src/main/groovy/com/jakewharton/sdkmanager/internal/PackageResolver.groovy index a4b70ab..b64e3a9 100644 --- a/src/main/groovy/com/jakewharton/sdkmanager/internal/PackageResolver.groovy +++ b/src/main/groovy/com/jakewharton/sdkmanager/internal/PackageResolver.groovy @@ -13,12 +13,33 @@ import static com.android.SdkConstants.FD_M2_REPOSITORY import static com.android.SdkConstants.FD_PLATFORMS import static com.android.SdkConstants.FD_ADDONS import static com.android.SdkConstants.FD_PLATFORM_TOOLS - +import static com.jakewharton.sdkmanager.internal.Util.hasAndroidPlugin + +/** + * {@link PackageResolver} resolves, verifies and downloads (if missing) + * the build tools (1), platform tools, compile version (1), + * support libraries, google play services libraries. + * + * (1): only resolved if applied on a project on which + * an android plugin (app/library) has been applied on. + */ class PackageResolver { + /** + * Resolves packages for project with the android SDK expected at sdk. + * + * @param project The {@link Project} to resolve for. + * @param sdk The android SDK path is expected in this path. + */ static void resolve(Project project, File sdk) { new PackageResolver(project, sdk, new AndroidCommand.Real(sdk, new System.Real())).resolve() } + /** + * Checks if the given folder exists and is non-empty. + * + * @param folder the folder to check. + * @return true if it existed and was non-empty. + */ static boolean folderExists(File folder) { return folder.exists() && folder.list().length != 0 } @@ -37,6 +58,14 @@ class PackageResolver { final File googleRepositoryDir final AndroidCommand androidCommand + /** + * Constructs a {@link PackageResolver} given a project to resolve for, + * a android sdk path, and an {@link AndroidCommand} to use. + * + * @param project The {@link Project} to resolve for. + * @param sdk The android SDK path is expected in this path. + * @param androidCommand The {@link AndroidCommand} to use for running commands against the SDK. + */ PackageResolver(Project project, File sdk, AndroidCommand androidCommand) { this.sdk = sdk this.project = project @@ -54,14 +83,41 @@ class PackageResolver { googleRepositoryDir = new File(googleExtrasDir, FD_M2_REPOSITORY) } + /** + * Resolves everything that can be resolved and skips what can't. + * @see PackageResolver PackageResolver for notes about what is resolved when. + */ def resolve() { - resolveBuildTools() - resolvePlatformTools() - resolveCompileVersion() - resolveSupportLibraryRepository() - resolvePlayServiceRepository() + resolving('build-tools', true, this.&resolveBuildTools) + resolving('platform-tools', false, this.&resolvePlatformTools) + resolving('compile-version', true, this.&resolveCompileVersion) + resolving('support-library', false, this.&resolveSupportLibraryRepository) + resolving('play-services', false, this.&resolvePlayServiceRepository) + } + + /** + * Conditionally runs a "resolving" closure under name. + * The closure is skipped if android was required, + * but the android plugin wasn't applied. + * + * @param name The name to give the closure to run. + * @param requireAndroid Whether or not to require that the + * android plugin be applied for the closure to run. + * @param closure The closure to run should the conditions for running be met. + */ + def resolving( String name, boolean requireAndroid, Closure closure ) { + if ( requireAndroid && !hasAndroidPlugin( project ) ) { + log.debug "Skipping: $name, no android plugin detected" + } else { + log.debug "Resolving: $name" + closure() + } } + /** + * Resolves the build tools using the revision specified in android.buildToolsRevision. + * If missing, the revision will be downloaded. + */ def resolveBuildTools() { def buildToolsRevision = project.android.buildToolsRevision log.debug "Build tools version: $buildToolsRevision" @@ -80,6 +136,9 @@ class PackageResolver { } } + /** + * Resolves the platform tools and downloads them if missing. + */ def resolvePlatformTools() { if (folderExists(platformToolsDir)) { log.debug 'Platform tools found!' @@ -94,6 +153,10 @@ class PackageResolver { } } + /** + * Resolves the compile version downloads it if missing. + * Additionally, the google SDK is installed if missing. + */ def resolveCompileVersion() { String compileVersion = project.android.compileSdkVersion log.debug "Compile API version: $compileVersion" @@ -113,6 +176,12 @@ class PackageResolver { } } + /** + * Installs compilation API version at baseDir if not already installed. + * + * @param baseDir where the compilation API versions are stored. + * @param version the compilation API version that will be installed if needed. + */ def installIfMissing(baseDir, version) { def existingDir = new File(baseDir, version) if (folderExists(existingDir)) { @@ -128,6 +197,13 @@ class PackageResolver { } } + /** + * Resolves the support libraries if the project + * applied upon has one of them as a dependency. + * + * If missing, they will be downloaded, as well + * as using that path as a local maven repository. + */ def resolveSupportLibraryRepository() { def supportLibraryDeps = findDependenciesWithGroup 'com.android.support' if (supportLibraryDeps.isEmpty()) { @@ -158,6 +234,13 @@ class PackageResolver { } } + /** + * Resolves the google play services if the project + * applied upon has one of them as a dependency. + * + * If missing, they will be downloaded, as well + * as using that path as a local maven repository. + */ def resolvePlayServiceRepository() { def playServicesDeps = findDependenciesWithGroup 'com.google.android.gms' if (playServicesDeps.isEmpty()) { @@ -194,6 +277,12 @@ class PackageResolver { } } + /** + * Finds all dependencies in all configurations that has group. + * + * @param group The group to match on. + * @return The list of dependencies. + */ def findDependenciesWithGroup(String group) { def deps = [] for (Configuration configuration : project.configurations) { @@ -206,6 +295,13 @@ class PackageResolver { return deps } + /** + * Checks if the dependencies given by deps + * is actually available on the file system. + * + * @param deps The dependencies to check. + * @return true if available. + */ def dependenciesAvailable(def deps) { try { project.configurations.detachedConfiguration(deps as Dependency[]).files From c80af984a3b5dc82001bb9ce408511d49062243b Mon Sep 17 00:00:00 2001 From: Centril Date: Wed, 19 Nov 2014 04:29:48 +0100 Subject: [PATCH 10/10] added com.jakewharton.sdkmanager plugin id alias. --- .../gradle-plugins/com.jakewharton.sdkmanager.properties | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/resources/META-INF/gradle-plugins/com.jakewharton.sdkmanager.properties diff --git a/src/main/resources/META-INF/gradle-plugins/com.jakewharton.sdkmanager.properties b/src/main/resources/META-INF/gradle-plugins/com.jakewharton.sdkmanager.properties new file mode 100644 index 0000000..9169e3c --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/com.jakewharton.sdkmanager.properties @@ -0,0 +1 @@ +implementation-class=com.jakewharton.sdkmanager.SdkManagerPlugin