diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 814cd8e..7d75f5c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,3 @@ -# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions -# Renaming ? Change the README badge. name: Build on: push: @@ -11,9 +9,14 @@ jobs: name: Base Checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 17 - - name: Perform base checks - run: ./gradlew build publishToDirectory \ No newline at end of file + distribution: temurin + cache: gradle + - uses: gradle/actions/wrapper-validation@v4 + - name: Check local deployment + run: ./gradlew build deployLocal + - name: Check sample app + run: cd tests && ../gradlew sample-library:assembleDebug \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 436687d..ed70656 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,17 +3,24 @@ on: release: types: [published] jobs: - BINTRAY_UPLOAD: - name: Bintray Upload + DEPLOY: + name: GitHub and Maven Central publication runs-on: ubuntu-latest env: - BINTRAY_USER: ${{ secrets.BINTRAY_USER }} - BINTRAY_KEY: ${{ secrets.BINTRAY_KEY }} - BINTRAY_REPO: ${{ secrets.BINTRAY_REPO }} + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + SONATYPE_USER: ${{ secrets.SONATYPE_USER }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GHUB_USER: ${{ secrets.GHUB_USER }} + GHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.GHUB_PERSONAL_ACCESS_TOKEN }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: - java-version: 1.8 - - name: Publish to Bintray - run: ./gradlew publishToBintray + java-version: 17 + distribution: temurin + cache: gradle + - name: Publish to Maven Central + run: ./gradlew deployNexus + - name: Publish to GitHub Packages + run: ./gradlew deployGithub \ No newline at end of file diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml new file mode 100644 index 0000000..24603f3 --- /dev/null +++ b/.github/workflows/snapshot.yml @@ -0,0 +1,23 @@ +name: Snapshot +on: + push: + branches: + - main +jobs: + SNAPSHOT: + name: Publish Snapshot + runs-on: ubuntu-latest + env: + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + SONATYPE_USER: ${{ secrets.SONATYPE_USER }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: gradle + - name: Publish Nexus Snapshot + run: ./gradlew deployNexusSnapshot \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7ef5a0e..cbef6a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.iml .gradle -/local.properties -/.idea/ +**/local.properties +**/.idea/ .DS_Store /build /captures diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index b5d9bbf..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
- - -
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b589d56..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index cb258ed..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 199e049..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml deleted file mode 100644 index a6fe551..0000000 --- a/.idea/kotlinScripting.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/markdown-navigator-enh.xml b/.idea/markdown-navigator-enh.xml deleted file mode 100644 index 12fb99d..0000000 --- a/.idea/markdown-navigator-enh.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml deleted file mode 100644 index 4463382..0000000 --- a/.idea/markdown-navigator.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index bb67fd9..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - 1.8 - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/Grease_grease__publishAllDirectory_.xml b/.idea/runConfigurations/Grease_grease__publishAllDirectory_.xml deleted file mode 100644 index 373b61a..0000000 --- a/.idea/runConfigurations/Grease_grease__publishAllDirectory_.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - true - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0e57478 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 DeepMedia Srl + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 2c1486f..cbdd165 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,30 @@ -[![Build Status](https://github.com/deepmedia/Grease/workflows/Build/badge.svg?event=push)](https://github.com/deepmedia/Grease/actions) +[![Build Status](https://github.com/deepmedia/Grease/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/deepmedia/Grease/actions) [![Release](https://img.shields.io/github/release/deepmedia/Grease.svg)](https://github.com/deepmedia/Grease/releases) [![Issues](https://img.shields.io/github/issues-raw/deepmedia/Grease.svg)](https://github.com/deepmedia/Grease/issues) # Grease A Gradle plugin for creating fat AARs, useful for distributing multiple modules in a single file. -To install the plugin, you must configure the build script classpath: +To install the plugin, apply it to your Android project: ```kotlin -buildscript { +// settings.gradle.kts +pluginManagement { repositories { - jcenter() - google() - } - dependencies { - classpath("io.deepmedia.tools:grease:0.2.0") + mavenCentral() } } -``` -## Usage +// build.gradle.kts +plugins { + id("com.android.library") + id("io.deepmedia.tools.grease") version "0.4.0" +} +``` -To apply the plugin, declare it in your build script with the `io.deepmedia.tools.grease` id. -This must be done after the com.android.library plugin: +Note: it is important that Grease is applied *after* the Android library plugin. -```groovy -apply plugin: 'com.android.library' -apply plugin: 'io.deepmedia.tools.grease' -``` +## Usage Once applied, Grease will create Gradle configurations that you can use to select which of your dependencies should be bundled in the final fat AAR. @@ -61,19 +58,21 @@ dependencies that you own, to be sure that they won't be present in the classpat ### Transitivity -When you add a grease dependency, by default all transitive dependencies are greased as well, so -they will become part of the fat AARs. To avoid this, you can mark the configuration as non transitive: +By default, declaring a specific grease dependency **will not** include transitive dependencies. +To do so, you can use grease configurations ending in `Tree`: ```kotlin -configurations["grease"].isTransitive = false -configurations["greaseRelease"].isTransitive = false -configurations["greaseDebug"].isTransitive = false - -// Variant specific configurations are created lazily so you must wait for them to be -// available before modifying them. -configurations.configureEach { - if (name == "greaseBlueCircleDebug") { - isTransitive = false - } +dependencies { + grease("my-package:artifact:1.0.0") // not transitive + greaseTree("my-other-package:other-artifact:1.0.0") // transitive } -``` \ No newline at end of file +``` + +### Relocations + +We support relocations through the popular [Shadow](https://github.com/GradleUp/shadow) plugin. Inside the `grease` +extension, you can use: + +- `relocate(prefix: String)` to relocate all included packages by prefixing them with the given prefix. Defaults to `"grease"`. +- `relocate(from: String, to: String, configure: Action)` to register a package-specific relocator, + as described in the [shadow plugin docs](https://gradleup.com/shadow/configuration/relocation/#relocating-packages) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135..2c35211 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index 1aa94a4..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 6689b85..9b42019 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/grease/build.gradle.kts b/grease/build.gradle.kts index 7b8948e..b6375cc 100644 --- a/grease/build.gradle.kts +++ b/grease/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "io.deepmedia.tools" -version = "0.3.0" +version = "0.4.0" gradlePlugin { plugins { @@ -30,9 +30,49 @@ deployer { } projectInfo { - description = "Fat AARs for Android." + description = "Fat AARs for Android, to distribute multiple library modules in a single file with no dependencies, with relocation support." url = "https://github.com/deepmedia/Grease" scm.fromGithub("deepmedia", "Grease") - developer("natario1", "mattia@deepmedia.io", "DeepMedia", "https://deepmedia.io") + developer("Mattia Iavarone", "mattia@deepmedia.io", "DeepMedia", "https://deepmedia.io") + license(apache2) + } + + signing { + key = secret("SIGNING_KEY") + password = secret("SIGNING_PASSWORD") + } + + // use "deployLocal" to deploy to local maven repository + localSpec { + directory.set(rootProject.layout.buildDirectory.get().dir("inspect")) + signing { + key = absent() + password = absent() + } + } + + // use "deployNexus" to deploy to OSSRH / maven central + nexusSpec { + auth.user = secret("SONATYPE_USER") + auth.password = secret("SONATYPE_PASSWORD") + syncToMavenCentral = true + } + + // use "deployNexusSnapshot" to deploy to sonatype snapshots repo + nexusSpec("snapshot") { + auth.user = secret("SONATYPE_USER") + auth.password = secret("SONATYPE_PASSWORD") + repositoryUrl = ossrhSnapshots1 + release.version = "latest-SNAPSHOT" + } + + // use "deployGithub" to deploy to github packages + githubSpec { + repository = "Grease" + owner = "deepmedia" + auth { + user = secret("GHUB_USER") + token = secret("GHUB_PERSONAL_ACCESS_TOKEN") + } } } \ No newline at end of file diff --git a/grease/src/main/kotlin/io/deepmedia/tools/grease/GreaseExtension.kt b/grease/src/main/kotlin/io/deepmedia/tools/grease/GreaseExtension.kt index 15c79da..bb2ce2b 100644 --- a/grease/src/main/kotlin/io/deepmedia/tools/grease/GreaseExtension.kt +++ b/grease/src/main/kotlin/io/deepmedia/tools/grease/GreaseExtension.kt @@ -3,35 +3,31 @@ package io.deepmedia.tools.grease import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer +import org.gradle.api.Action +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.listProperty +import org.gradle.kotlin.dsl.newInstance +import org.gradle.kotlin.dsl.property +import javax.inject.Inject -abstract class GreaseExtension { +abstract class GreaseExtension @Inject constructor(objects: ObjectFactory) { - internal val relocators = mutableListOf() - internal val transformers = mutableListOf() + internal val prefix = objects.property().convention("") + internal val relocators = objects.listProperty() + internal val transformers = objects.listProperty() - internal var isRelocationEnabled = false - var relocationPrefix: String = "shadow" - set(value) { - field = value - isRelocationEnabled = true - } + fun relocate(prefix: String = "grease") { + this.prefix.set(prefix) + } - fun relocate( - from: String, - to: String, - configure: (SimpleRelocator.() -> Unit)? = null - ) { + fun relocate(from: String, to: String, configure: Action = Action { }) { val relocator = SimpleRelocator(from, to, emptyList(), emptyList()) - configure?.invoke(relocator) + configure.execute(relocator) relocators.add(relocator) } - fun transform( - transformer: T, - configure: (T.() -> Unit)? = null - ) { - configure?.invoke(transformer) + fun transform(transformer: T, configure: Action = Action { }) { + configure.execute(transformer) transformers.add(transformer) } - } \ No newline at end of file diff --git a/grease/src/main/kotlin/io/deepmedia/tools/grease/GreasePlugin.kt b/grease/src/main/kotlin/io/deepmedia/tools/grease/GreasePlugin.kt index 45c4ed5..b23770d 100644 --- a/grease/src/main/kotlin/io/deepmedia/tools/grease/GreasePlugin.kt +++ b/grease/src/main/kotlin/io/deepmedia/tools/grease/GreasePlugin.kt @@ -2,6 +2,8 @@ package io.deepmedia.tools.grease +import com.android.build.api.component.analytics.AnalyticsEnabledLibraryVariant +import com.android.build.api.component.analytics.AnalyticsEnabledVariant import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.Variant import com.android.build.api.variant.impl.getApiString @@ -121,7 +123,7 @@ open class GreasePlugin : Plugin { val log = logger.child("configureVariantManifest") log.d { "Configuring variant output ${variant.name}..." } - val componentConfig = variant as ComponentCreationConfig + val componentConfig = variant.componentCreationConfigOrThrow() target.locateTask(componentConfig.computeTaskName("process", "Manifest"))?.configure { val processManifestTask = this as ProcessLibraryManifest @@ -222,7 +224,7 @@ open class GreasePlugin : Plugin { val log = logger.child("configureVariantJniLibs") log.d { "Configuring variant ${variant.name}..." } - val creationConfig = variant as ComponentCreationConfig + val creationConfig = variant.componentCreationConfigOrThrow() target.locateTask(creationConfig.computeTaskName("copy", "JniLibsProjectAndLocalJars"))?.configure { val copyJniTask = this as LibraryJniLibsTask @@ -319,7 +321,7 @@ open class GreasePlugin : Plugin { val log = logger.child("configureVariantResources") log.d { "Configuring variant ${variant.name}..." } - val creationConfig = variant as ComponentCreationConfig + val creationConfig = variant.componentCreationConfigOrThrow() target.locateTask(creationConfig.computeTaskName("package", "Resources"))?.configure { this as MergeResources @@ -389,7 +391,7 @@ open class GreasePlugin : Plugin { val log = logger.child("configureVariantSources") log.d { "Configuring variant ${variant.name}..." } - val creationConfig = variant as ComponentCreationConfig + val creationConfig = variant.componentCreationConfigOrThrow() val workdir = target.greaseBuildDir.get().dir(variant.name) val aarExtractWorkdir = workdir.dir("extract").dir("aar") @@ -479,27 +481,28 @@ open class GreasePlugin : Plugin { } } - if (greaseExtension.isRelocationEnabled) { + val relocationPrefix = greaseExtension.prefix.get() + if (relocationPrefix.isNotEmpty()) { greaseProcessTask.get().outputs.files .asSequence() .flatMap { inputFile -> inputFile.packageNames } .distinct() .forEach { packageName -> - val newPackageName = "${greaseExtension.relocationPrefix}.$packageName" + val newPackageName = "${relocationPrefix}.$packageName" log.d { "Relocate package from $packageName to $newPackageName" } relocate(packageName, newPackageName) packagesToReplace[packageName] = newPackageName } + } - greaseExtension.relocators.forEach { relocator -> - relocate(relocator) - if (relocator is SimpleRelocator) { - packagesToReplace[relocator.pattern] = relocator.shadedPattern - } + greaseExtension.relocators.get().forEach { relocator -> + relocate(relocator) + if (relocator is SimpleRelocator) { + packagesToReplace[relocator.pattern] = relocator.shadedPattern } - greaseExtension.transformers.forEach(::transform) - } + + greaseExtension.transformers.get().forEach(::transform) } doLast { @@ -567,7 +570,7 @@ open class GreasePlugin : Plugin { ) { val log = logger.child("configureVariantAssets") log.d { "Configuring variant ${variant.name}..." } - val creationConfig = variant as ComponentCreationConfig + val creationConfig = variant.componentCreationConfigOrThrow() creationConfig.taskContainer.mergeAssetsTask.configure { val extraAssets = configurations.artifactsOf(AndroidArtifacts.ArtifactType.ASSETS) dependsOn(extraAssets) @@ -621,7 +624,7 @@ open class GreasePlugin : Plugin { ) { val log = logger.child("configureVariantProguardFiles") log.d { "Configuring variant ${variant.name}..." } - val creationConfig = variant as ComponentCreationConfig + val creationConfig = variant.componentCreationConfigOrThrow() target.locateTask(creationConfig.computeTaskName("merge", "ConsumerProguardFiles"))?.configure { val mergeFileTask = this as MergeFileTask // UNFILTERED_PROGUARD_RULES, FILTERED_PROGUARD_RULES, AAPT_PROGUARD_RULES, ... @@ -637,3 +640,11 @@ open class GreasePlugin : Plugin { } } } + +private fun Variant.componentCreationConfigOrThrow(): ComponentCreationConfig { + return when (this) { + is ComponentCreationConfig -> this + is AnalyticsEnabledVariant -> this.delegate.componentCreationConfigOrThrow() + else -> error("Could not find ComponentCreationConfig in $this.") + } +} diff --git a/grease/src/main/kotlin/io/deepmedia/tools/grease/RClassRelocator.kt b/grease/src/main/kotlin/io/deepmedia/tools/grease/RClassRelocator.kt index 52f22d6..4272338 100644 --- a/grease/src/main/kotlin/io/deepmedia/tools/grease/RClassRelocator.kt +++ b/grease/src/main/kotlin/io/deepmedia/tools/grease/RClassRelocator.kt @@ -16,7 +16,7 @@ internal class RClassRelocator( init { include( "%regex[$fromRPathRegex\\$.*]") - include( "%regex[$fromRPathRegex.*]") + include( "%regex[$fromRPathRegex]") } override fun canRelocateClass(className: String?): Boolean = false diff --git a/grease/src/main/kotlin/io/deepmedia/tools/grease/configurations.kt b/grease/src/main/kotlin/io/deepmedia/tools/grease/configurations.kt index 76bfdf1..0bf055e 100644 --- a/grease/src/main/kotlin/io/deepmedia/tools/grease/configurations.kt +++ b/grease/src/main/kotlin/io/deepmedia/tools/grease/configurations.kt @@ -40,11 +40,7 @@ private class ArtifactsFileCollection(private val fileCollections: List TaskContainer.locateOrRegisterTask( return locateTask(name, type) ?: registerTask(name, type, body = body) } +@Suppress("UNCHECKED_CAST") internal fun TaskContainer.locateOrRegisterTask(name: String, body: Task.() -> (Unit)): TaskProvider { return (locateTask(name, DefaultTask::class.java) ?: registerTask(name, DefaultTask::class.java, body = body)) as TaskProvider } diff --git a/sample/consumer-rules.pro b/sample/consumer-rules.pro deleted file mode 100644 index 57eb197..0000000 --- a/sample/consumer-rules.pro +++ /dev/null @@ -1,3 +0,0 @@ --keepclassmembers class sample.class.from.consumer.rules { - public *; -} \ No newline at end of file diff --git a/sample/proguard-rules.pro b/sample/proguard-rules.pro deleted file mode 100644 index 7d9d656..0000000 --- a/sample/proguard-rules.pro +++ /dev/null @@ -1,5 +0,0 @@ - --keepattributes SourceFile,LineNumberTable --keepclassmembers class sample.class.from.default.rules { - public *; -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index ea26650..8c8f6c4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,4 @@ pluginManagement { - includeBuild("./grease") repositories { google() gradlePluginPortal() @@ -14,8 +13,11 @@ dependencyResolutionManagement { gradlePluginPortal() mavenCentral() } + versionCatalogs { + create("libs") + } } -rootProject.name = "grease" +rootProject.name = "Grease" -include(":sample") \ No newline at end of file +include(":grease") \ No newline at end of file diff --git a/tests/gradle.properties b/tests/gradle.properties new file mode 100644 index 0000000..83df5e3 --- /dev/null +++ b/tests/gradle.properties @@ -0,0 +1,19 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official diff --git a/sample/.gitignore b/tests/sample-dependency-pure/.gitignore similarity index 100% rename from sample/.gitignore rename to tests/sample-dependency-pure/.gitignore diff --git a/tests/sample-dependency-pure/build.gradle.kts b/tests/sample-dependency-pure/build.gradle.kts new file mode 100644 index 0000000..c3b88ba --- /dev/null +++ b/tests/sample-dependency-pure/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + alias(libs.plugins.android.library) +} + +android { + namespace = "io.deepmedia.tools.grease.sample.dependency.pure" + compileSdk = 34 + defaultConfig { + minSdk = 21 + } +} + +dependencies { + // Empty +} \ No newline at end of file diff --git a/tests/sample-dependency-pure/src/main/AndroidManifest.xml b/tests/sample-dependency-pure/src/main/AndroidManifest.xml new file mode 100644 index 0000000..972c3a8 --- /dev/null +++ b/tests/sample-dependency-pure/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sample-dependency-pure/src/main/java/io/deepmedia/tools/grease/sample/dependency/pure/PureDependencyClass.kt b/tests/sample-dependency-pure/src/main/java/io/deepmedia/tools/grease/sample/dependency/pure/PureDependencyClass.kt new file mode 100644 index 0000000..dd8276f --- /dev/null +++ b/tests/sample-dependency-pure/src/main/java/io/deepmedia/tools/grease/sample/dependency/pure/PureDependencyClass.kt @@ -0,0 +1,5 @@ +package io.deepmedia.tools.grease.sample.dependency.pure + +object PureDependencyClass { + fun foo() = "bar" +} \ No newline at end of file diff --git a/tests/sample-library/.gitignore b/tests/sample-library/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/tests/sample-library/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/sample/build.gradle.kts b/tests/sample-library/build.gradle.kts similarity index 73% rename from sample/build.gradle.kts rename to tests/sample-library/build.gradle.kts index 92ad8f2..55b2e61 100644 --- a/sample/build.gradle.kts +++ b/tests/sample-library/build.gradle.kts @@ -4,13 +4,13 @@ plugins { } grease { - relocationPrefix = "temp" + relocate() } android { - namespace = "io.deepmedia.tools.grease.sample" - ndkVersion = "20.1.5948944" - compileSdk = 29 + namespace = "io.deepmedia.tools.grease.sample.library" + ndkVersion = "23.1.7779620" + compileSdk = 34 defaultConfig { minSdk = 21 @@ -56,17 +56,19 @@ android { } dependencies { - greaseApi("androidx.core:core:1.0.0") + grease("androidx.core:core:1.0.0") // include deps to pom when publishing api("com.google.android.material:material:1.0.0") // Includes resource and some manifest changes implementation("androidx.lifecycle:lifecycle-runtime:2.8.4") - afterEvaluate { - // Includes native libraries - "greaseApi"("org.tensorflow:tensorflow-lite:2.3.0") - // Manifest changes, layout resources - "grease"("com.otaliastudios:cameraview:2.7.2") - } + // Includes native libraries + grease("org.tensorflow:tensorflow-lite:2.3.0") + // Manifest changes, layout resources + grease("com.otaliastudios:cameraview:2.7.2") + + // Doesn't work. TODO: we need to configure grease configurations so that in case of multiple matching + // variants, they prefer one where com.android.build.api.attributes.BuildTypeAttr is set to release + // grease(project(":sample-dependency-pure")) } \ No newline at end of file diff --git a/sample/src/main/assets/sample_asset_2.png b/tests/sample-library/consumer-rules.pro similarity index 100% rename from sample/src/main/assets/sample_asset_2.png rename to tests/sample-library/consumer-rules.pro diff --git a/tests/sample-library/proguard-rules.pro b/tests/sample-library/proguard-rules.pro new file mode 100644 index 0000000..c14a015 --- /dev/null +++ b/tests/sample-library/proguard-rules.pro @@ -0,0 +1,2 @@ + +-keepattributes SourceFile,LineNumberTable \ No newline at end of file diff --git a/sample/src/main/AndroidManifest.xml b/tests/sample-library/src/main/AndroidManifest.xml similarity index 100% rename from sample/src/main/AndroidManifest.xml rename to tests/sample-library/src/main/AndroidManifest.xml diff --git a/sample/src/main/CMakeLists.txt b/tests/sample-library/src/main/CMakeLists.txt similarity index 100% rename from sample/src/main/CMakeLists.txt rename to tests/sample-library/src/main/CMakeLists.txt diff --git a/sample/src/main/assets/sample_asset_1 b/tests/sample-library/src/main/assets/sample_asset_1 similarity index 100% rename from sample/src/main/assets/sample_asset_1 rename to tests/sample-library/src/main/assets/sample_asset_1 diff --git a/sample/src/main/assets/sample_asset_3.log b/tests/sample-library/src/main/assets/sample_asset_2.png similarity index 100% rename from sample/src/main/assets/sample_asset_3.log rename to tests/sample-library/src/main/assets/sample_asset_2.png diff --git a/tests/sample-library/src/main/assets/sample_asset_3.log b/tests/sample-library/src/main/assets/sample_asset_3.log new file mode 100644 index 0000000..e69de29 diff --git a/sample/src/main/cc/grease-api.cc b/tests/sample-library/src/main/cc/grease-api.cc similarity index 100% rename from sample/src/main/cc/grease-api.cc rename to tests/sample-library/src/main/cc/grease-api.cc diff --git a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleActivity.java b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleActivity.java similarity index 89% rename from sample/src/main/java/io/deepmedia/tools/grease/sample/SampleActivity.java rename to tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleActivity.java index ccd27b2..c7e6ec2 100644 --- a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleActivity.java +++ b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleActivity.java @@ -1,4 +1,4 @@ -package io.deepmedia.tools.grease.sample; +package io.deepmedia.tools.grease.sample.library; import android.app.Activity; import android.os.Bundle; diff --git a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleApplication.java b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleApplication.java similarity index 82% rename from sample/src/main/java/io/deepmedia/tools/grease/sample/SampleApplication.java rename to tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleApplication.java index dd06af7..1525fa3 100644 --- a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleApplication.java +++ b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleApplication.java @@ -1,4 +1,4 @@ -package io.deepmedia.tools.grease.sample; +package io.deepmedia.tools.grease.sample.library; import android.app.Application; import android.util.Log; diff --git a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleView.java b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleView.java similarity index 82% rename from sample/src/main/java/io/deepmedia/tools/grease/sample/SampleView.java rename to tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleView.java index 459666c..6921d51 100644 --- a/sample/src/main/java/io/deepmedia/tools/grease/sample/SampleView.java +++ b/tests/sample-library/src/main/java/io/deepmedia/tools/grease/sample/library/SampleView.java @@ -1,4 +1,4 @@ -package io.deepmedia.tools.grease.sample; +package io.deepmedia.tools.grease.sample.library; import android.content.Context; import android.util.Log; diff --git a/sample/src/main/res/layout/sample_layout.xml b/tests/sample-library/src/main/res/layout/sample_layout.xml similarity index 82% rename from sample/src/main/res/layout/sample_layout.xml rename to tests/sample-library/src/main/res/layout/sample_layout.xml index 94c192d..08dd18d 100644 --- a/sample/src/main/res/layout/sample_layout.xml +++ b/tests/sample-library/src/main/res/layout/sample_layout.xml @@ -1,5 +1,5 @@ -