diff --git a/.editorconfig b/.editorconfig index ded11e1..843663b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,26 @@ root = true [*] +indent_style = space +indent_size = 2 + +end_of_line = lf charset = utf-8 -indent_size = 4 +trim_trailing_whitespace = true insert_final_newline = true + +[*.{java,kt,kts,scala,rs,xml,kt.spec,kts.spec}] +indent_size = 4 + +[*.{kt,kts}] +ktlint_code_style = android +ktlint_ignore_back_ticked_identifier = true +max_line_length = 200 +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_allow_trailing_comma = true +ij_kotlin_allow_trailing_comma_on_call_site = true + +[*.md] trim_trailing_whitespace = true [*{.yml,yaml}] diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..d254421 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,19 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ + +/.name +/compiler.xml +/encodings.xml +/gradle.xml +/kotlinc.xml +/kotlinScripting.xml +/misc.xml +/vcs.xml +codeStyles/codeStyleConfig.xml +codeStyles/Project.xml diff --git a/LICENSE b/LICENSE index 1b795d0..41950c3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020 +Copyright (c) 2023 Axzae Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index de09bba..b7d261f 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,92 @@ -# kotlin-gradle-plugin-template 🐘 +# Unmeta Gradle Plugin for Android -[![Use this template](https://img.shields.io/badge/-Use%20this%20template-brightgreen)](https://github.com/cortinico/kotlin-gradle-plugin-template/generate) [![Pre Merge Checks](https://github.com/cortinico/kotlin-gradle-plugin-template/workflows/Pre%20Merge%20Checks/badge.svg)](https://github.com/cortinico/kotlin-gradle-plugin-template/actions?query=workflow%3A%22Pre+Merge+Checks%22) [![License](https://img.shields.io/github/license/cortinico/kotlin-android-template.svg)](LICENSE) ![Language](https://img.shields.io/github/languages/top/cortinico/kotlin-android-template?color=blue&logo=kotlin) +

-A simple Github template that lets you create a **Gradle Plugin** 🐘 project using **100% Kotlin** and be up and running in a **few seconds**. +[![build](https://img.shields.io/github/actions/workflow/status/axzae/unmeta-gradle-plugin/pre-merge.yaml?branch=main)][actions] +[![plugin portal](https://img.shields.io/gradle-plugin-portal/v/com.axzae.unmeta)][pluginportal] -This template is focused on delivering a project with **static analysis** and **continuous integration** already in place. +

-## How to use 👣 +A gradle plugin for Android Project to remove all Kotlin [`@DebugMetadata`][debugmetadata] annotations from the compiled +classes. -Just click on [![Use this template](https://img.shields.io/badge/-Use%20this%20template-brightgreen)](https://github.com/cortinico/kotlin-gradle-plugin-template/generate) button to create a new repo starting from this template. +Kotlin Coroutines' [`@DebugMetadata`][debugmetadata] annotations [are not fully processed by ProGuard / R8][1] and +contain un-obfuscated symbol information, both in binary and plain text forms. This information can be used to more +easily reverse engineer your code. -Once created don't forget to update the: -- [gradle.properties](plugin-build/gradle.properties) -- Plugin Usages (search for [com.ncorti.kotlin.gradle.template](https://github.com/cortinico/kotlin-gradle-plugin-template/search?q=com.ncorti.kotlin.gradle.template&unscoped_q=com.ncorti.kotlin.gradle.template) in the repo and replace it with your ID). +This plugin allows removing all Kotlin [`@DebugMetadata`][debugmetadata] annotations from generated class files in * +*release** build. -## Features 🎨 +## Usage -- **100% Kotlin-only template**. -- Plugin build setup with **composite build**. -- 100% Gradle Kotlin DSL setup. -- Dependency versions managed via Gradle Versions Catalog (`libs.versions.toml`). -- CI Setup with GitHub Actions. -- Kotlin Static Analysis via `ktlint` and `detekt`. -- Publishing-ready to Gradle Portal. -- Issues Template (bug report + feature request) -- Pull Request Template. +In order to make Unmeta work with your project you have to apply the Unmeta Gradle plugin to the project. Please notice +that the Unmeta plugin must be applied after the Android plugin. -## Composite Build 📦 +#### Plugin DSL -This template is using a [Gradle composite build](https://docs.gradle.org/current/userguide/composite_builds.html) to build, test and publish the plugin. This means that you don't need to run Gradle twice to test the changes on your Gradle plugin (no more `publishToMavenLocal` tricks or so). +```kotlin +// Project build.gradle.kts +plugins { + id("com.axzae.unmeta") version "1.0.0" apply false +} -The included build is inside the [plugin-build](plugin-build) folder. - -### `preMerge` task - -A `preMerge` task on the top level build is already provided in the template. This allows you to run all the `check` tasks both in the top level and in the included build. - -You can easily invoke it with: +// Module(app) build.gradle.kts +plugins { + id("com.android.application") + // ... + id("com.axzae.unmeta") +} ``` -./gradlew preMerge + +#### Legacy Plugin Application + +```kotlin +// Project build.gradle.kts +buildscript { + dependencies { + classpath("com.axzae.unmeta:com.axzae.unmeta.gradle.plugin:1.0.0") + } +} ``` -If you need to invoke a task inside the included build with: +## Configuration -``` -./gradlew -p plugin-build +```kotlin +unmeta { + isEnabled.set(true) // Default: true + verbose.set(true) // Default: false +} ``` - -### Dependency substitution - -Please note that the project relies on module name/group in order for [dependency substitution](https://docs.gradle.org/current/userguide/resolution_rules.html#sec:dependency_substitution_rules) to work properly. If you change only the plugin ID everything will work as expected. If you change module name/group, things might break and you probably have to specify a [substitution rule](https://docs.gradle.org/current/userguide/resolution_rules.html#sub:project_to_module_substitution). - - -## Publishing 🚀 - -This template is ready to let you publish to [Gradle Portal](https://plugins.gradle.org/). - -The [![Publish Plugin to Portal](https://github.com/cortinico/kotlin-gradle-plugin-template/workflows/Publish%20Plugin%20to%20Portal/badge.svg?branch=1.0.0)](https://github.com/cortinico/kotlin-gradle-plugin-template/actions?query=workflow%3A%22Publish+Plugin+to+Portal%22) Github Action will take care of the publishing whenever you **push a tag**. - -Please note that you need to configure two secrets: `GRADLE_PUBLISH_KEY` and `GRADLE_PUBLISH_SECRET` with the credetials you can get from your profile on the Gradle Portal. - -## 100% Kotlin 🅺 - -This template is designed to use Kotlin everywhere. The build files are written using [**Gradle Kotlin DSL**](https://docs.gradle.org/current/userguide/kotlin_dsl.html) as well as the [Plugin DSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block) to setup the build. - -Dependencies are centralized inside the [libs.versions.toml](gradle/libs.versions.toml). - -Moreover, a minimalistic Gradle Plugin is already provided in Kotlin to let you easily start developing your own around it. - -## Static Analysis 🔍 - -This template is using [**ktlint**](https://github.com/pinterest/ktlint) with the [ktlint-gradle](https://github.com/jlleitschuh/ktlint-gradle) plugin to format your code. To reformat all the source code as well as the buildscript you can run the `ktlintFormat` gradle task. - -This template is also using [**detekt**](https://github.com/arturbosch/detekt) to analyze the source code, with the configuration that is stored in the [detekt.yml](config/detekt/detekt.yml) file (the file has been generated with the `detektGenerateConfig` task). - -## CI ⚙️ - -This template is using [**GitHub Actions**](https://github.com/cortinico/kotlin-android-template/actions) as CI. You don't need to setup any external service and you should have a running CI once you start using this template. - -There are currently the following workflows available: -- [Validate Gradle Wrapper](.github/workflows/gradle-wrapper-validation.yml) - Will check that the gradle wrapper has a valid checksum -- [Pre Merge Checks](.github/workflows/pre-merge.yaml) - Will run the `preMerge` tasks as well as trying to run the Gradle plugin. -- [Publish to Plugin Portal](.github/workflows/publish-plugin.yaml) - Will run the `publishPlugin` task when pushing a new tag. - -## Contributing 🤝 +## Contributing Feel free to open a issue or submit a pull request for any bugs/improvements. -## License 📄 +## License -This template is licensed under the MIT License - see the [License](License) file for details. -Please note that the generated template is offering to start with a MIT license but you can change it to whatever you wish, as long as you attribute under the MIT terms that you're using the template. + Copyright (c) 2023 Axzae + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +[1]: https://github.com/Kotlin/kotlinx.coroutines/issues/2267#issuecomment-698826645 + +[debugmetadata]: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/DebugMetadata.kt +[pluginportal]: https://plugins.gradle.org/plugin/com.axzae.unmeta +[actions]: https://github.com/axzae/unmeta-gradle-plugin/actions diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 331bfc4..a9f49fc 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -1,8 +1,8 @@ plugins { java - id("com.ncorti.kotlin.gradle.template.plugin") + id("com.axzae.unmeta") } -templateExampleConfig { +unmeta { message.set("Just trying this gradle plugin...") } diff --git a/plugin-build/gradle.properties b/plugin-build/gradle.properties index 3e4ac7f..37aeb1d 100644 --- a/plugin-build/gradle.properties +++ b/plugin-build/gradle.properties @@ -1,8 +1,8 @@ -ID=com.ncorti.kotlin.gradle.template.plugin +ID=com.axzae.unmeta VERSION=1.0.0 -GROUP=com.ncorti.kotlin.gradle.template -DISPLAY_NAME=An empty Gradle Plugin from a template -DESCRIPTION=An empty Gradle plugin created from a template -WEBSITE=https://github.com/cortinico/kotlin-gradle-plugin-template -VCS_URL=https://github.com/cortinico/kotlin-gradle-plugin-template -IMPLEMENTATION_CLASS=com.ncorti.kotlin.gradle.template.plugin.TemplatePlugin +GROUP=com.axzae +DISPLAY_NAME=Unmeta Kotlin Gradle Plugin for Android +DESCRIPTION=Remove @DebugMetadata annotation from your Kotlin classes +WEBSITE=https://github.com/axzae/unmeta-gradle-plugin +VCS_URL=https://github.com/axzae/unmeta-gradle-plugin +IMPLEMENTATION_CLASS=com.axzae.unmeta.UnmetaPlugin diff --git a/plugin-build/plugin/build.gradle.kts b/plugin-build/plugin/build.gradle.kts index 0143d7a..43600bd 100644 --- a/plugin-build/plugin/build.gradle.kts +++ b/plugin-build/plugin/build.gradle.kts @@ -32,7 +32,7 @@ gradlePlugin { version = property("VERSION").toString() description = property("DESCRIPTION").toString() displayName = property("DISPLAY_NAME").toString() - tags.set(listOf("plugin", "gradle", "sample", "template")) + tags.set(listOf("kotlin", "metadata")) } } } diff --git a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExtension.kt b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaExtension.kt similarity index 80% rename from plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExtension.kt rename to plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaExtension.kt index c45e936..f8fb781 100644 --- a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExtension.kt +++ b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaExtension.kt @@ -1,4 +1,4 @@ -package com.ncorti.kotlin.gradle.template.plugin +package com.axzae.unmeta import org.gradle.api.Project import org.gradle.api.file.RegularFileProperty @@ -8,7 +8,7 @@ import javax.inject.Inject const val DEFAULT_OUTPUT_FILE = "template-example.txt" @Suppress("UnnecessaryAbstractClass") -abstract class TemplateExtension @Inject constructor(project: Project) { +abstract class UnmetaExtension @Inject constructor(project: Project) { private val objects = project.objects @@ -21,6 +21,6 @@ abstract class TemplateExtension @Inject constructor(project: Project) { // Example of a property with a default set with .convention val outputFile: RegularFileProperty = objects.fileProperty().convention( - project.layout.buildDirectory.file(DEFAULT_OUTPUT_FILE) + project.layout.buildDirectory.file(DEFAULT_OUTPUT_FILE), ) } diff --git a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePlugin.kt b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaPlugin.kt similarity index 58% rename from plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePlugin.kt rename to plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaPlugin.kt index 3aa15e1..992f159 100644 --- a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePlugin.kt +++ b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaPlugin.kt @@ -1,18 +1,18 @@ -package com.ncorti.kotlin.gradle.template.plugin +package com.axzae.unmeta import org.gradle.api.Plugin import org.gradle.api.Project -const val EXTENSION_NAME = "templateExampleConfig" -const val TASK_NAME = "templateExample" +const val EXTENSION_NAME = "unmeta" +const val TASK_NAME = "unmetaTask" -abstract class TemplatePlugin : Plugin { +abstract class UnmetaPlugin : Plugin { override fun apply(project: Project) { // Add the 'template' extension object - val extension = project.extensions.create(EXTENSION_NAME, TemplateExtension::class.java, project) + val extension = project.extensions.create(EXTENSION_NAME, UnmetaExtension::class.java, project) // Add a task that uses configuration from the extension object - project.tasks.register(TASK_NAME, TemplateExampleTask::class.java) { + project.tasks.register(TASK_NAME, UnmetaTask::class.java) { it.tag.set(extension.tag) it.message.set(extension.message) it.outputFile.set(extension.outputFile) diff --git a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExampleTask.kt b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaTask.kt similarity index 80% rename from plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExampleTask.kt rename to plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaTask.kt index 26d3f09..f0b01ca 100644 --- a/plugin-build/plugin/src/main/java/com/ncorti/kotlin/gradle/template/plugin/TemplateExampleTask.kt +++ b/plugin-build/plugin/src/main/java/com/axzae/unmeta/UnmetaTask.kt @@ -1,7 +1,8 @@ -package com.ncorti.kotlin.gradle.template.plugin +package com.axzae.unmeta import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty +import org.gradle.api.plugins.BasePlugin import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional @@ -9,13 +10,11 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option -abstract class TemplateExampleTask : DefaultTask() { +abstract class UnmetaTask : DefaultTask() { init { - description = "Just a sample template task" - - // Don't forget to set the group here. - // group = BasePlugin.BUILD_GROUP + description = "Drop Kotlin @DebugMetadata from java classes" + group = BasePlugin.BUILD_GROUP } @get:Input @@ -31,7 +30,7 @@ abstract class TemplateExampleTask : DefaultTask() { abstract val outputFile: RegularFileProperty @TaskAction - fun sampleAction() { + fun unmetaAction() { val prettyTag = tag.orNull?.let { "[$it]" } ?: "" logger.lifecycle("$prettyTag message is: ${message.orNull}") diff --git a/plugin-build/plugin/src/test/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePluginTest.kt b/plugin-build/plugin/src/test/java/com/axzae/unmeta/UnmetaPluginTest.kt similarity index 54% rename from plugin-build/plugin/src/test/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePluginTest.kt rename to plugin-build/plugin/src/test/java/com/axzae/unmeta/UnmetaPluginTest.kt index a6c4f99..9370f28 100644 --- a/plugin-build/plugin/src/test/java/com/ncorti/kotlin/gradle/template/plugin/TemplatePluginTest.kt +++ b/plugin-build/plugin/src/test/java/com/axzae/unmeta/UnmetaPluginTest.kt @@ -1,4 +1,4 @@ -package com.ncorti.kotlin.gradle.template.plugin +package com.axzae.unmeta import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert.assertEquals @@ -6,36 +6,36 @@ import org.junit.Assert.assertNotNull import org.junit.Test import java.io.File -class TemplatePluginTest { +class UnmetaPluginTest { @Test fun `plugin is applied correctly to the project`() { val project = ProjectBuilder.builder().build() - project.pluginManager.apply("com.ncorti.kotlin.gradle.template.plugin") + project.pluginManager.apply("com.axzae.unmeta") - assert(project.tasks.getByName("templateExample") is TemplateExampleTask) + assert(project.tasks.getByName("unmetaTask") is UnmetaTask) } @Test - fun `extension templateExampleConfig is created correctly`() { + fun `extension unmeta is created correctly`() { val project = ProjectBuilder.builder().build() - project.pluginManager.apply("com.ncorti.kotlin.gradle.template.plugin") + project.pluginManager.apply("com.axzae.unmeta") - assertNotNull(project.extensions.getByName("templateExampleConfig")) + assertNotNull(project.extensions.getByName("unmeta")) } @Test fun `parameters are passed correctly from extension to task`() { val project = ProjectBuilder.builder().build() - project.pluginManager.apply("com.ncorti.kotlin.gradle.template.plugin") + project.pluginManager.apply("com.axzae.unmeta") val aFile = File(project.projectDir, ".tmp") - (project.extensions.getByName("templateExampleConfig") as TemplateExtension).apply { + (project.extensions.getByName("unmeta") as UnmetaExtension).apply { tag.set("a-sample-tag") message.set("just-a-message") outputFile.set(aFile) } - val task = project.tasks.getByName("templateExample") as TemplateExampleTask + val task = project.tasks.getByName("unmetaTask") as UnmetaTask assertEquals("a-sample-tag", task.tag.get()) assertEquals("just-a-message", task.message.get()) diff --git a/plugin-build/settings.gradle.kts b/plugin-build/settings.gradle.kts index e306329..b145c2d 100644 --- a/plugin-build/settings.gradle.kts +++ b/plugin-build/settings.gradle.kts @@ -31,6 +31,6 @@ gradleEnterprise { } } -rootProject.name = ("com.ncorti.kotlin.gradle.template") +rootProject.name = ("com.axzae.unmeta") include(":plugin") diff --git a/settings.gradle.kts b/settings.gradle.kts index 92b3535..0b764f1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,7 +25,7 @@ gradleEnterprise { } } -rootProject.name = "kotlin-gradle-plugin-template" +rootProject.name = "unmeta-gradle-plugin" include(":example") includeBuild("plugin-build")