diff --git a/README.md b/README.md index 3781124..30b2807 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,18 @@ Preconditions: 1.Add the code below to you `build.gradle` file in the project root folder. -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.appswithlove.updraft/updraft/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.appswithlove.updraft/updraft) +[![Maven Central](https://maven-badges.sml.io/sonatype-central/com.appswithlove.updraft/updraft/badge.svg)](https://maven-badges.sml.io/sonatype-central/com.appswithlove.updraft/updraft) ```groovy buildscript { repositories { - ... + // ... mavenCentral() } dependencies { - ... - classpath 'com.appswithlove.updraft:updraft:2.2.9' + // ... + classpath 'com.appswithlove.updraft:updraft:2.3.0' } } ``` @@ -32,7 +32,7 @@ or ```kotlin plugins { - id("com.appswithlove.updraft") version "2.2.9" + id("com.appswithlove.updraft") version "2.3.0" } ``` @@ -111,11 +111,11 @@ In order to debug the plugin, `clean` -> `jar` -> `publishJarPublicationToMavenL buildscript { repositories { mavenLocal() - ... + // ... } dependencies { - classpath 'com.appswithlove.updraft:updraft:2.2.9' - ... + classpath 'com.appswithlove.updraft:updraft:2.3.0' + // ... } } ``` diff --git a/build.gradle b/build.gradle deleted file mode 100644 index ed1b61e..0000000 --- a/build.gradle +++ /dev/null @@ -1,42 +0,0 @@ -buildscript { - ext { - kotlin_version = '2.2.0' - compose_version = '1.8.3' - } - repositories { - maven { - url = "https://plugins.gradle.org/m2/" - } - mavenCentral() - } - dependencies { - classpath "org.jetbrains.dokka:dokka-gradle-plugin:2.0.0" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - - // if :lib was built before, take the local version, - // otherwise it takes the version on server. - // check the Build window for output. - -// File directory = new File(getRootDir(), "/lib/build/libs") -// File[] contents = directory.listFiles() -// if (contents == null || contents.length == 0) { -// println("updraft - mavenCentral version") -// classpath "com.appswithlove.updraft:updraft:2.2.6" -// } else { -// println("updraft - local version") -// classpath fileTree(include: ['*.jar'], dir: 'lib/build/libs') -// } - classpath "com.appswithlove.updraft:updraft:2.2.6" - } -} - -plugins { - id "com.vanniktech.maven.publish" version "0.34.0" - id 'com.github.kt3k.coveralls' version '2.4.0' - id 'signing' - id 'com.android.application' version '8.11.1' apply false - id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false - id 'org.jetbrains.kotlin.jvm' version "$kotlin_version" apply false - id 'com.gradle.plugin-publish' version '0.16.0' - id 'org.jetbrains.kotlin.plugin.compose' version "$kotlin_version" apply false -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..6e07c3c --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,21 @@ +buildscript { + repositories { + maven("https://plugins.gradle.org/m2/") + mavenCentral() + } + dependencies { + classpath(libs.dokka.gradle.plugin) + } +} + +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.updraft) apply false + alias(libs.plugins.maven.publish) apply false + alias(libs.plugins.gradle.publish) apply false + alias(libs.plugins.coveralls) + alias(libs.plugins.kotlin.jvm) apply false + id("signing") +} diff --git a/gradle.properties b/gradle.properties index b1a8456..a2b2d8a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ GROUP=com.appswithlove.updraft POM_ARTIFACT_ID=updraft -VERSION_NAME=2.2.9 +VERSION_NAME=2.3.0 POM_NAME=updraft-plugin-android POM_DESCRIPTION=This is a gradle Android plugin for automated uploads to Updraft diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..c4d8c5b --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,41 @@ +[versions] +agp = "8.11.1" +kotlin = "2.2.20" +composeBom = "2025.10.00" +activityCompose = "1.11.0" +coreKtx = "1.17.0" +lifecycleRuntimeKtx = "2.9.4" +cglibNodep = "3.3.0" +dokkaGradlePlugin = "2.0.0" +junit = "4.13.2" +updraft = "2.2.9" +maven-publish = "0.34.0" +gradle-publish = "2.0.0" +coveralls = "2.4.0" + +[libraries] +compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" } +activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" } +core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } +lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +material = { module = "androidx.compose.material:material" } +ui = { module = "androidx.compose.ui:ui" } +ui-tooling = { module = "androidx.compose.ui:ui-tooling" } +ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } +cglib-nodep = { module = "cglib:cglib-nodep", version.ref = "cglibNodep" } +dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokkaGradlePlugin" } +gradle = { module = "com.android.tools.build:gradle", version.ref = "agp" } +gradle-api = { module = "com.android.tools.build:gradle-api", version.ref = "agp" } +junit = { module = "junit:junit", version.ref = "junit" } +kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +updraft = { id = "com.appswithlove.updraft", version.ref = "updraft" } +maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "maven-publish" } +gradle-publish = { id = "com.gradle.plugin-publish", version.ref = "gradle-publish" } +coveralls = { id = "com.github.kt3k.coveralls", version.ref = "coveralls" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 626c86d..dcf5dbf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Oct 20 07:59:33 CEST 2017 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/lib/build.gradle b/lib/build.gradle deleted file mode 100644 index 31cfd1e..0000000 --- a/lib/build.gradle +++ /dev/null @@ -1,56 +0,0 @@ -import com.vanniktech.maven.publish.GradlePlugin -import com.vanniktech.maven.publish.JavadocJar - -plugins { - id 'groovy' - id 'java-gradle-plugin' - id 'com.vanniktech.maven.publish' - id 'com.gradle.plugin-publish' -} - -group GROUP -version VERSION_NAME - -dependencies { - implementation gradleApi() - implementation localGroovy() - testImplementation gradleTestKit() - testImplementation('org.spockframework:spock-core:1.0-groovy-2.4') { - exclude module: 'groovy-all' - } - testRuntimeOnly 'cglib:cglib-nodep:3.3.0' -} - -tasks.withType(GenerateModuleMetadata).configureEach { - enabled = false -} - -tasks.withType(Test).configureEach { - testLogging.events = ["passed", "skipped", "failed", "standardOut", "standardError"] -} - -mavenPublishing { - configure(new GradlePlugin(new JavadocJar.Javadoc(), true)) -} - -def pluginId = project.findProperty("GROUP") ?: "" -def pluginName = project.findProperty("POM_NAME") ?: "" -def pluginDescription = project.findProperty("POM_DESCRIPTION") ?: "" -def pluginVersion = project.findProperty("VERSION_NAME") ?: "" -def pluginWebsite = project.findProperty("POM_URL") ?: "" -def pluginVcsUrl = project.findProperty("POM_SCM_URL") ?: "" - -pluginBundle { - website = pluginWebsite - vcsUrl = pluginVcsUrl - - plugins { - updraft { - id = pluginId - displayName = pluginName - description = pluginDescription - version = pluginVersion - tags = ['updraft', 'android'] - } - } -} diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts new file mode 100644 index 0000000..68ffa1d --- /dev/null +++ b/lib/build.gradle.kts @@ -0,0 +1,81 @@ +import com.vanniktech.maven.publish.GradlePlugin +import com.vanniktech.maven.publish.JavadocJar +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +plugins { + `java-gradle-plugin` + alias(libs.plugins.maven.publish) + alias(libs.plugins.gradle.publish) + kotlin("jvm") +} + +dependencies { + implementation(gradleApi()) + testImplementation(gradleTestKit()) + testRuntimeOnly(libs.cglib.nodep) + implementation(libs.kotlin.gradle.plugin) + implementation(libs.gradle) + implementation(libs.gradle.api) + implementation(libs.kotlin.stdlib) +} + +tasks.withType().configureEach { + enabled = false +} + +tasks.withType().configureEach { + testLogging { + events("passed", "skipped", "failed", "standardOut", "standardError") + } +} + +tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") + } +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(11)) + } +} + +kotlin { + jvmToolchain(11) +} + +mavenPublishing { + configure( + GradlePlugin( + javadocJar = JavadocJar.None(), + sourcesJar = true, + ) + ) +} + +val pluginId: String = findProperty("GROUP") as String? ?: "" +val pluginName: String = findProperty("POM_NAME") as String? ?: "" +val pluginDescription: String = findProperty("POM_DESCRIPTION") as String? ?: "" +val pluginVersion: String = findProperty("VERSION_NAME") as String? ?: "" +val pluginWebsite: String = findProperty("POM_URL") as String? ?: "" +val pluginVcsUrl: String = findProperty("POM_SCM_URL") as String? ?: "" + +gradlePlugin { + website.set(pluginWebsite) + vcsUrl.set(pluginVcsUrl) + + plugins { + create("updraft") { + id = pluginId + displayName = pluginName + description = pluginDescription + version = pluginVersion + tags = listOf("updraft", "android") + implementationClass = "com.appswithlove.updraft.UpdraftPlugin" + } + } +} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/GitBranchValueSource.groovy b/lib/src/main/groovy/com/appswithlove/updraft/GitBranchValueSource.groovy deleted file mode 100644 index 4c01a0d..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/GitBranchValueSource.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.appswithlove.updraft - -import org.gradle.api.provider.ValueSource -import org.gradle.api.provider.ValueSourceParameters - -abstract class GitBranchValueSource implements ValueSource { - String obtain() { - try { - def error = null - def bashUrl = "git rev-parse --abbrev-ref HEAD" - def command = bashUrl.execute() - def outputUrlStream = new StringBuffer() - command.waitForProcessOutput(outputUrlStream, error) - if (error == null && outputUrlStream.size() > 0) { - return outputUrlStream.toString() - } else { - return "" - } - } catch (Exception ignored) { - return "" - } - } -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/GitCommitValueSource.groovy b/lib/src/main/groovy/com/appswithlove/updraft/GitCommitValueSource.groovy deleted file mode 100644 index 5147217..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/GitCommitValueSource.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.appswithlove.updraft - -import org.gradle.api.provider.ValueSource -import org.gradle.api.provider.ValueSourceParameters - -abstract class GitCommitValueSource implements ValueSource { - String obtain() { - try { - def error = null - def bashUrl = "git rev-parse HEAD" - def command = bashUrl.execute() - def outputUrlStream = new StringBuffer() - command.waitForProcessOutput(outputUrlStream, error) - if (error == null && outputUrlStream.size() > 0) { - return outputUrlStream.toString() - } else { - return "" - } - } catch (Exception ignored) { - return "" - } - } -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/GitTagsValueSource.groovy b/lib/src/main/groovy/com/appswithlove/updraft/GitTagsValueSource.groovy deleted file mode 100644 index 4d58e57..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/GitTagsValueSource.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.appswithlove.updraft - -import org.gradle.api.provider.ValueSource -import org.gradle.api.provider.ValueSourceParameters - -abstract class GitTagsValueSource implements ValueSource { - String obtain() { - try { - def error = null - def bashUrl = "git describe --tags" - def command = bashUrl.execute() - def outputUrlStream = new StringBuffer() - command.waitForProcessOutput(outputUrlStream, error) - if (error == null && outputUrlStream.size() > 0) { - return outputUrlStream.toString() - } else { - return "" - } - } catch (Exception ignored) { - return "" - } - } -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/GitUrlValueSource.groovy b/lib/src/main/groovy/com/appswithlove/updraft/GitUrlValueSource.groovy deleted file mode 100644 index cbedbf6..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/GitUrlValueSource.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.appswithlove.updraft - -import org.gradle.api.provider.ValueSource -import org.gradle.api.provider.ValueSourceParameters - -abstract class GitUrlValueSource implements ValueSource { - String obtain() { - try { - def error = null - def bashUrl = "git config --get remote.origin.url" - def command = bashUrl.execute() - def outputUrlStream = new StringBuffer() - command.waitForProcessOutput(outputUrlStream, error) - if (error == null && outputUrlStream.size() > 0) { - return outputUrlStream.toString() - } else { - return "" - } - } catch (Exception ignored) { - return "" - } - } -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftExtension.groovy b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftExtension.groovy deleted file mode 100644 index 811348c..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftExtension.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package com.appswithlove.updraft - -/** - * The plugin extension that will serve the required information vor connection to the right updraft module. - */ -class UpdraftExtension { - def urls = [:] - def releaseNotes = null -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy deleted file mode 100644 index de8c6fb..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftPlugin.groovy +++ /dev/null @@ -1,155 +0,0 @@ -package com.appswithlove.updraft - -import org.gradle.api.GradleException -import org.gradle.api.Plugin -import org.gradle.api.Project - -/** - * A plugin for uploading apk files to updraft.*/ -class UpdraftPlugin implements Plugin { - - @Override - void apply(Project project) { - project.extensions.create('updraft', UpdraftExtension.class) - project.android.applicationVariants.all { variant -> - - String variantName = variant.name - String variantNameCapitalized = variantName.capitalize() - String projectBasePath = getProject().getProjectDir().getAbsolutePath() - - def uploadUrlsProvider = project.providers.provider { project.updraft.urls } - def uploadUrls = uploadUrlsProvider.map { urlsMap -> - def urlsForVariant = urlsMap[variantNameCapitalized] - if (urlsForVariant == null) { - return [] - } - if (urlsForVariant instanceof String) { - return [urlsForVariant] - } - return urlsForVariant - } - - def gitBranchProvider = project.providers.of(GitBranchValueSource.class) {} - def gitTagsProvider = project.providers.of(GitTagsValueSource.class) {} - def gitCommitProvider = project.providers.of(GitCommitValueSource.class) {} - def gitUrlProvider = project.providers.of(GitUrlValueSource.class) {} - def releaseNotesProvider = project.providers.provider { getReleaseNotes(project, variant) } - - def apkFileProvider = project.provider { - def buildDir = project.layout.buildDirectory.get().asFile - def apkDir = new File(buildDir, "outputs/apk/${variant.flavorName}/${variant.buildType.name}") - - if (apkDir.exists() && apkDir.isDirectory()) { - def apkFiles = apkDir.listFiles({ file -> file.name.endsWith(".apk") } as FileFilter) - - if (apkFiles && apkFiles.size() > 1) { - throw new GradleException("More than one .apk file exists in ${apkDir}: ${apkFiles*.name}") - } - - return apkFiles ? apkFiles[0] : null - } - return null - } - def apkFile = apkFileProvider.flatMap { file -> - file ? project.layout.file(project.provider { file }) : project.objects.fileProperty() - } - - def aabFileProvider = project.provider { - def buildDir = project.layout.buildDirectory.get().asFile - def bundleDir = new File(buildDir, "outputs/bundle/${variantName}") - - if (bundleDir.exists() && bundleDir.isDirectory()) { - def aabFiles = bundleDir.listFiles({ file -> file.name.endsWith(".aab") } as FileFilter) - - if (aabFiles && aabFiles.size() > 1) { - throw new GradleException("More than one .aab file exists in ${bundleDir}: ${aabFiles*.name}") - } - - return aabFiles ? aabFiles[0] : null - } - return null - } - def aabFile = aabFileProvider.flatMap { file -> - file ? project.layout.file(project.provider { file }) : project.objects.fileProperty() - } - - // Registers a task for every available build variant / flavor - project.tasks.register("updraft${variantNameCapitalized}", UpdraftTask) { - outputFile.set(apkFile) - isBundle.set(false) - basePath.set(projectBasePath) - currentVariantName.set(variantName) - urls.set(uploadUrls) - gitBranch.set(gitBranchProvider) - gitTags.set(gitTagsProvider) - gitCommit.set(gitCommitProvider) - gitUrl.set(gitUrlProvider) - releaseNotes.set(releaseNotesProvider) - - doFirst { - def outputFile = apkFile.getOrNull()?.asFile - if (outputFile == null || !outputFile.exists()) { - throw new GradleException("Could not find a build artifact. (Make sure to run assemble${variantNameCapitalized} task first)") - } - } - } - - // Registers a task for every available build variant / flavor - project.tasks.register("updraftBundle${variantNameCapitalized}", UpdraftTask) { - outputFile.set(aabFile) - isBundle.set(true) - basePath.set(projectBasePath) - currentVariantName.set(variantName) - urls.set(uploadUrls) - gitBranch.set(gitBranchProvider) - gitTags.set(gitTagsProvider) - gitCommit.set(gitCommitProvider) - gitUrl.set(gitUrlProvider) - releaseNotes.set(releaseNotesProvider) - - doFirst { - def outputFile = aabFile.getOrNull()?.asFile - if (outputFile == null || !outputFile.exists()) { - throw new GradleException("Could not find a build artifact. (Make sure to run bundle${variantNameCapitalized} task first)") - } - } - } - } - } - - private static String getReleaseNotes(Project project, variant) { - if (project.hasProperty('releaseNotes')) { - println("Using releaseNotes from gradle property") - return project.property('releaseNotes') - } - - if (project.updraft.releaseNotes != null) { - println("Using releaseNotes from updraft extension") - return project.updraft.releaseNotes - } else { - def variantFile = null - if (variant.productFlavors.size() > 0) { - variantFile = new File(project.projectDir.toString() + "/src/" + variant.productFlavors[0].name + "/updraft/release-notes.txt") - } - def mainFile = new File(project.projectDir.toString() + "/src/main/updraft/release-notes.txt") - - if (variantFile != null && variantFile.exists()) { - println("Using releaseNotes from variant file") - return variantFile.readLines().join("\n") - } else if (mainFile.exists()) { - println("Using releaseNotes from main file") - return mainFile.readLines().join("\n") - } else { - println("Using releaseNotes last commit") - try { - def result = project.providers.exec { - commandLine("git", "log", "-1", "--pretty=%B") - }.standardOutput.asText - return result.get() - } catch (Exception ignored) { - return "" - } - } - } - } -} diff --git a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy b/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy deleted file mode 100644 index 90052b7..0000000 --- a/lib/src/main/groovy/com/appswithlove/updraft/UpdraftTask.groovy +++ /dev/null @@ -1,125 +0,0 @@ -package com.appswithlove.updraft - -import groovy.json.JsonSlurperClassic -import org.gradle.api.DefaultTask -import org.gradle.api.GradleException -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.Optional -import org.gradle.process.ExecOperations - -import javax.inject.Inject - -abstract class UpdraftTask extends DefaultTask { - - @Inject - abstract ExecOperations getExecOperations() - - @InputFile - @Optional - abstract RegularFileProperty getOutputFile() - - @Input - abstract Property getIsBundle() - - @Input - abstract Property getBasePath() - - @Input - abstract Property getCurrentVariantName() - - @Input - abstract ListProperty getUrls() - - @Input - abstract Property getGitBranch() - - @Input - abstract Property getGitTags() - - @Input - abstract Property getGitCommit() - - @Input - abstract Property getGitUrl() - - @Input - abstract Property getReleaseNotes() - - @TaskAction - void upload() { - def fileToUpload = outputFile.asFile.get() - - def uploadUrls = urls.get() - if (uploadUrls == null || uploadUrls.isEmpty()) { - throw new GradleException('There was no url provided for this buildVariant. Please check for typos.') - } - - if (uploadUrls instanceof String) { - println("--------------------------------------") - println("Url was not wrapped in array. Doing it for you. :)") - println("url --> [url]") - println("--------------------------------------") - uploadUrls = [uploadUrls] - } - - for (String url in uploadUrls) { - List curlArgs = [ - '-X', 'PUT', - '-F', "app=@${fileToUpload}", - '-F', "build_type=Gradle", - createCurlParam(gitBranch.get(), "custom_branch"), - createCurlParam(gitUrl.get(), "custom_URL"), - createCurlParam(gitTags.get(), "custom_tags"), - createCurlParam(gitCommit.get(), "custom_commit"), - createCurlParam(releaseNotes.get(), "whats_new"), - url - ].findAll { it != '' } - - new ByteArrayOutputStream().withStream { os -> - getExecOperations().exec { - executable 'curl' - args curlArgs - standardOutput os - } - - def execResponse = new JsonSlurperClassic().parseText(os.toString()) - - if (execResponse instanceof HashMap && execResponse.size() > 0) { - if (execResponse.containsKey("success") && execResponse["success"] == "ok") { - def publicUrl = execResponse["public_link"] - println() - println("--------------------------------------") - println("Your App was successfully updrafted!") - if (publicUrl != null) { - println("Get it here -> $publicUrl") - } - println("--------------------------------------") - } else if (execResponse.containsKey("detail") && execResponse["detail"] == "Not found.") { - throw new GradleException('Could not updraft to the given url. Please recheck that.') - } else { - throw new GradleException(os.toString()) - } - } else { - println(execResponse) - println() - println("--------------------------------------") - println("Your App was successfully updrafted!") - println("--------------------------------------") - } - } - } - } - - private static String createCurlParam(String text, String name) { - if (text == null || text.isBlank()) { - "" - } else { - "-F ${name}=${text}" - } - } -} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/GitBranchValueSource.kt b/lib/src/main/kotlin/com/appswithlove/updraft/GitBranchValueSource.kt new file mode 100644 index 0000000..6202202 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/GitBranchValueSource.kt @@ -0,0 +1,24 @@ +package com.appswithlove.updraft + +import org.gradle.api.provider.ValueSource +import org.gradle.api.provider.ValueSourceParameters +import java.io.ByteArrayOutputStream + +abstract class GitBranchValueSource : ValueSource { + override fun obtain(): String { + return try { + val process = ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD") + .redirectErrorStream(true) + .start() + + val outputStream = ByteArrayOutputStream() + process.inputStream.copyTo(outputStream) + process.waitFor() + + val result = outputStream.toString().trim() + result.ifEmpty { "" } + } catch (_: Exception) { + "" + } + } +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/GitCommitValueSource.kt b/lib/src/main/kotlin/com/appswithlove/updraft/GitCommitValueSource.kt new file mode 100644 index 0000000..9ad7fe2 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/GitCommitValueSource.kt @@ -0,0 +1,25 @@ +package com.appswithlove.updraft + +import org.gradle.api.provider.ValueSource +import org.gradle.api.provider.ValueSourceParameters +import java.io.ByteArrayOutputStream + +abstract class GitCommitValueSource : ValueSource { + + override fun obtain(): String { + return try { + val process = ProcessBuilder("git", "rev-parse", "HEAD") + .redirectErrorStream(true) + .start() + + val outputStream = ByteArrayOutputStream() + process.inputStream.copyTo(outputStream) + process.waitFor() + + val result = outputStream.toString().trim() + result.ifEmpty { "" } + } catch (_: Exception) { + "" + } + } +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/GitTagsValueSource.kt b/lib/src/main/kotlin/com/appswithlove/updraft/GitTagsValueSource.kt new file mode 100644 index 0000000..cf02f74 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/GitTagsValueSource.kt @@ -0,0 +1,25 @@ +package com.appswithlove.updraft + +import org.gradle.api.provider.ValueSource +import org.gradle.api.provider.ValueSourceParameters +import java.io.ByteArrayOutputStream + +abstract class GitTagsValueSource : ValueSource { + + override fun obtain(): String { + return try { + val process = ProcessBuilder("git", "describe", "--tags") + .redirectErrorStream(true) + .start() + + val outputStream = ByteArrayOutputStream() + process.inputStream.copyTo(outputStream) + process.waitFor() + + val result = outputStream.toString().trim() + result.ifEmpty { "" } + } catch (_: Exception) { + "" + } + } +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/GitUrlValueSource.kt b/lib/src/main/kotlin/com/appswithlove/updraft/GitUrlValueSource.kt new file mode 100644 index 0000000..ba45633 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/GitUrlValueSource.kt @@ -0,0 +1,25 @@ +package com.appswithlove.updraft + +import org.gradle.api.provider.ValueSource +import org.gradle.api.provider.ValueSourceParameters +import java.io.ByteArrayOutputStream + +abstract class GitUrlValueSource : ValueSource { + + override fun obtain(): String { + return try { + val process = ProcessBuilder("git", "config", "--get", "remote.origin.url") + .redirectErrorStream(true) + .start() + + val outputStream = ByteArrayOutputStream() + process.inputStream.copyTo(outputStream) + process.waitFor() + + val result = outputStream.toString().trim() + result.ifEmpty { "" } + } catch (_: Exception) { + "" + } + } +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftExtension.kt b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftExtension.kt new file mode 100644 index 0000000..ed9b060 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftExtension.kt @@ -0,0 +1,6 @@ +package com.appswithlove.updraft + +open class UpdraftExtension { + var urls: Map> = mapOf() + var releaseNotes: String? = null +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftPlugin.kt b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftPlugin.kt new file mode 100644 index 0000000..94b4201 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftPlugin.kt @@ -0,0 +1,168 @@ +package com.appswithlove.updraft + +import org.gradle.api.GradleException +import org.gradle.api.Plugin +import org.gradle.api.Project +import java.io.File + +/** + * A plugin for uploading APK/AAB files to updraft.*/ +class UpdraftPlugin : Plugin { + + override fun apply(project: Project) { + val updraftExtension = project.extensions.create("updraft", UpdraftExtension::class.java) + + val android = project.extensions.getByName("android") as com.android.build.gradle.AppExtension + android.applicationVariants.all { variant -> + val variantName = variant.name + val variantNameCapitalized = variantName.replaceFirstChar { it.uppercase() } + val flavorName = variant.flavorName + val buildTypeName = variant.buildType.name + + // Providers + val uploadUrlsProvider = project.providers.provider { updraftExtension.urls } + val uploadUrls = uploadUrlsProvider.map { urlsMap -> + val urlsForVariant = urlsMap[variantNameCapitalized] + when (urlsForVariant) { + is Iterable<*> -> urlsForVariant + else -> emptyList() + } + } + + val gitBranchProvider = project.providers.of(GitBranchValueSource::class.java) {} + val gitTagsProvider = project.providers.of(GitTagsValueSource::class.java) {} + val gitCommitProvider = project.providers.of(GitCommitValueSource::class.java) {} + val gitUrlProvider = project.providers.of(GitUrlValueSource::class.java) {} + val flavors = variant.productFlavors.map { it.name } + val releaseNotesProvider = + project.providers.provider { getReleaseNotes(project, flavors, updraftExtension) } + + // APK provider + val apkFileProvider = project.provider { + val buildDir = project.layout.buildDirectory.asFile.get() + val apkDir = File(buildDir, "outputs/apk/$flavorName/$buildTypeName") + + if (apkDir.exists() && apkDir.isDirectory) { + val apkFiles = + apkDir.listFiles { file -> file.name.endsWith(".apk") } ?: emptyArray() + if (apkFiles.size > 1) { + throw GradleException("More than one .apk file exists in $apkDir: ${apkFiles.map { it.name }}") + } + apkFiles.firstOrNull() + } else null + } + + val apkFile = apkFileProvider.flatMap { file -> + file.let { project.layout.file(project.provider { it }) } + } + + // AAB provider + val aabFileProvider = project.provider { + val buildDir = project.layout.buildDirectory.asFile.get() + val bundleDir = File(buildDir, "outputs/bundle/$variantName") + + if (bundleDir.exists() && bundleDir.isDirectory) { + val aabFiles = + bundleDir.listFiles { file -> file.name.endsWith(".aab") } ?: emptyArray() + if (aabFiles.size > 1) { + throw GradleException("More than one .aab file exists in $bundleDir: ${aabFiles.map { it.name }}") + } + aabFiles.firstOrNull() + } else null + } + + val aabFile = aabFileProvider.flatMap { file -> + file.let { project.layout.file(project.provider { it }) } + } + + // Register APK task + project.tasks.register( + "updraft$variantNameCapitalized", + UpdraftTask::class.java, + ) { task -> + task.outputFile.set(apkFile) + task.urls.set(uploadUrls) + task.gitBranch.set(gitBranchProvider) + task.gitTags.set(gitTagsProvider) + task.gitCommit.set(gitCommitProvider) + task.gitUrl.set(gitUrlProvider) + task.releaseNotes.set(releaseNotesProvider) + + task.doFirst { + val outputFile = apkFile.getOrNull()?.asFile + if (outputFile == null || !outputFile.exists()) { + throw GradleException("Could not find a build artifact. (Make sure to run assemble$variantNameCapitalized task first)") + } + } + } + + // Register AAB task + project.tasks.register( + "updraftBundle$variantNameCapitalized", + UpdraftTask::class.java, + ) { task -> + task.outputFile.set(aabFile) + task.urls.set(uploadUrls) + task.gitBranch.set(gitBranchProvider) + task.gitTags.set(gitTagsProvider) + task.gitCommit.set(gitCommitProvider) + task.gitUrl.set(gitUrlProvider) + task.releaseNotes.set(releaseNotesProvider) + + task.doFirst { + val outputFile = aabFile.getOrNull()?.asFile + if (outputFile == null || !outputFile.exists()) { + throw GradleException("Could not find a build artifact. (Make sure to run bundle$variantNameCapitalized task first)") + } + } + } + } + } + + private fun getReleaseNotes( + project: Project, + flavors: List, + updraftExtension: UpdraftExtension, + ): String { + project.findProperty("releaseNotes")?.let { + println("Using releaseNotes from gradle property") + return it.toString() + } + + updraftExtension.releaseNotes?.let { + println("Using releaseNotes from updraft extension") + return it + } + + val variantFile = if (flavors.isNotEmpty()) { + File("${project.projectDir}/src/${flavors[0]}/updraft/release-notes.txt") + } else { + null + } + val mainFile = File("${project.projectDir}/src/main/updraft/release-notes.txt") + + return when { + variantFile != null && variantFile.exists() -> { + println("Using releaseNotes from variant file") + variantFile.readLines().joinToString("\n") + } + + mainFile.exists() -> { + println("Using releaseNotes from main file") + mainFile.readLines().joinToString("\n") + } + + else -> { + println("Using releaseNotes last commit") + try { + val output = project.providers.exec { + it.commandLine("git", "log", "-1", "--pretty=%B") + }.standardOutput.asText.get() + output + } catch (_: Exception) { + "" + } + } + } + } +} diff --git a/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftTask.kt b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftTask.kt new file mode 100644 index 0000000..4f91bc9 --- /dev/null +++ b/lib/src/main/kotlin/com/appswithlove/updraft/UpdraftTask.kt @@ -0,0 +1,116 @@ +package com.appswithlove.updraft + +import groovy.json.JsonSlurperClassic +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import java.io.ByteArrayOutputStream +import javax.inject.Inject + +abstract class UpdraftTask : DefaultTask() { + + @get:Inject + abstract val execOperations: ExecOperations + + @get:InputFile + @get:Optional + abstract val outputFile: RegularFileProperty + + @get:Input + abstract val urls: ListProperty + + @get:Input + abstract val gitBranch: Property + + @get:Input + abstract val gitTags: Property + + @get:Input + abstract val gitCommit: Property + + @get:Input + abstract val gitUrl: Property + + @get:Input + abstract val releaseNotes: Property + + @TaskAction + fun upload() { + val fileToUpload = outputFile.asFile.get() + + var uploadUrls = urls.get() + if (uploadUrls.isEmpty()) { + throw GradleException("There was no url provided for this buildVariant. Please check for typos.") + } + + if (uploadUrls.size == 1 && uploadUrls[0].isNotBlank() && !uploadUrls[0].startsWith("http")) { + println("--------------------------------------") + println("Url was not wrapped in array. Doing it for you. :)") + println("url --> [url]") + println("--------------------------------------") + uploadUrls = listOf(uploadUrls[0]) + } + + uploadUrls.forEach { url -> + val curlArgs = listOf( + "-X", "PUT", + "-F", "app=@$fileToUpload", + "-F", "build_type=Gradle", + createCurlParam(gitBranch.get(), "custom_branch"), + createCurlParam(gitUrl.get(), "custom_URL"), + createCurlParam(gitTags.get(), "custom_tags"), + createCurlParam(gitCommit.get(), "custom_commit"), + createCurlParam(releaseNotes.get(), "whats_new"), + url + ).filter { it.isNotBlank() } + + ByteArrayOutputStream().use { os -> + execOperations.exec { + it.executable = "curl" + it.args = curlArgs + it.standardOutput = os + } + + val execResponse = JsonSlurperClassic().parseText(os.toString()) + + if (execResponse is Map<*, *> && execResponse.isNotEmpty()) { + when { + execResponse["success"] == "ok" -> { + val publicUrl = execResponse["public_link"] + println("\n--------------------------------------") + println("Your App was successfully updrafted!") + if (publicUrl != null) println("Get it here -> $publicUrl") + println("--------------------------------------") + } + + execResponse["detail"] == "Not found." -> { + throw GradleException("Could not updraft to the given url. Please recheck that.") + } + + else -> { + throw GradleException(os.toString()) + } + } + } else { + println(execResponse) + println("\n--------------------------------------") + println("Your App was successfully updrafted!") + println("--------------------------------------") + } + } + } + } + + companion object { + private fun createCurlParam(text: String?, name: String): String { + return if (text.isNullOrBlank()) "" else "-F $name=$text" + } + } +} diff --git a/lib/src/main/resources/META-INF/gradle-plugins/com.appswithlove.updraft.properties b/lib/src/main/resources/META-INF/gradle-plugins/com.appswithlove.updraft.properties deleted file mode 100644 index 9196917..0000000 --- a/lib/src/main/resources/META-INF/gradle-plugins/com.appswithlove.updraft.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=com.appswithlove.updraft.UpdraftPlugin diff --git a/local.properties b/local.properties deleted file mode 100644 index 4b5a997..0000000 --- a/local.properties +++ /dev/null @@ -1,8 +0,0 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Tue Apr 09 16:10:41 CEST 2019 -sdk.dir=/Users/yannickpulver/Library/Android/sdk diff --git a/sample/build.gradle b/sample/build.gradle deleted file mode 100644 index 478f682..0000000 --- a/sample/build.gradle +++ /dev/null @@ -1,89 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile - -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id 'com.appswithlove.updraft' - id 'org.jetbrains.kotlin.plugin.compose' -} - -android { - namespace = 'com.appswithlove.sample' - compileSdk = 36 - - defaultConfig { - applicationId "com.appswithlove.updraft.sample" - minSdk 29 - targetSdk 36 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary true - } - } - - flavorDimensions "main" - productFlavors { - stage { - dimension = "main" - } - prod { - dimension = "main" - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - tasks.withType(KotlinJvmCompile).configureEach { - compilerOptions { - jvmTarget = JvmTarget.JVM_1_8 - freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") - } - } - - buildFeatures { - compose true - } - - composeOptions { - kotlinCompilerExtensionVersion compose_version - } - - packagingOptions { - resources { - excludes += '/META-INF/{AL2.0,LGPL2.1}' - } - } -} - -dependencies { - implementation 'androidx.core:core-ktx:1.16.0' - implementation "androidx.compose.ui:ui:$compose_version" - implementation "androidx.compose.material:material:$compose_version" - implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.9.2' - implementation 'androidx.activity:activity-compose:1.10.1' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.2.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' - androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" - debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" -} - -updraft { - urls['StageDebug'] = ["https://app.getupdraft.com/api/app_upload/eaa30e534f824fde8b9a0d8b7071834a/65ae1e0f4b1f4b1898c9c956c4486289/"] - urls['ProdDebug'] = ["https://app.getupdraft.com/api/app_upload/3e49bd8893624de0a44d919fa05b7b6c/65ae1e0f4b1f4b1898c9c956c4486289/"] -} diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts new file mode 100644 index 0000000..cb96a3a --- /dev/null +++ b/sample/build.gradle.kts @@ -0,0 +1,93 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.updraft) +} + +android { + namespace = "com.appswithlove.sample" + compileSdk = 36 + + defaultConfig { + applicationId = "com.appswithlove.updraft.sample" + minSdk = 29 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + flavorDimensions += "main" + productFlavors { + create("stage") { + dimension = "main" + } + create("prod") { + dimension = "main" + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") + } + } + + buildFeatures { + compose = true + } + + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(11)) + } +} + +kotlin { + jvmToolchain(11) +} + +updraft { + urls = mapOf( + "StageDebug" to listOf("https://app.getupdraft.com/api_upload/.../.../"), + "ProdRelease" to listOf("https://app.getupdraft.com/api_upload/.../.../"), + ) +} + +dependencies { + implementation(platform(libs.compose.bom)) + implementation(libs.core.ktx) + implementation(libs.ui) + implementation(libs.material) + implementation(libs.ui.tooling.preview) + implementation(libs.lifecycle.runtime.ktx) + implementation(libs.activity.compose) + debugImplementation(libs.ui.tooling) + implementation(libs.junit) +} diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 6ad1044..e139f8a 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -7,6 +7,17 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/Theme" /> + android:theme="@style/Theme"> + + + + + + + + \ No newline at end of file diff --git a/sample/src/main/java/com/appswithlove/updraft/sample/MainActivity.kt b/sample/src/main/java/com/appswithlove/updraft/sample/MainActivity.kt new file mode 100644 index 0000000..e02de31 --- /dev/null +++ b/sample/src/main/java/com/appswithlove/updraft/sample/MainActivity.kt @@ -0,0 +1,51 @@ +package com.appswithlove.updraft.sample + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.appswithlove.updraft.sample.ui.theme.UpdraftTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + UpdraftTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colors.background + ) { + HomeScreen() + } + } + } + } +} + +@Composable +fun HomeScreen() { + Column( + Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Text(text = "Hey there!") + } +} + +@Preview(showBackground = true) +@Composable +fun DefaultPreview() { + UpdraftTheme { + HomeScreen() + } +} diff --git a/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Color.kt b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Color.kt new file mode 100644 index 0000000..66e8739 --- /dev/null +++ b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Color.kt @@ -0,0 +1,8 @@ +package com.appswithlove.updraft.sample.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple200 = Color(0xFFBB86FC) +val Purple500 = Color(0xFF6200EE) +val Purple700 = Color(0xFF3700B3) +val Teal200 = Color(0xFF03DAC5) diff --git a/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Shape.kt b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Shape.kt new file mode 100644 index 0000000..203bbfb --- /dev/null +++ b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Shape.kt @@ -0,0 +1,11 @@ +package com.appswithlove.updraft.sample.ui.theme + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Shapes +import androidx.compose.ui.unit.dp + +val Shapes = Shapes( + small = RoundedCornerShape(4.dp), + medium = RoundedCornerShape(4.dp), + large = RoundedCornerShape(0.dp) +) diff --git a/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Theme.kt b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Theme.kt new file mode 100644 index 0000000..43c01c8 --- /dev/null +++ b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Theme.kt @@ -0,0 +1,44 @@ +package com.appswithlove.updraft.sample.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.MaterialTheme +import androidx.compose.material.darkColors +import androidx.compose.material.lightColors +import androidx.compose.runtime.Composable + +private val DarkColorPalette = darkColors( + primary = Purple200, + primaryVariant = Purple700, + secondary = Teal200 +) + +private val LightColorPalette = lightColors( + primary = Purple500, + primaryVariant = Purple700, + secondary = Teal200 + + /* Other default colors to override + background = Color.White, + surface = Color.White, + onPrimary = Color.White, + onSecondary = Color.Black, + onBackground = Color.Black, + onSurface = Color.Black, + */ +) + +@Composable +fun UpdraftTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { + val colors = if (darkTheme) { + DarkColorPalette + } else { + LightColorPalette + } + + MaterialTheme( + colors = colors, + typography = Typography, + shapes = Shapes, + content = content + ) +} diff --git a/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Type.kt b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Type.kt new file mode 100644 index 0000000..4009c8c --- /dev/null +++ b/sample/src/main/java/com/appswithlove/updraft/sample/ui/theme/Type.kt @@ -0,0 +1,27 @@ +package com.appswithlove.updraft.sample.ui.theme + +import androidx.compose.material.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +val Typography = Typography( + body1 = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp + ) + /* Other default text styles to override + button = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + fontSize = 14.sp + ), + caption = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 12.sp + ) + */ +) diff --git a/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.java b/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.java deleted file mode 100644 index cd5edf5..0000000 --- a/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.appswithlove.sample; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.kt b/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.kt new file mode 100644 index 0000000..7a5e023 --- /dev/null +++ b/sample/src/test/java/com/appswithlove/sample/ExampleUnitTest.kt @@ -0,0 +1,11 @@ +package com.appswithlove.sample + +import org.junit.Test +import org.junit.Assert.* + +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/settings.gradle b/settings.gradle.kts similarity index 78% rename from settings.gradle rename to settings.gradle.kts index c4e16b3..5c8f694 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -14,5 +14,6 @@ dependencyResolutionManagement { } } -include ':sample' -include ':lib' +rootProject.name = "updraft-plugin-android" +include(":sample") +include(":lib")