diff --git a/.editorconfig b/.editorconfig index 6612cab..0e5e28c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,4 @@ +# Source: https://gist.github.com/osipxd/9a786496634a1ef0ea622c9805601490 root = true [*] @@ -10,60 +11,89 @@ trim_trailing_whitespace = true max_line_length = 120 ij_visual_guides = 100 -## General +# General ij_continuation_indent_size = 8 ij_smart_tabs = false ij_wrap_on_typing = false ij_any_keep_indents_on_empty_lines = false -## Formatter Control +# Formatter ij_formatter_tags_enabled = true ij_formatter_on_tag = @formatter:on ij_formatter_off_tag = @formatter:off -[{*.kt, *.kts}] -ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL -ij_continuation_indent_size = 4 # To match ktlint settings -ij_kotlin_keep_indents_on_empty_lines = false +[{*.kt,*.kts}] +# Tabs and Indents +# continuation_indent_size = 4 to match ktlint settings +ij_kotlin_continuation_indent_size = 4 +ij_kotlin_keep_indents_on_empty_lines = unset + +# Spaces +## Before parentheses +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_when_parentheses = true +## Around operators +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_range = false +## Other +ij_kotlin_space_before_comma = false +ij_kotlin_space_after_comma = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_space_before_lambda_arrow = true -## Wrapping and Braces -# Keep when reformatting +# Wrapping and Braces +## Keep when reformatting ij_kotlin_keep_line_breaks = true ij_kotlin_keep_first_column_comment = true -# Extends/implements list +## Extends/implements list ij_kotlin_extends_list_wrap = normal ij_kotlin_align_multiline_extends_list = false ij_kotlin_continuation_indent_in_supertype_lists = false -# Function declaration parameters +## Function declaration parameters ij_kotlin_method_parameters_wrap = on_every_item ij_kotlin_align_multiline_parameters = true ij_kotlin_method_parameters_new_line_after_left_paren = true ij_kotlin_method_parameters_right_paren_on_new_line = true ij_kotlin_continuation_indent_in_parameter_lists = false -# Function call arguments +## Function call arguments ij_kotlin_call_parameters_wrap = on_every_item ij_kotlin_align_multiline_parameters_in_calls = false ij_kotlin_call_parameters_new_line_after_left_paren = true ij_kotlin_call_parameters_right_paren_on_new_line = true ij_kotlin_continuation_indent_in_argument_lists = false -# Function parentheses +## Function parentheses ij_kotlin_align_multiline_method_parentheses = false -# Chained function calls +## Chained function calls ij_kotlin_method_call_chain_wrap = normal ij_kotlin_wrap_first_method_in_call_chain = false ij_kotlin_continuation_indent_for_chained_calls = false -# 'if()' statement +## 'if()' statement ij_kotlin_else_on_new_line = false ij_kotlin_if_rparen_on_new_line = true ij_kotlin_continuation_indent_in_if_conditions = false -# 'do ... while()' statement +## 'do ... while()' statement ij_kotlin_while_on_new_line = false -# 'try' statement +## 'try' statement ij_kotlin_catch_on_new_line = false ij_kotlin_finally_on_new_line = false -# Binary expressions +## Binary expressions ij_kotlin_align_multiline_binary_operation = false -# Wraps +## Wraps ij_kotlin_assignment_wrap = normal ij_kotlin_enum_constants_wrap = off ij_kotlin_class_annotation_wrap = split_into_lines @@ -71,75 +101,63 @@ ij_kotlin_method_annotation_wrap = split_into_lines ij_kotlin_field_annotation_wrap = split_into_lines ij_kotlin_parameter_annotation_wrap = off ij_kotlin_variable_annotation_wrap = off -# 'when' statements +## 'when' statements ij_kotlin_align_in_columns_case_branch = false -# Braces placement +ij_kotlin_line_break_after_multiline_when_entry = true +## Braces placement ij_kotlin_lbrace_on_next_line = false -# Expression body functions +## Expression body functions ij_kotlin_wrap_expression_body_functions = 1 ij_kotlin_continuation_indent_for_expression_bodies = false -# Elvis expressions +## Elvis expressions ij_kotlin_wrap_elvis_expressions = 1 ij_kotlin_continuation_indent_in_elvis = false -## Spaces -# Before Parentheses -ij_kotlin_space_before_if_parentheses = true -ij_kotlin_space_before_for_parentheses = true -ij_kotlin_space_before_while_parentheses = true -ij_kotlin_space_before_catch_parentheses = true -ij_kotlin_space_before_when_parentheses = true -# Around Operators -ij_kotlin_spaces_around_assignment_operators = true -ij_kotlin_spaces_around_logical_operators = true -ij_kotlin_spaces_around_equality_operators = true -ij_kotlin_spaces_around_relational_operators = true -ij_kotlin_spaces_around_additive_operators = true -ij_kotlin_spaces_around_multiplicative_operators = true -ij_kotlin_spaces_around_unary_operator = false -ij_kotlin_spaces_around_range = false -# Other -ij_kotlin_space_before_comma = false -ij_kotlin_space_after_comma = true -ij_kotlin_space_before_type_colon = false -ij_kotlin_space_after_type_colon = true -ij_kotlin_space_after_extend_colon = true -ij_kotlin_space_before_extend_colon = true -ij_kotlin_insert_whitespaces_in_simple_one_line_method = true -ij_kotlin_spaces_around_function_type_arrow = true -ij_kotlin_spaces_around_when_arrow = true -ij_kotlin_space_before_lambda_arrow = true - -## Blank Lines -# Keep Maximum Blank Lines +# Blank Lines +## Keep maximum blank lines ij_kotlin_keep_blank_lines_in_declarations = 1 ij_kotlin_keep_blank_lines_in_code = 1 ij_kotlin_keep_blank_lines_before_right_brace = 0 -# Minimum Blank Lines +## Minimum blank lines ij_kotlin_blank_lines_after_class_header = 0 ij_kotlin_blank_lines_around_block_when_branches = 1 ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 -## Imports +# Imports ij_kotlin_name_count_to_use_star_import = 5 ij_kotlin_name_count_to_use_star_import_for_members = 3 ij_kotlin_import_nested_classes = false -ij_kotlin_packages_to_use_import_on_demand = java.util.*, kotlinx.android.synthetic.**, io.ktor.** -ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^ +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ -## Other +# Other +## Trailing comma ij_kotlin_allow_trailing_comma = true -ij_kotlin_allow_trailing_comma_on_call_site = true +ij_kotlin_allow_trailing_comma_on_call_site = false -## Code generation +# Code generation +## Comment code ij_kotlin_line_comment_at_first_column = true ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_add_space_on_reformat = false ij_kotlin_block_comment_at_first_column = true +ij_kotlin_block_comment_add_space = false -[**/res/**.xml] -ij_continuation_indent_size = 4 +# Load/Save +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL -## Other +[*.kts] +# Always use wildcard imports in scripts +ij_kotlin_name_count_to_use_star_import = 2 + +# EditorConfig can not set some of XML code style options. +# Remember to set default Android XML code style: Editor > Code Style > XML > Set from... -> Android +[{**/res/**.xml,**/AndroidManifest.xml}] +# Tabs and Indents +ij_xml_continuation_indent_size = 4 +ij_xml_keep_indents_on_empty_lines = unset + +# Other ij_xml_keep_line_breaks = false ij_xml_keep_line_breaks_in_text = true ij_xml_keep_blank_lines = 2 @@ -148,31 +166,60 @@ ij_xml_text_wrap = normal ij_xml_align_text = false ij_xml_align_attributes = false ij_xml_keep_whitespaces = false -# Spaces +## Spaces ij_xml_space_around_equals_in_attribute = false ij_xml_space_after_tag_name = false ij_xml_space_inside_empty_tag = true -# CDATA +## CDATA ij_xml_keep_whitespaces_around_cdata = preserve ij_xml_keep_whitespaces_inside_cdata = false -## Code Generation +# Code Generation ij_xml_line_comment_at_first_column = true ij_xml_block_comment_at_first_column = true +ij_xml_block_comment_add_space = false -## Android +# Android ij_xml_use_custom_settings = true [*.md] trim_trailing_whitespace = false -[{*.yaml, *.yml}] +# Wrapping and Braces +ij_markdown_wrap_text_if_long = false +ij_markdown_wrap_text_inside_blockquotes = false +## When reformatting +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_format_tables = true + +# Tabs and Indents +ij_markdown_keep_indents_on_empty_lines = unset + +# Blank Lines +## Keep maximum blank lines +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_between_paragraphs = 1 +## Minimum blank lines +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_between_paragraphs = 1 + +# Spaces +## Force one space +ij_markdown_force_one_space_between_words = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_after_blockquote_symbol = true + +[{*.yaml,*.yml}] indent_size = 2 -ij_yaml_spaces_within_brackets = false -ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_indents_on_empty_lines = unset ij_yaml_keep_line_breaks = true +ij_yaml_spaces_within_brackets = false -[{*.bash, *.sh, *.zsh}] +[{*.bash,*.sh,*.zsh}] indent_size = 2 tab_width = 2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 64a63fd..5ca3b8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,19 +13,19 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 - name: Run Check - uses: eskatos/gradle-command-action@v2 - with: - arguments: detektMainAll check - cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }} + run: ./gradlew detektMainAll check publish: name: Publish @@ -35,19 +35,19 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 - name: Run Publish - uses: eskatos/gradle-command-action@v2 - with: - arguments: publishAllPublicationsToGithubPackagesRepository - cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }} + run: ./gradlew publishAllPublicationsToGithubPackagesRepository env: ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }} ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }} @@ -63,22 +63,21 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 - name: Run Publish - uses: eskatos/gradle-command-action@v2 - with: - arguments: publishToMavenLocal - cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }} + run: ./gradlew publishToMavenLocal - name: Run Build - uses: eskatos/gradle-command-action@v2 - with: - arguments: build - build-root-directory: samples/${{ matrix.sample }} + run: | + cd samples/${{ matrix.sample }} + ./gradlew build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8c66fbf --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Create Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: set up JDK + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Publish to Maven Central + run: ./gradlew publishToMavenCentral publishPlugin + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }} + GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} + GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} + + - name: Extract release notes + uses: ffurrer2/extract-release-notes@v2 + with: + release_notes_file: RELEASE_NOTES.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + body_path: RELEASE_NOTES.md diff --git a/.idea/detekt.xml b/.idea/detekt.xml index 731d382..92bfd7f 100644 --- a/.idea/detekt.xml +++ b/.idea/detekt.xml @@ -1,8 +1,13 @@ - - true - true - $PROJECT_DIR$/config/detekt/detekt.yml + + + - \ No newline at end of file + diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml index 524f428..800dcd0 100644 --- a/.idea/externalDependencies.xml +++ b/.idea/externalDependencies.xml @@ -1,7 +1,7 @@ - + diff --git a/CHANGELOG.md b/CHANGELOG.md index 5998982..c68e432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,123 @@ ## [Unreleased] +- *No changes* + +## [0.19] (2024-07-26) + +> [!NOTE] +> This release removes many implicit features that couldn't be configured from outside. +> It is also a part of a process of removing the features that could be easily implemented via [pre-compiled script plugins](https://docs.gradle.org/current/userguide/implementing_gradle_plugins_precompiled.html) (for example, SDK versions and tests configuration). +> It is recommended to migrate these configurations to pre-compiled script plugins. + +### Stable `addSharedSourceSetRoot` extension + +Experimental extension `addSharedSourceSetRoot(...)` has been replaced with the new stable version: + +```kotlin +android { + // The old way (Deprecated) + addSharedSourceSetRoot("debug", "qa") + + // The new way + sourceSets.addSharedSourceSetRoot("debug", "qa") +} +``` + +### Introduce `SigningConfig.fromProperties` (Experimental) + +It is common practice to store keystore credentials in `.properties` file. +This extension lets you apply configurations from a property file. + +```kotlin +android { + signingConfigs.getByName("debug") { + fromProperties(file("cert/debug.properties")) + } +} +``` + +### :warning: BREAKING CHANGES + +- **common:** Deprecate `redmadrobot.jvmTarget` with deprecation level `Error`. + Use [JVM Toolchains](https://kotl.in/gradle/jvm/toolchain) instead to specify JVM target. + Kotlin, Android Gradle Plugin, detekt and many other tools have support for this mechanism, + In most cases, adding this into your `build.gradle.kts` should be enough: + ```kotlin + kotlin { + jvmToolchain(17) + } + ``` + You can also configure [automatic toolchains downloading](https://docs.gradle.org/current/userguide/toolchains.html#sub:download_repositories). +- **android:** Don't set default `minSdk` (it was `23`) and `targetSdk` (it was `33`). + It was a poor decision to set defaults for these fields as could implicitly bump an SDK version in a project. + If you want to use `redmadrobot.android` to align SDK versions among all modules, you should set these properties explicitly: + ```kotlin + redmadrobot { + android { + minSdk = 23 + targetSdk = 34 + } + } + ``` +- **common:** Disable [automatic repositories adding](https://github.com/RedMadRobot/gradle-infrastructure#automatically-added-repositories) by default. + If you rely on this feature, consider declaring required repositories explicitly, or enable it in `gradle.properties`: + ```properties + redmadrobot.add.repositories=true + ``` +- **android:** Don't apply [`org.gradle.android.cache-fix` plugin](https://github.com/gradle/android-cache-fix-gradle-plugin/) automatically. + This change allows removing android-cache-fix-gradle-plugin from the project dependencies. + See [the plugin documentation](https://github.com/gradle/android-cache-fix-gradle-plugin/?tab=readme-ov-file#applying-the-plugin) to learn how to apply this plugin to your project. +- **android:** Don't apply `proguard-android-optimize.txt` rules by default. + If you need these rules, apply it manually: + ```kotlin + android { + defaultConfig { + proguardFile(getDefaultProguardFile("proguard-android-optimize.txt")) + } + } + ``` +- **android:** Do not add `LOCK_ORIENTATION` and `CRASH_REPORTS_ENABLED` variables to `BuildConfig` implicitly +- **kotlin:** Don't set `allWarningsAsErrors` flag implicitly. + It was impossible to disable this feature. + To keep going with the old behavior, add the following code to your build script: + ```kotlin + val warningsAsErrors = findProperty("warningsAsErrors") == "true" || isRunningOnCi + tasks.withType().configureEach { + compilerOptions.allWarningsAsErrors = warningsAsErrors + } + ``` + +### Other Changes + +- **android:** Use `ANDROID_BUILD_TOOLS_VERSION` env variable for `buildToolsVersion` if the option is not configured (#132) +- **android:** Make an extension `Project.collectProguardFiles` public +- **android:** Add the option `redmadrobot.android.ndkVersion` to specify NDK version for all android modules +- **android:** Remove the workaround for Explicit API enabling as the issue has been [fixed](https://youtrack.jetbrains.com/issue/KT-37652) in Kotlin 1.9 +- **android:** Remove disabling of build features `aidl`, `renderScript` and `buildConfig` as they are already disabled by default in new versions of AGP +- **kotlin:** Deprecate accessor `kotlinCompile`. + It is recommended to use `kotlin.compilerOptions { ... }` to configure compilation instead. +- Update Gradle to `8.9` + +### Dependencies + +| Dependency | Minimal version | +|-----------------------|:-------------------:| +| Gradle | `7.4` → `8.0` | +| Kotlin Gradle Plugin | `1.7.10` → `1.9.0` | +| Android Gradle Plugin | `7.4.0` → `8.4.0` | + +infrastructure-kotlin: +- [Kotlin](https://kotlinlang.org/docs/whatsnew20.html) `1.8.10` → `2.0.0` + +infrastructure-android: +- [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) `7.4.2` → `8.5.1` +- Remove `android-cache-fix-gradle-plugin` from dependencies +- Remove `com.android.tools:common` from dependencies + +infrastructure-detekt: +- [Detekt](https://github.com/detekt/detekt/releases/tag/v1.23.6) `1.22.0` → `1.23.6` +- [JGit](https://projects.eclipse.org/projects/technology.jgit/releases/6.10.0) `6.4.0` → `6.10.0` + ## [0.18.1] (2023-04-18) - Fix compatibility with Gradle lower than 8.0 (#127) @@ -603,6 +721,7 @@ Pull request: #35 - Added CHANGELOG.md :) [unreleased]: https://github.com/RedMadRobot/gradle-infrastructure/compare/main..develop +[0.19]: https://github.com/RedMadRobot/gradle-infrastructure/compare/v0.18.1..v0.19 [0.18.1]: https://github.com/RedMadRobot/gradle-infrastructure/compare/v0.18..v0.18.1 [0.18]: https://github.com/RedMadRobot/gradle-infrastructure/compare/v0.17..v0.18 [0.17]: https://github.com/RedMadRobot/gradle-infrastructure/compare/v0.16.2..v0.17 diff --git a/README.md b/README.md index 3d8eb4d..4c84905 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Small plugins to reduce boilerplate in Gradle build scripts. -> :warning: It is designed to use with Gradle Kotlin DSL and can't be used from Groovy DSL. +> [!IMPORTANT] +> These plugins are designed to be used with Gradle Kotlin DSL only. --- @@ -24,7 +25,7 @@ Small plugins to reduce boilerplate in Gradle build scripts. - [Configuration](#configuration) - [Align version of all Kotlin libraries](#align-version-of-all-kotlin-libraries) - [Warnings as errors](#warnings-as-errors) - - [Share sources between build types](#share-sources-between-build-types) + - [Share sources between build variants](#share-sources-between-build-variants) - [Enable Detekt checks only on changed files](#enable-detekt-checks-only-on-changed-files) - [Configure JUnit test execution options](#configure-junit-test-execution-options) - [Automatically added repositories](#automatically-added-repositories) @@ -56,11 +57,11 @@ Then you can apply any of plugins where you need: ```kotlin plugins { - id("com.redmadrobot.kotlin-library") version "0.18.1" - id("com.redmadrobot.publish") version "0.18.1" - id("com.redmadrobot.detekt") version "0.18.1" - id("com.redmadrobot.application") version "0.18.1" - id("com.redmadrobot.android-library") version "0.18.1" + id("com.redmadrobot.kotlin-library") version "0.19" + id("com.redmadrobot.publish") version "0.19" + id("com.redmadrobot.detekt") version "0.19" + id("com.redmadrobot.application") version "0.19" + id("com.redmadrobot.android-library") version "0.19" } ``` @@ -79,7 +80,7 @@ plugins { redmadrobot { android { - minSdk.set(28) + minSdk = 28 } } ``` @@ -103,20 +104,42 @@ android { | gradle-infrastructure | Minimal Gradle version | Minimal KGP version | Minimal AGP version | |----------------------:|:----------------------:|:-------------------:|:-------------------:| +| **0.19** | 8.0 | 1.9.0 | 8.4.0 | | **0.18** | 7.5 | 1.7.10 | 7.4.0 | | **0.17** | 7.2 | 1.7.10 | 7.1.0 | ## Plugins -[![](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggQlRcbnN1YmdyYXBoIGluZnJhc3RydWN0dXJlLWFuZHJvaWRcbiAgICBhbmRyb2lkLWNvbmZpZ1tjb20ucmVkbWFkcm9ib3QuYW5kcm9pZC1jb25maWddXG4gICAgY29tLnJlZG1hZHJvYm90LmFwcGxpY2F0aW9uIC0tPiBhbmRyb2lkLWNvbmZpZ1xuICAgIGNvbS5yZWRtYWRyb2JvdC5hbmRyb2lkLWxpYnJhcnkgLS0-IGFuZHJvaWQtY29uZmlnXG5lbmRcblxuc3ViZ3JhcGggaW5mcmFzdHJ1Y3R1cmUtZGV0ZWt0XG4gICAgY29tLnJlZG1hZHJvYm90LmRldGVrdFxuZW5kXG5cbnN1YmdyYXBoIGluZnJhc3RydWN0dXJlLWtvdGxpblxuICAgIGtvdGxpbi1jb25maWdbY29tLnJlZG1hZHJvYm90LmtvdGxpbi1jb25maWddXG4gICAgY29tLnJlZG1hZHJvYm90LmtvdGxpbi1saWJyYXJ5IC0tPiBrb3RsaW4tY29uZmlnXG5lbmRcblxuc3ViZ3JhcGggaW5mcmFzdHJ1Y3R1cmUtcHVibGlzaFxuICAgIHB1Ymxpc2gtY29uZmlnW2NvbS5yZWRtYWRyb2JvdC5wdWJsaXNoLWNvbmZpZ11cbiAgICBjb20ucmVkbWFkcm9ib3QucHVibGlzaCAtLT4gcHVibGlzaC1jb25maWdcbmVuZFxuXG5hbmRyb2lkLWNvbmZpZyAtLT4ga290bGluLWNvbmZpZyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6dHJ1ZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOnRydWV9)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiZ3JhcGggQlRcbnN1YmdyYXBoIGluZnJhc3RydWN0dXJlLWFuZHJvaWRcbiAgICBhbmRyb2lkLWNvbmZpZ1tjb20ucmVkbWFkcm9ib3QuYW5kcm9pZC1jb25maWddXG4gICAgY29tLnJlZG1hZHJvYm90LmFwcGxpY2F0aW9uIC0tPiBhbmRyb2lkLWNvbmZpZ1xuICAgIGNvbS5yZWRtYWRyb2JvdC5hbmRyb2lkLWxpYnJhcnkgLS0-IGFuZHJvaWQtY29uZmlnXG5lbmRcblxuc3ViZ3JhcGggaW5mcmFzdHJ1Y3R1cmUtZGV0ZWt0XG4gICAgY29tLnJlZG1hZHJvYm90LmRldGVrdFxuZW5kXG5cbnN1YmdyYXBoIGluZnJhc3RydWN0dXJlLWtvdGxpblxuICAgIGtvdGxpbi1jb25maWdbY29tLnJlZG1hZHJvYm90LmtvdGxpbi1jb25maWddXG4gICAgY29tLnJlZG1hZHJvYm90LmtvdGxpbi1saWJyYXJ5IC0tPiBrb3RsaW4tY29uZmlnXG5lbmRcblxuc3ViZ3JhcGggaW5mcmFzdHJ1Y3R1cmUtcHVibGlzaFxuICAgIHB1Ymxpc2gtY29uZmlnW2NvbS5yZWRtYWRyb2JvdC5wdWJsaXNoLWNvbmZpZ11cbiAgICBjb20ucmVkbWFkcm9ib3QucHVibGlzaCAtLT4gcHVibGlzaC1jb25maWdcbmVuZFxuXG5hbmRyb2lkLWNvbmZpZyAtLT4ga290bGluLWNvbmZpZyIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOnRydWUsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ) +```mermaid +graph BT +subgraph infrastructure-android + android-config[com.redmadrobot.android-config] + com.redmadrobot.application --> android-config + com.redmadrobot.android-library --> android-config +end + +subgraph infrastructure-detekt + com.redmadrobot.detekt +end + +subgraph infrastructure-kotlin + kotlin-config[com.redmadrobot.kotlin-config] + com.redmadrobot.kotlin-library --> kotlin-config +end + +subgraph infrastructure-publish + publish-config[com.redmadrobot.publish-config] + com.redmadrobot.publish --> publish-config +end + +android-config --> kotlin-config +``` ### kotlin-library Common configurations for pure Kotlin libraries. - Applies plugin `kotlin` -- Specifies `jvmTarget` 11 -- Adds repository `mavenCentral` (see [Automatically added repositories](#automatically-added-repositories)) - Enables [explicit API mode][explicit-api] ### publish @@ -147,8 +170,8 @@ You can configure publication via extension `redmadrobot.publishing`: ```kotlin redmadrobot { publishing { - signArtifacts.set(true) // Enables artifacts signing, required for publication to OSSRH - useGpgAgent.set(true) // By default use gpg-agent for artifacts signing + signArtifacts = true // Enables artifacts signing, required for publication to OSSRH + useGpgAgent = true // By default use gpg-agent for artifacts signing } } ``` @@ -205,7 +228,6 @@ publishing.publications.getByName(PUBLICATION_NAME) { ### detekt -- Adds repository `mavenCentral` (see [Automatically added repositories](#automatically-added-repositories)) - Applies `detekt` plugin with `detekt-formatting` - Configures additional tasks: - `detektAll` - Runs Detekt over the whole codebase @@ -223,25 +245,24 @@ publishing.publications.getByName(PUBLICATION_NAME) { Common configurations for Android libraries and application. -Both: -- Specifies `jvmTarget` and `compatibility` 11 +[Both][BaseAndroidPlugin]: - Specifies default compile, min and target SDK -- Disables `aidl`, `renderScript` and `shaders` [build-features] -- Adds repositories `mavenCentral` and `google` (see [Automatically added repositories](#automatically-added-repositories)) +- Disables `shaders` [build-features] by default - Applies [android-cache-fix-gradle-plugin](https://github.com/gradle/android-cache-fix-gradle-plugin) +- Configures Android Lint with [defaults][lint-options] +- [Filters tests][testTaskFilter] to be run on `test` task according to the config. + By default, keeps only tests for build type `release`. -Library: +[Library][AndroidLibraryPlugin]: - Applies plugin `com.android.library` - Adds all proguard files from `proguard` folder as `consumerProguardFiles` -- Disables `buildConfig`, `androidResources` and `resValues` [build-features] +- Disables `androidResources` and `resValues` [build-features] by default - Enables [explicit API mode][explicit-api] -Application: +[Application][AndroidApplicationPlugin]: - Applies plugin `com.android.application` - Adds all proguard files from `proguard` folder - Configures `debug`, `qa` and `release` build types -- Adds `LOCK_ORIENTATION` and `CRASH_REPORTS_ENABLED` BuildConfig variables which `false` only for `debug` build type -- Configures Android Lint [default options][lint-options] #### QA build type name configuration @@ -293,15 +314,71 @@ See [compatibility table](#compatibility) to check what versions are compatible ### Configuration -You can configure the plugins with an extension named `redmadrobot`. -Look for available properties with description in [RedmadrobotExtension]. +You can configure the plugins via the `redmadrobot` extension. +Here are listed all available options, with their default values: -The extension should be configured in root project. ```kotlin -// root project build.gradle.kts - redmadrobot { - configsDir.set(file("path/to/configs/")) + /* Common options */ + // Directory with configs for static analyzers and other tools. + configsDir = file("config/") + + // Directory with reports of static analyzers and other tools. + reportsDir = file("build/reports/") + + /* `kotlin-config` options */ + test { + // Specifies that JUnit Platform (JUnit 5) should be used to execute tests. + useJunitPlatform() + + // Specifies that JUnit 4 should be used to execute tests. + useJunit() + } + + /* `android-config` options */ + android { + // minSdk to be used in all android modules. + minSdk = 23 + + // targetSdk to be used in all android modules. + targetSdk = 34 + + // compileSdk to be used in all android modules + compileSdk = "34" + + // Build Tools version to be used in all android modules. + buildToolsVersion = System.getenv("ANDROID_BUILD_TOOLS_VERSION") + + // NDK version to be used in all android modules. + ndkVersion = System.getenv("ANDROID_NDK_VERSION") + + // Filter for test tasks that should be run on ':test'. + testTasksFilter = { taskProvider -> taskProvider.name.endsWith("ReleaseUnitTest") } + + // Overrides of test configuration for android projects + test { /* ... */ } + } + + /* `detekt` options */ + detekt { + // Enable Detekt checks only for modified files + // (Disabled by default) + checkOnlyDiffWithBranch(branch = "main") { + fileExtensions = setOf(".kt", ".kts") + } + } + + /* `publish-config` options */ + publishing { + // Enables artifacts signing before publication. + signArtifacts = false + + // Use gpg-agent to sign artifacts. Has effect only if signArtifacts is `true`. + useGpgAgent = true + + // Configures POM file for this project and its subprojects. + pom { /* ... */ } + } } ``` @@ -335,25 +412,19 @@ dependencies { } ``` -### Warnings as errors +### Share sources between build variants -By default, infrastructure plugins enable Kotlin compiler's option `allWarningsAsErrors` (`-Werror`) on CI. -You can change it by defining the `warningsAsErrors` project property. +You can share sources between two build variants. +For example, you need to use debug panel in both "debug" and "QA" builds, and don't want to duplicate code for each of these build types. +You can do it in one line with [addSharedSourceSetRoot] extension-function: -[Read more about Gradle project properties][project-properties] - -### Share sources between build types - -You can share sources between two build types. -For example, you need to use debug panel in both debug and QA builds, and don't want to write similar duplicating code for each of these build types. -You can do it with one line with [addSharedSourceSetRoot] extension-function: ```kotlin android { // We need to share sources between debug and QA builds - addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) + sourceSet.addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) - // We can specify name for the source set root if need - addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA, name = "debugPanel") + // We can specify a name for the source set root if needed + sourceSet.addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA, name = "debugPanel") } ``` @@ -423,16 +494,20 @@ redmadrobot { ### Automatically added repositories -Infrastructure plugins automatically add repositories required to make project work: +> [!WARNING] +> This feature is deprecated and is disabled by default since v0.19 +> Currently you can enable this behavior, though this option may be deleted at some point. + +Infrastructure plugins can automatically add required repositories: - **kotlin** plugin adds `mavenCentral` repo - **detekt** plugin adds `mavenCentral` repo - **android** plugins add `mavenCentral` and `google` repos -In the case you don't want these repositories to be added automatically, you can disable this behavior via flag in `gradle.properties`: +This feature should be enabled by flag in `gradle.properties`: ```properties -redmadrobot.add.repositories=false +redmadrobot.add.repositories=true ``` ## Samples @@ -496,7 +571,7 @@ Execution failed for task ':app:stripDebugDebugSymbols'. It is because NDK version on CI differs from a requested version. You can change requested version by setting `android.ndkVersion`. -Plugins `com.redmadrobot.android-library` and `com.redmadrobot.application` by default apply NDK version from env variable `ANDROID_NDK_VERSION` if it set. +Plugins `com.redmadrobot.android-library` and `com.redmadrobot.application` by default apply NDK version from env variable `ANDROID_NDK_VERSION` if it is set. ### `Could not resolve` or `Could not find` dependencies @@ -536,11 +611,14 @@ For major changes, please open an issue first to discuss what you would like to [MIT][license] [samples]: samples/ -[RedmadrobotExtension]: infrastructure/src/main/kotlin/extension/RedmadrobotExtension.kt [MavenPom]: infrastructure/src/main/kotlin/dsl/MavenPom.kt [predicates]: infrastructure/src/main/kotlin/dsl/PublishingPredicates.kt [addSharedSourceSetRoot]: infrastructure-android/src/main/kotlin/dsl/SourceSets.kt -[lint-options]: https://github.com/RedMadRobot/gradle-infrastructure/blob/2e96c04cbb9d15ca508d1d4b4a8b1e2da4bab6af/infrastructure/src/main/kotlin/AndroidApplicationPlugin.kt#L63-L72 +[lint-options]: infrastructure-android/src/main/kotlin/android/BaseAndroidPlugin.kt#L76-L80 +[testTaskFilter]: infrastructure-android/src/main/kotlin/android/AndroidOptions.kt#L28-L35 +[BaseAndroidPlugin]: infrastructure-android/src/main/kotlin/android/BaseAndroidPlugin.kt +[AndroidLibraryPlugin]: infrastructure-android/src/main/kotlin/android/AndroidLibraryPlugin.kt +[AndroidApplicationPlugin]: infrastructure-android/src/main/kotlin/android/AndroidApplicationPlugin.kt [infrastructure]: # [itemsadapter]: https://github.com/RedMadRobot/itemsadapter diff --git a/build.gradle.kts b/build.gradle.kts index e3f094c..30da3a6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,46 +1,19 @@ -import com.redmadrobot.build.dsl.developer -import com.redmadrobot.build.dsl.isRunningOnCi -import com.redmadrobot.build.dsl.mit -import com.redmadrobot.build.dsl.setGitHubProject - plugins { id("com.redmadrobot.detekt") id("com.redmadrobot.publish-config") alias(libs.plugins.versions) - `kotlin-dsl` apply false } redmadrobot { - jvmTarget.set(JavaVersion.VERSION_11) - - publishing { - signArtifacts.set(!isRunningOnCi) - - pom { - setGitHubProject("RedMadRobot/gradle-infrastructure") - - licenses { - mit() - } - - developers { - developer(id = "osipxd", name = "Osip Fatkullin", email = "o.fatkullin@redmadrobot.com") - developer(id = "rwqwr", name = "Roman Ivanov", email = "r.ivanov@redmadrobot.com") - } - } - } + jvmTarget = JavaVersion.VERSION_11 } subprojects { apply { - plugin("org.gradle.kotlin.kotlin-dsl") plugin("io.gitlab.arturbosch.detekt") } dependencies { detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.22.0") } - - group = "com.redmadrobot.build" - version = "0.18.1" } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 11be23e..eba1350 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,11 +3,13 @@ plugins { } dependencies { - api(libs.infrastructure.detekt) - api(libs.infrastructure.kotlin) - api(libs.infrastructure.publish) - api(libs.pluginPublish) - api(libs.kotlinGradle) + implementation(libs.infrastructure.detekt) + implementation(libs.infrastructure.kotlin) + implementation(libs.infrastructure.publish) + implementation(libs.pluginPublish) + implementation(libs.mavenPublishPlugin) + implementation(libs.gradle.kotlinDsl) + implementation(libs.kotlinGradle) } repositories { diff --git a/buildSrc/src/main/kotlin/commons.gradle.kts b/buildSrc/src/main/kotlin/commons.gradle.kts deleted file mode 100644 index 3ec4dc6..0000000 --- a/buildSrc/src/main/kotlin/commons.gradle.kts +++ /dev/null @@ -1,30 +0,0 @@ -import com.redmadrobot.build.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion - -plugins { - id("com.redmadrobot.kotlin-library") - id("com.redmadrobot.publish") -} - -publishing { - repositories { - if (isRunningOnCi) githubPackages("RedMadRobot/gradle-infrastructure") - if (isReleaseVersion && credentialsExist("ossrh")) ossrh() - } -} - -afterEvaluate { - // Don't publish markers to OSSRH repository - tasks.withType() - .matching { task -> task.repository.name == "ossrh" && "PluginMarker" in task.name } - .configureEach { enabled = false } - - // Keep gradle-infrastructure compatible with older versions of Gradle. - kotlinCompile { - compilerOptions { - apiVersion.set(KotlinVersion.KOTLIN_1_4) - languageVersion.set(KotlinVersion.KOTLIN_1_4) - freeCompilerArgs.add("-Xuse-ir") // Needed as long as languageVersion is less than 1.5 - } - } -} diff --git a/buildSrc/src/main/kotlin/convention.common.gradle.kts b/buildSrc/src/main/kotlin/convention.common.gradle.kts new file mode 100644 index 0000000..6818c7d --- /dev/null +++ b/buildSrc/src/main/kotlin/convention.common.gradle.kts @@ -0,0 +1,17 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + +plugins { + id("com.redmadrobot.kotlin-library") + id("convention.publish") + id("org.gradle.kotlin.kotlin-dsl") +} + +kotlin { + // Keep gradle-infrastructure compatible with older versions of Gradle. + // Language version should be in sync with the one used in Gradle + // https://docs.gradle.org/current/userguide/compatibility.html#kotlin + compilerOptions { + apiVersion = KotlinVersion.KOTLIN_1_8 + languageVersion = KotlinVersion.KOTLIN_1_8 + } +} diff --git a/buildSrc/src/main/kotlin/convention.plugin.gradle.kts b/buildSrc/src/main/kotlin/convention.plugin.gradle.kts new file mode 100644 index 0000000..bab8977 --- /dev/null +++ b/buildSrc/src/main/kotlin/convention.plugin.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("convention.common") + id("com.gradle.plugin-publish") +} + +gradlePlugin { + website = "https://github.com/RedMadRobot/gradle-infrastructure" + vcsUrl = "https://github.com/RedMadRobot/gradle-infrastructure.git" +} diff --git a/buildSrc/src/main/kotlin/convention.publish.gradle.kts b/buildSrc/src/main/kotlin/convention.publish.gradle.kts new file mode 100644 index 0000000..8fe85c5 --- /dev/null +++ b/buildSrc/src/main/kotlin/convention.publish.gradle.kts @@ -0,0 +1,47 @@ +import com.redmadrobot.build.dsl.* +import com.vanniktech.maven.publish.SonatypeHost + +plugins { + id("com.vanniktech.maven.publish") + signing +} + +publishing { + repositories { + if (isRunningOnCi) githubPackages("RedMadRobot/gradle-infrastructure") + } +} + +mavenPublishing { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, automaticRelease = true) + signAllPublications() + + coordinates(artifactId = project.name) + + pom { + name = project.name + description = project.description + + setGitHubProject("RedMadRobot/gradle-infrastructure") + + licenses { + mit() + } + + developers { + developer(id = "osipxd", name = "Osip Fatkullin", email = "o.fatkullin@redmadrobot.com") + developer(id = "rwqwr", name = "Roman Ivanov", email = "r.ivanov@redmadrobot.com") + } + } +} + +// com.vanniktech.maven.publish uses afterEvaluate +// so we want to change tasks after-after evaluate +afterEvaluate { + afterEvaluate { + // Don't publish markers to Maven Central repository + tasks.withType() + .matching { task -> task.repository.name == "mavenCentral" && "PluginMarker" in task.name } + .configureEach { enabled = false } + } +} diff --git a/buildSrc/src/main/kotlin/gradle-plugin-commons.gradle.kts b/buildSrc/src/main/kotlin/gradle-plugin-commons.gradle.kts deleted file mode 100644 index 14d424f..0000000 --- a/buildSrc/src/main/kotlin/gradle-plugin-commons.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - id("commons") - id("com.gradle.plugin-publish") -} - -gradlePlugin { - website.set("https://github.com/RedMadRobot/gradle-infrastructure") - vcsUrl.set("https://github.com/RedMadRobot/gradle-infrastructure.git") -} diff --git a/gradle.properties b/gradle.properties index 1939e6a..0941785 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,6 @@ +group=com.redmadrobot.build +version=0.19 + # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d2eabe9..1e17594 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,18 +1,17 @@ [versions] -infrastructure = "0.18" +infrastructure = "0.18.1" [libraries] infrastructure-kotlin = { module = "com.redmadrobot.build:infrastructure-kotlin", version.ref = "infrastructure" } infrastructure-detekt = { module = "com.redmadrobot.build:infrastructure-detekt", version.ref = "infrastructure" } infrastructure-publish = { module = "com.redmadrobot.build:infrastructure-publish", version.ref = "infrastructure" } -androidTools-gradle = "com.android.tools.build:gradle:7.4.2" -androidTools-common = "com.android.tools:common:30.4.2" -androidGradleCacheFix = "gradle.plugin.org.gradle.android:android-cache-fix-gradle-plugin:2.7.0" -detektGradle = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.22.0" -kotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10" -pluginPublish = "com.gradle.publish:plugin-publish-plugin:1.1.0" -jgit = "org.eclipse.jgit:org.eclipse.jgit:6.4.0.202211300538-r" +androidTools-gradle = "com.android.tools.build:gradle:8.5.1" +detektGradle = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.6" +kotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0" +pluginPublish = "com.gradle.publish:plugin-publish-plugin:1.2.1" +mavenPublishPlugin = "com.vanniktech:gradle-maven-publish-plugin:0.29.0" +gradle-kotlinDsl = "org.gradle.kotlin:gradle-kotlin-dsl-plugins:4.4.0" +jgit = "org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r" [plugins] -versions = "com.github.ben-manes.versions:0.46.0" - +versions = "com.github.ben-manes.versions:0.51.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a7..2c35211 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c85a1f..09523c0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cb..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/. @@ -83,7 +85,9 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +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 @@ -130,10 +134,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +205,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..9d21a21 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/infrastructure-android/build.gradle.kts b/infrastructure-android/build.gradle.kts index f353da7..e955e27 100644 --- a/infrastructure-android/build.gradle.kts +++ b/infrastructure-android/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("gradle-plugin-commons") + convention.plugin } description = "Small plugins to reduce boilerplate in Android projects' Gradle build scripts." @@ -33,8 +33,5 @@ gradlePlugin { dependencies { api(projects.infrastructureKotlin) - compileOnly(libs.androidTools.gradle) // Should be provided by project - compileOnly(libs.androidTools.common) // Should be provided via AGP - - implementation(libs.androidGradleCacheFix) + compileOnly(libs.androidTools.gradle) // Should be provided by a project } diff --git a/infrastructure-android/src/main/kotlin/android/AndroidApplicationPlugin.kt b/infrastructure-android/src/main/kotlin/android/AndroidApplicationPlugin.kt index f19402b..7a7711c 100644 --- a/infrastructure-android/src/main/kotlin/android/AndroidApplicationPlugin.kt +++ b/infrastructure-android/src/main/kotlin/android/AndroidApplicationPlugin.kt @@ -9,13 +9,9 @@ import com.android.build.api.variant.ApplicationVariant import com.redmadrobot.build.StaticAnalyzerSpec import com.redmadrobot.build.android.internal.android import com.redmadrobot.build.android.internal.androidComponents -import com.redmadrobot.build.android.internal.projectProguardFiles +import com.redmadrobot.build.android.internal.ifPresent import com.redmadrobot.build.android.task.MakeDebuggableTask -import com.redmadrobot.build.dsl.BUILD_TYPE_DEBUG -import com.redmadrobot.build.dsl.BUILD_TYPE_QA -import com.redmadrobot.build.dsl.BUILD_TYPE_RELEASE -import com.redmadrobot.build.dsl.finalizeQaBuildType -import com.redmadrobot.build.internal.InternalGradleInfrastructureApi +import com.redmadrobot.build.dsl.* import org.gradle.api.Project import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.register @@ -26,12 +22,9 @@ import org.gradle.kotlin.dsl.register * * Tied to `com.redmadrobot.application` plugin ID. */ -public class AndroidApplicationPlugin : BaseAndroidPlugin() { - - @InternalGradleInfrastructureApi - override fun Project.configure() { - applyBaseAndroidPlugin("com.android.application") +public class AndroidApplicationPlugin : BaseAndroidPlugin("com.android.application") { + override fun Project.configure(configPlugin: AndroidConfigPlugin) { configureApp() androidComponents { onVariants(selector().withBuildType(BUILD_TYPE_QA)) { it.makeDebuggable(tasks) } @@ -43,10 +36,7 @@ public class AndroidApplicationPlugin : BaseAndroidPlugin() { private fun Project.configureApp() = android { defaultConfig { // Collect proguard rules from 'proguard' dir - setProguardFiles(projectProguardFiles() + getDefaultProguardFile("proguard-android-optimize.txt")) - - buildConfigField("boolean", VAR_LOCK_ORIENTATION, "true") - buildConfigField("boolean", VAR_CRASH_REPORTS_ENABLED, "true") + proguardFiles.addAll(collectProguardFiles()) } finalizeQaBuildType() @@ -56,9 +46,6 @@ private fun Project.configureApp() = android { isDebuggable = true isMinifyEnabled = false isShrinkResources = false - - buildConfigField("boolean", VAR_LOCK_ORIENTATION, "false") - buildConfigField("boolean", VAR_CRASH_REPORTS_ENABLED, "false") } release { @@ -73,10 +60,6 @@ private fun Project.configureApp() = android { applicationIdSuffix = ".$BUILD_TYPE_QA" matchingFallbacks += listOf(BUILD_TYPE_DEBUG, BUILD_TYPE_RELEASE) signingConfig = signingConfigs.findByName(BUILD_TYPE_DEBUG) - - // We can not use isDebuggable = true here, so set DEBUG field ourselves. - // See `makeDebuggable` for more information - buildConfigField(type = "boolean", name = "DEBUG", value = "true") } } } @@ -85,7 +68,8 @@ private fun Project.configureApp() = android { // set isDebuggable to `false` and manually set "debuggable" flag in manifest // See: https://issuetracker.google.com/issues/238655204 private fun ApplicationVariant.makeDebuggable(tasks: TaskContainer) { - val makeDebuggableTask = tasks.register("make${name.capitalize()}Debuggable") + val capitalizedName = name.replaceFirstChar { it.uppercaseChar() } + val makeDebuggableTask = tasks.register("make${capitalizedName}Debuggable") artifacts.use(makeDebuggableTask) .wiredWithFiles( @@ -99,17 +83,20 @@ private fun ApplicationExtension.finalizeApp( androidOptions: AndroidOptions, staticAnalyzerSpec: StaticAnalyzerSpec, ) { - defaultConfig { - targetSdk = androidOptions.targetSdk.get() - } + androidOptions.targetSdk.ifPresent { defaultConfig.targetSdk = it } lint { xmlOutput = staticAnalyzerSpec.reportsDir.file("lint-results.xml").get().asFile htmlOutput = staticAnalyzerSpec.reportsDir.file("lint-results.html").get().asFile } -} - -// Constants -private const val VAR_LOCK_ORIENTATION = "LOCK_ORIENTATION" -private const val VAR_CRASH_REPORTS_ENABLED = "CRASH_REPORTS_ENABLED" + buildTypes { + if (buildFeatures.buildConfig == true) { + qa { + // We can not use isDebuggable = true here, so set DEBUG field ourselves. + // See `makeDebuggable` for more information + buildConfigField(type = "boolean", name = "DEBUG", value = "true") + } + } + } +} diff --git a/infrastructure-android/src/main/kotlin/android/AndroidConfigPlugin.kt b/infrastructure-android/src/main/kotlin/android/AndroidConfigPlugin.kt index 73670da..ee5dc91 100644 --- a/infrastructure-android/src/main/kotlin/android/AndroidConfigPlugin.kt +++ b/infrastructure-android/src/main/kotlin/android/AndroidConfigPlugin.kt @@ -5,10 +5,8 @@ import com.redmadrobot.build.StaticAnalyzerSpec import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import com.redmadrobot.build.internal.hasPlugin import com.redmadrobot.build.kotlin.KotlinConfigPlugin -import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.internal.plugins.PluginRegistry -import org.gradle.api.provider.Provider import org.gradle.kotlin.dsl.apply import javax.inject.Inject @@ -25,9 +23,6 @@ public open class AndroidConfigPlugin @Inject constructor( internal lateinit var androidOptions: AndroidOptionsImpl private set - internal val jvmTarget: Provider - get() = redmadrobotExtension.jvmTarget - internal val staticAnalyzerSpec: StaticAnalyzerSpec get() = redmadrobotExtension diff --git a/infrastructure-android/src/main/kotlin/android/AndroidLibraryPlugin.kt b/infrastructure-android/src/main/kotlin/android/AndroidLibraryPlugin.kt index 98ea76f..965e3a0 100644 --- a/infrastructure-android/src/main/kotlin/android/AndroidLibraryPlugin.kt +++ b/infrastructure-android/src/main/kotlin/android/AndroidLibraryPlugin.kt @@ -4,14 +4,9 @@ package com.redmadrobot.build.android import com.android.build.api.dsl.LibraryExtension import com.redmadrobot.build.android.internal.android -import com.redmadrobot.build.android.internal.projectProguardFiles -import com.redmadrobot.build.internal.InternalGradleInfrastructureApi -import com.redmadrobot.build.kotlin.internal.kotlin +import com.redmadrobot.build.dsl.collectProguardFiles import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -private const val ARG_EXPLICIT_API = "-Xexplicit-api" +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension /** * Plugin that applies default configurations for Android library project. @@ -19,47 +14,22 @@ private const val ARG_EXPLICIT_API = "-Xexplicit-api" * * Tied to `com.redmadrobot.android-library` plugin ID. */ -public class AndroidLibraryPlugin : BaseAndroidPlugin() { - - @InternalGradleInfrastructureApi - override fun Project.configure() { - applyBaseAndroidPlugin("com.android.library") +public class AndroidLibraryPlugin : BaseAndroidPlugin("com.android.library") { + override fun Project.configure(configPlugin: AndroidConfigPlugin) { android { defaultConfig { // Add all files from 'proguard' dir - consumerProguardFiles.addAll(projectProguardFiles()) + consumerProguardFiles.addAll(collectProguardFiles()) } buildFeatures { - buildConfig = false resValues = false androidResources = false } } // Enable Explicit API mode for libraries by default - if (kotlin.explicitApi == null) kotlin.explicitApi() - afterEvaluate { - configureExplicitApi(kotlin.explicitApi) - } + kotlinExtension.explicitApi() } } - -// Workaround to configure Explicit API mode in android library modules -// Related issues: -// https://youtrack.jetbrains.com/issue/KT-37652 -// https://issuetracker.google.com/issues/167819676 -// https://issuetracker.google.com/issues/168371736 -// TODO: Remove when the issue will be fixed -private fun Project.configureExplicitApi(mode: ExplicitApiMode?) { - if (mode == null) return - - tasks.matching { it is KotlinCompile && !it.name.contains("test", ignoreCase = true) } - .configureEach { - val options = (this as KotlinCompile).kotlinOptions - if (options.freeCompilerArgs.none { arg -> arg.startsWith(ARG_EXPLICIT_API) }) { - options.freeCompilerArgs += mode.toCompilerArg() - } - } -} diff --git a/infrastructure-android/src/main/kotlin/android/AndroidOptions.kt b/infrastructure-android/src/main/kotlin/android/AndroidOptions.kt index 4b47a7a..47d11a7 100644 --- a/infrastructure-android/src/main/kotlin/android/AndroidOptions.kt +++ b/infrastructure-android/src/main/kotlin/android/AndroidOptions.kt @@ -6,25 +6,33 @@ import org.gradle.api.tasks.TaskProvider /** Options for android projects. */ public interface AndroidOptions { - /** Minimal Android SDK to use across all android modules. */ + /** Minimal Android SDK to be used in all android modules. */ public val minSdk: Property - /** Target Android SDK to use across all android modules. */ + /** Target Android SDK to be used in all android modules. */ public val targetSdk: Property /** - * Compile Android SDK to use across all android modules. + * Compile Android SDK to be used in all android modules. * It can be version number ("33") or version code ("T"). * Uses [targetSdk] as compile SDK if not configured. */ public val compileSdk: Property /** - * Build Tools version to use across all android modules. - * Uses default version for current Android Gradle Plugin if not configured. + * Build Tools version to be used in all android modules. + * + * By default, uses the version from environment variable `ANDROID_BUILD_TOOLS_VERSION`, + * or default version for current Android Gradle Plugin if the variable is not present. */ public val buildToolsVersion: Property + /** + * NDK to be used in all android modules. + * By default, uses the version from the environment variable `ANDROID_NDK_VERSION` if it is set. + */ + public val ndkVersion: Property + /** * Filters test tasks that should be run on ':test'. * It is useful if you don't want to run tests for all build variants when run 'test' task. @@ -34,8 +42,5 @@ public interface AndroidOptions { */ public val testTasksFilter: Property<(TaskProvider<*>) -> Boolean> - public companion object { - internal const val DEFAULT_MIN_API = 23 - internal const val DEFAULT_TARGET_API = 33 - } + public companion object } diff --git a/infrastructure-android/src/main/kotlin/android/AndroidOptionsImpl.kt b/infrastructure-android/src/main/kotlin/android/AndroidOptionsImpl.kt index 06eec9b..3a63d28 100644 --- a/infrastructure-android/src/main/kotlin/android/AndroidOptionsImpl.kt +++ b/infrastructure-android/src/main/kotlin/android/AndroidOptionsImpl.kt @@ -5,26 +5,32 @@ import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import com.redmadrobot.build.kotlin.TestOptions import com.redmadrobot.build.kotlin.TestOptionsImpl import org.gradle.api.plugins.ExtensionAware +import org.gradle.api.provider.ProviderFactory import org.gradle.kotlin.dsl.create +import javax.inject.Inject @OptIn(InternalGradleInfrastructureApi::class) @Suppress("LeakingThis") -internal abstract class AndroidOptionsImpl : AndroidOptions, WithDefaults { +internal abstract class AndroidOptionsImpl @Inject constructor( + providers: ProviderFactory, +) : AndroidOptions, WithDefaults { private val testOptions: TestOptionsImpl private var areTestDefaultsSet = false init { minSdk - .convention(AndroidOptions.DEFAULT_MIN_API) .finalizeValueOnRead() targetSdk - .convention(AndroidOptions.DEFAULT_TARGET_API) .finalizeValueOnRead() compileSdk .convention(targetSdk.map(Int::toString)) .finalizeValueOnRead() buildToolsVersion + .convention(providers.environmentVariable("ANDROID_BUILD_TOOLS_VERSION")) + .finalizeValueOnRead() + ndkVersion + .convention(providers.environmentVariable("ANDROID_NDK_VERSION")) .finalizeValueOnRead() testTasksFilter .convention { taskProvider -> taskProvider.name.endsWith("ReleaseUnitTest") } @@ -43,6 +49,7 @@ internal abstract class AndroidOptionsImpl : AndroidOptions, WithDefaults { + + override fun apply(target: Project) { + with(target) { + val configPlugin = plugins.apply(AndroidConfigPlugin::class) + applyBaseAndroidPlugin(androidPluginId, configPlugin) + configure(configPlugin) + } + } - @InternalGradleInfrastructureApi - protected val configPlugin: AndroidConfigPlugin - get() = project.plugins.getPlugin(AndroidConfigPlugin::class) + internal abstract fun Project.configure(configPlugin: AndroidConfigPlugin) - /** Should be called from [configure] in implementation. */ - @InternalGradleInfrastructureApi - protected fun Project.applyBaseAndroidPlugin(pluginId: String) { - val configPlugin = plugins.apply(AndroidConfigPlugin::class) + private fun Project.applyBaseAndroidPlugin(pluginId: String, configPlugin: AndroidConfigPlugin) { apply { plugin(pluginId) plugin("kotlin-android") - - // Apply fix for Android caching problems - // See https://github.com/gradle/android-cache-fix-gradle-plugin - plugin("org.gradle.android.cache-fix") } - configureKotlin(configPlugin.jvmTarget) configureAndroid() androidComponents { finalizeDsl { extension -> extension.applyAndroidOptions( options = configPlugin.androidOptions, - jvmTarget = configPlugin.jvmTarget, staticAnalyzerSpec = configPlugin.staticAnalyzerSpec, ) filterTestTaskDependencies(configPlugin.androidOptions) @@ -62,14 +52,8 @@ public abstract class BaseAndroidPlugin internal constructor() : InfrastructureP } } -private fun Project.configureAndroid() = android> { - // Set NDK version from env variable if exists - val requestedNdkVersion = System.getenv("ANDROID_NDK_VERSION") - if (requestedNdkVersion != null) ndkVersion = requestedNdkVersion - +private fun Project.configureAndroid() = android { buildFeatures { - aidl = false - renderScript = false shaders = false } @@ -81,22 +65,14 @@ private fun Project.configureAndroid() = android> { } @OptIn(InternalGradleInfrastructureApi::class) -private fun CommonExtension<*, *, *, *>.applyAndroidOptions( +private fun CommonExtension.applyAndroidOptions( options: AndroidOptions, - jvmTarget: Provider, staticAnalyzerSpec: StaticAnalyzerSpec, ) { - setCompileSdkVersion(options.compileSdk.get()) + options.compileSdk.ifPresent { setCompileSdkVersion(it) } options.buildToolsVersion.ifPresent { buildToolsVersion = it } - - defaultConfig { - minSdk = options.minSdk.get() - } - - compileOptions { - sourceCompatibility = jvmTarget.get() - targetCompatibility = jvmTarget.get() - } + options.ndkVersion.ifPresent { ndkVersion = it } + options.minSdk.ifPresent { defaultConfig.minSdk = it } testOptions { unitTests.all { it.setTestOptions(options.test) } @@ -108,8 +84,8 @@ private fun CommonExtension<*, *, *, *>.applyAndroidOptions( } } -/** Universal function to set compile SDK even if it is preview version. */ -private fun CommonExtension<*, *, *, *>.setCompileSdkVersion(version: String) { +/** Universal function to set compile SDK even if it is a preview version. */ +private fun CommonExtension.setCompileSdkVersion(version: String) { val intVersion = version.toIntOrNull() if (intVersion != null) { compileSdk = intVersion @@ -118,7 +94,7 @@ private fun CommonExtension<*, *, *, *>.setCompileSdkVersion(version: String) { } } -/** Filter unit tests to be run with 'test' task. */ +/** Filter unit tests to be run with the 'test' task. */ private fun Project.filterTestTaskDependencies(options: AndroidOptions) { afterEvaluate { tasks.named("test") { diff --git a/infrastructure-android/src/main/kotlin/android/internal/Accessors.kt b/infrastructure-android/src/main/kotlin/android/internal/Accessors.kt index 33053c7..6997e8b 100644 --- a/infrastructure-android/src/main/kotlin/android/internal/Accessors.kt +++ b/infrastructure-android/src/main/kotlin/android/internal/Accessors.kt @@ -2,15 +2,22 @@ package com.redmadrobot.build.android.internal -import com.android.build.api.dsl.CommonExtension import com.android.build.api.variant.AndroidComponentsExtension import com.redmadrobot.build.android.AndroidOptions import com.redmadrobot.build.kotlin.TestOptions import org.gradle.api.Project import org.gradle.api.plugins.ExtensionAware import org.gradle.kotlin.dsl.getByName +import com.android.build.api.dsl.CommonExtension as ParameterizedCommonExtension -internal fun > Project.android(configure: T.() -> Unit) { +internal typealias CommonExtension = ParameterizedCommonExtension<*, *, *, *, *, *> + +@JvmName("androidCommon") +internal fun Project.android(configure: CommonExtension.() -> Unit) { + android(configure) +} + +internal fun Project.android(configure: T.() -> Unit) { extensions.configure("android", configure) } diff --git a/infrastructure-android/src/main/kotlin/android/internal/Proguard.kt b/infrastructure-android/src/main/kotlin/android/internal/Proguard.kt deleted file mode 100644 index 0a41caa..0000000 --- a/infrastructure-android/src/main/kotlin/android/internal/Proguard.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.redmadrobot.build.android.internal - -import org.gradle.api.Project -import java.io.File - -/** Collects proguard rules from 'proguard' dir. */ -internal fun Project.projectProguardFiles(): List { - return fileTree("proguard") - .files - .filter { it.extension == "pro" } -} diff --git a/infrastructure-android/src/main/kotlin/android/internal/Provider.kt b/infrastructure-android/src/main/kotlin/android/internal/Provider.kt index 2dec641..2f971a3 100644 --- a/infrastructure-android/src/main/kotlin/android/internal/Provider.kt +++ b/infrastructure-android/src/main/kotlin/android/internal/Provider.kt @@ -2,6 +2,6 @@ package com.redmadrobot.build.android.internal import org.gradle.api.provider.Property -internal fun Property.ifPresent(action: (T) -> Unit) { +internal inline fun Property.ifPresent(action: (T) -> Unit) { if (isPresent) action(get()) } diff --git a/infrastructure-android/src/main/kotlin/dsl/ProjectProguardFiles.kt b/infrastructure-android/src/main/kotlin/dsl/ProjectProguardFiles.kt new file mode 100644 index 0000000..6e3916e --- /dev/null +++ b/infrastructure-android/src/main/kotlin/dsl/ProjectProguardFiles.kt @@ -0,0 +1,11 @@ +package com.redmadrobot.build.dsl + +import org.gradle.api.Project +import java.io.File + +/** Collects proguard rules from the specified [path]. */ +public fun Project.collectProguardFiles(path: String = "proguard"): List { + return fileTree(path) + .files + .filter { it.extension == "pro" } +} diff --git a/infrastructure-android/src/main/kotlin/dsl/Signing.kt b/infrastructure-android/src/main/kotlin/dsl/Signing.kt new file mode 100644 index 0000000..6b79cf3 --- /dev/null +++ b/infrastructure-android/src/main/kotlin/dsl/Signing.kt @@ -0,0 +1,29 @@ +package dsl + +import com.android.build.api.dsl.SigningConfig +import org.gradle.api.Incubating +import java.io.File +import java.util.* + +/** + * Applies signature configuration from the specified [propertiesFile]. + * + * The file content should have the following format: + * ``` + * store_file=[relative path to keystore file] + * store_password=[keystore password] + * key_alias=[the alias of the needed key] + * key_password=[the password for the specified alias] + * ``` + */ +@Incubating +public fun SigningConfig.fromProperties(propertiesFile: File) { + val directory = propertiesFile.parentFile + val properties = Properties() + propertiesFile.inputStream().use(properties::load) + + storeFile = File(directory, properties.getProperty("store_file")) + storePassword = properties.getProperty("store_password") + keyAlias = properties.getProperty("key_alias") + keyPassword = properties.getProperty("key_password") +} diff --git a/infrastructure-android/src/main/kotlin/dsl/SourceSets.kt b/infrastructure-android/src/main/kotlin/dsl/SourceSets.kt index 14c3bb7..5cfbbcf 100644 --- a/infrastructure-android/src/main/kotlin/dsl/SourceSets.kt +++ b/infrastructure-android/src/main/kotlin/dsl/SourceSets.kt @@ -1,10 +1,21 @@ package com.redmadrobot.build.dsl -import com.android.SdkConstants.* import com.android.build.api.dsl.AndroidSourceSet -import com.android.build.api.dsl.CommonExtension -import org.gradle.api.Incubating -import org.gradle.kotlin.dsl.get +import com.redmadrobot.build.android.internal.CommonExtension +import org.gradle.api.NamedDomainObjectContainer + +/** Use `sourceSets.addSharedSourceSetRoot` instead. */ +@Deprecated( + "Use sourceSets.addSharedSourceSetRoot(...) instead.", + ReplaceWith("this.sourceSets.addSharedSourceSetRoot(variant1, variant2, name)") +) +public fun CommonExtension.addSharedSourceSetRoot( + variant1: String, + variant2: String, + name: String = "$variant1${variant2.replaceFirstChar { it.uppercaseChar() }}", +) { + sourceSets.addSharedSourceSetRoot(variant1, variant2, name) +} /** * Adds source set root with the given [name], shared between [variant1] and [variant2] source sets. @@ -12,38 +23,34 @@ import org.gradle.kotlin.dsl.get * ``` * android { * // Here we need to share sources between debug and QA builds - * addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) + * sourceSets.addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) * * // We can specify name for the source set root if need - * addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA, name = "debugPanel") + * sourceSets.addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA, name = "debugPanel") * } * ``` */ -@Incubating -public fun CommonExtension<*, *, *, *>.addSharedSourceSetRoot( +public fun NamedDomainObjectContainer.addSharedSourceSetRoot( variant1: String, variant2: String, - name: String = "$variant1${variant2.capitalize()}", + name: String = "$variant1${variant2.replaceFirstChar { it.uppercaseChar() }}", ) { - val variant1SourceSets = sourceSets[variant1] - val variant2SourceSets = sourceSets[variant2] val root = "src/$name" - - variant1SourceSets.addRoot(root) - variant2SourceSets.addRoot(root) + getByName(variant1).addRoot(root) + getByName(variant2).addRoot(root) } -@Suppress("UnstableApiUsage") +/** Works similar to [AndroidSourceSet.setRoot], but adds the new [path] to the existing roots. */ private fun AndroidSourceSet.addRoot(path: String) { - java.srcDirs("$path/$FD_JAVA") - kotlin.srcDirs("$path/$FD_JAVA", "$path/kotlin") - resources.srcDir("$path/$FD_JAVA_RES") - res.srcDir("$path/$FD_RES") - assets.srcDir("$path/$FD_ASSETS") - manifest.srcFile("$path/$FN_ANDROID_MANIFEST_XML") - aidl.srcDir("$path/$FD_AIDL") - renderscript.srcDir("$path/$FD_RENDERSCRIPT") + java.srcDirs("$path/java") + kotlin.srcDirs("$path/java", "$path/kotlin") + resources.srcDir("$path/resources") + res.srcDir("$path/res") + assets.srcDir("$path/assets") + manifest.srcFile("$path/AndroidManifest.xml") + aidl.srcDir("$path/aidl") + renderscript.srcDir("$path/rs") jniLibs.srcDir("$path/jniLibs") shaders.srcDir("$path/shaders") - mlModels.srcDir("$path/$FD_ML_MODELS") + mlModels.srcDir("$path/ml") } diff --git a/infrastructure-common/build.gradle.kts b/infrastructure-common/build.gradle.kts index 2449249..f691469 100644 --- a/infrastructure-common/build.gradle.kts +++ b/infrastructure-common/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("commons") + convention.common } description = "Commons for gradle-infrastructure plugins" diff --git a/infrastructure-common/src/main/kotlin/RedmadrobotExtension.kt b/infrastructure-common/src/main/kotlin/RedmadrobotExtension.kt index dc9fe0b..bdaabef 100644 --- a/infrastructure-common/src/main/kotlin/RedmadrobotExtension.kt +++ b/infrastructure-common/src/main/kotlin/RedmadrobotExtension.kt @@ -8,8 +8,12 @@ public interface RedmadrobotExtension : StaticAnalyzerSpec { /** * JVM version to be used as a target by Kotlin and Java compilers. - * By default, used Java 11. + * Use [JVM Toolchains](https://kotl.in/gradle/jvm/toolchain) instead. */ + @Deprecated( + "Use JVM Toolchains instead. See https://kotl.in/gradle/jvm/toolchain", + level = DeprecationLevel.ERROR + ) public val jvmTarget: Property public companion object { diff --git a/infrastructure-common/src/main/kotlin/RedmadrobotExtensionImpl.kt b/infrastructure-common/src/main/kotlin/RedmadrobotExtensionImpl.kt index 82ce64c..2323b94 100644 --- a/infrastructure-common/src/main/kotlin/RedmadrobotExtensionImpl.kt +++ b/infrastructure-common/src/main/kotlin/RedmadrobotExtensionImpl.kt @@ -1,7 +1,6 @@ package com.redmadrobot.build import com.redmadrobot.build.internal.findByName -import org.gradle.api.JavaVersion import org.gradle.api.file.ProjectLayout import org.gradle.api.plugins.ExtensionAware import org.gradle.api.plugins.ExtensionContainer @@ -13,9 +12,6 @@ internal abstract class RedmadrobotExtensionImpl @Inject constructor( ) : RedmadrobotExtension, ExtensionAware, WithDefaults { init { - jvmTarget - .convention(JavaVersion.VERSION_11) - .finalizeValueOnRead() configsDir .convention(layout.projectDirectory.dir(StaticAnalyzerSpec.DEFAULT_CONFIGS_DIR)) .finalizeValueOnRead() @@ -25,7 +21,6 @@ internal abstract class RedmadrobotExtensionImpl @Inject constructor( } override fun setDefaults(defaults: RedmadrobotExtensionImpl) { - jvmTarget.convention(defaults.jvmTarget) configsDir.convention(defaults.configsDir) reportsDir.convention(defaults.reportsDir) } diff --git a/infrastructure-common/src/main/kotlin/StaticAnalyzerSpec.kt b/infrastructure-common/src/main/kotlin/StaticAnalyzerSpec.kt index ce9766d..cdc9fb7 100644 --- a/infrastructure-common/src/main/kotlin/StaticAnalyzerSpec.kt +++ b/infrastructure-common/src/main/kotlin/StaticAnalyzerSpec.kt @@ -5,10 +5,10 @@ import org.gradle.api.file.DirectoryProperty /** Options used for static analyzers' configurations. */ public interface StaticAnalyzerSpec { - /** Directory where stored configs for static analyzers. */ + /** Directory with configs for static analyzers and other tools. */ public val configsDir: DirectoryProperty - /** Directory where will be stored static analyzers reports. */ + /** Directory with reports of static analyzers and other tools. */ public val reportsDir: DirectoryProperty public companion object { diff --git a/infrastructure-common/src/main/kotlin/internal/ProjectOptions.kt b/infrastructure-common/src/main/kotlin/internal/ProjectOptions.kt index 29c079c..8669c41 100644 --- a/infrastructure-common/src/main/kotlin/internal/ProjectOptions.kt +++ b/infrastructure-common/src/main/kotlin/internal/ProjectOptions.kt @@ -6,6 +6,6 @@ import org.gradle.kotlin.dsl.repositories @InternalGradleInfrastructureApi public fun Project.addRepositoriesIfNeed(block: RepositoryHandler.() -> Unit) { - val addRepositories = findBooleanProperty("redmadrobot.add.repositories") != false + val addRepositories = findBooleanProperty("redmadrobot.add.repositories") == true if (addRepositories) repositories(block) } diff --git a/infrastructure-detekt/build.gradle.kts b/infrastructure-detekt/build.gradle.kts index 20fd723..cdbff21 100644 --- a/infrastructure-detekt/build.gradle.kts +++ b/infrastructure-detekt/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("gradle-plugin-commons") + convention.plugin } description = "Additional functionality for detekt" diff --git a/infrastructure-detekt/src/main/kotlin/DetektPlugin.kt b/infrastructure-detekt/src/main/kotlin/DetektPlugin.kt index 5ec5878..8f4cae9 100644 --- a/infrastructure-detekt/src/main/kotlin/DetektPlugin.kt +++ b/infrastructure-detekt/src/main/kotlin/DetektPlugin.kt @@ -49,7 +49,7 @@ private fun Project.configureDependencies() { } dependencies { - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.22.0") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.6") } } @@ -135,9 +135,9 @@ private fun Project.configureDetektDiffTask( ) val findChangedFiles = tasks.register("findChangedFiles") { - projectDir.set(layout.projectDirectory) - filterParams.set(changedFilesFilter) - branch.set(detektDiffOptions.baseBranch) + projectDir = layout.projectDirectory + filterParams = changedFilesFilter + branch = detektDiffOptions.baseBranch } detektTask(staticAnalyzerSpec, "detektDiff") { @@ -155,18 +155,18 @@ private inline fun Project.detektTask( return tasks.register(name) { parallel = true config.setFrom(provider { staticAnalyzerSpec.configsDir.get().file("detekt/detekt.yml") }) - baseline.set(provider { staticAnalyzerSpec.configsDir.getFileIfExists("detekt/baseline.xml") }) + baseline = provider { staticAnalyzerSpec.configsDir.getFileIfExists("detekt/baseline.xml") } setSource(projectDir) - reportsDir.set(staticAnalyzerSpec.reportsDir.asFile) + reportsDir = staticAnalyzerSpec.reportsDir.asFile include("**/*.kt") include("**/*.kts") exclude("**/res/**") exclude("**/build/**") exclude("**/.*/**") reports { - xml.required.set(true) - txt.required.set(false) - html.required.set(false) + xml.required = true + txt.required = false + html.required = false } configure() } @@ -178,9 +178,9 @@ private inline fun Project.detektCreateBaselineTask( crossinline configure: DetektCreateBaselineTask.() -> Unit, ): TaskProvider { return tasks.register(name) { - parallel.set(true) + parallel = true config.setFrom(provider { staticAnalyzerSpec.configsDir.get().file("detekt/detekt.yml") }) - baseline.set(provider { staticAnalyzerSpec.configsDir.get().file("detekt/baseline.xml") }) + baseline = provider { staticAnalyzerSpec.configsDir.get().file("detekt/baseline.xml") } setSource(projectDir) include("**/*.kt") include("**/*.kts") @@ -203,7 +203,7 @@ private inline fun Project.extractDetektTaskProviderByT val baseExtensions = extensions.getByType() baseExtensions.checkVariantExists(variantName) { existingVariants -> val candidates = existingVariants.joinToString(", ") { variant -> - "'${createDetektVariantTaskName(taskSuffix, variant.capitalize(), "All")}'" + "'${createDetektVariantTaskName(taskSuffix, variant, "All")}'" } "Task ${createDetektVariantTaskName(taskSuffix, variantName, "All")} not found in project. " + "Some candidates are: $candidates" @@ -218,12 +218,12 @@ private inline fun Project.extractDetektTaskProviderByT } private fun BaseExtension.checkVariantExists(variantName: String, lazyMessage: (List) -> String) { - val requiredVariant = variants?.find { it.name.capitalize() == variantName } + val requiredVariant = variants?.find { it.name.capitalized() == variantName } checkNotNull(requiredVariant) { lazyMessage.invoke(variants?.map { it.name }.orEmpty()) } } private fun createDetektVariantTaskName(suffix: String, variantName: String, postfix: String = ""): String { - return "detekt$suffix$variantName$postfix" + return "detekt$suffix${variantName.capitalized()}$postfix" } private fun List.checkModulesContainDetekt(lazyMessage: (String) -> String) { diff --git a/infrastructure-detekt/src/main/kotlin/internal/String.kt b/infrastructure-detekt/src/main/kotlin/internal/String.kt new file mode 100644 index 0000000..21abe63 --- /dev/null +++ b/infrastructure-detekt/src/main/kotlin/internal/String.kt @@ -0,0 +1,3 @@ +package com.redmadrobot.build.detekt.internal + +internal fun String.capitalized() = this.replaceFirstChar { it.uppercaseChar() } diff --git a/infrastructure-kotlin/build.gradle.kts b/infrastructure-kotlin/build.gradle.kts index 82cff85..ab50eff 100644 --- a/infrastructure-kotlin/build.gradle.kts +++ b/infrastructure-kotlin/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("gradle-plugin-commons") + convention.plugin } description = "Defaults for Kotlin projects" @@ -25,5 +25,5 @@ gradlePlugin { dependencies { api(projects.infrastructureCommon) - compileOnlyApi(libs.kotlinGradle) // Should be provided by project + compileOnlyApi(libs.kotlinGradle) // Should be provided by a project } diff --git a/infrastructure-kotlin/src/main/kotlin/dsl/Accessors.kt b/infrastructure-kotlin/src/main/kotlin/dsl/Accessors.kt index f82fbe0..2c92738 100644 --- a/infrastructure-kotlin/src/main/kotlin/dsl/Accessors.kt +++ b/infrastructure-kotlin/src/main/kotlin/dsl/Accessors.kt @@ -5,6 +5,10 @@ import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile /** Configures all tasks with type [KotlinCompile]. */ +@Deprecated( + "Use kotlin { ... } or tasks.withType() instead", + ReplaceWith("kotlin(configure)") +) public inline fun Project.kotlinCompile(crossinline configure: KotlinCompile.() -> Unit) { tasks.withType().configureEach { configure() } } diff --git a/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinConfigPlugin.kt b/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinConfigPlugin.kt index aaac4cc..3fbfb23 100644 --- a/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinConfigPlugin.kt +++ b/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinConfigPlugin.kt @@ -3,10 +3,8 @@ package com.redmadrobot.build.kotlin import com.redmadrobot.build.InfrastructurePlugin import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import com.redmadrobot.build.internal.hasPlugin -import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.internal.plugins.PluginRegistry -import org.gradle.api.provider.Provider import javax.inject.Inject /** @@ -23,9 +21,6 @@ public open class KotlinConfigPlugin @Inject constructor( public lateinit var testOptions: TestOptionsImpl private set - internal val jvmTarget: Provider - get() = redmadrobotExtension.jvmTarget - @InternalGradleInfrastructureApi override fun Project.configure() { check(pluginRegistry.hasPlugin("kotlin")) { diff --git a/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinLibraryPlugin.kt b/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinLibraryPlugin.kt index cc06512..63a5329 100644 --- a/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinLibraryPlugin.kt +++ b/infrastructure-kotlin/src/main/kotlin/kotlin/KotlinLibraryPlugin.kt @@ -1,43 +1,37 @@ package com.redmadrobot.build.kotlin -import com.redmadrobot.build.InfrastructurePlugin import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import com.redmadrobot.build.internal.addRepositoriesIfNeed -import com.redmadrobot.build.kotlin.internal.configureKotlin -import com.redmadrobot.build.kotlin.internal.java -import com.redmadrobot.build.kotlin.internal.kotlin import com.redmadrobot.build.kotlin.internal.setTestOptions +import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.testing.Test import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension /** - * Plugin that applies default configurations for Kotlin library project. + * Plugin that applies default configurations for a Kotlin library project. * Should be applied in place of `kotlin` plugin. * * Tied to `com.redmadrobot.kotlin-library` plugin ID. */ -public class KotlinLibraryPlugin : InfrastructurePlugin() { +public class KotlinLibraryPlugin : Plugin { - @InternalGradleInfrastructureApi - override fun Project.configure() { + override fun apply(target: Project) { + target.configure() + } + + @OptIn(InternalGradleInfrastructureApi::class) + private fun Project.configure() { apply(plugin = "kotlin") val configPlugin = plugins.apply(KotlinConfigPlugin::class) // Enable Explicit API mode for libraries by default - kotlin.explicitApi() + kotlinExtension.explicitApi() - configureKotlin(configPlugin.jvmTarget) configureKotlinTest(configPlugin.testOptions) configureRepositories() - - afterEvaluate { - java { - targetCompatibility = configPlugin.jvmTarget.get() - sourceCompatibility = configPlugin.jvmTarget.get() - } - } } } diff --git a/infrastructure-kotlin/src/main/kotlin/kotlin/TestOptions.kt b/infrastructure-kotlin/src/main/kotlin/kotlin/TestOptions.kt index d20ae5a..733d090 100644 --- a/infrastructure-kotlin/src/main/kotlin/kotlin/TestOptions.kt +++ b/infrastructure-kotlin/src/main/kotlin/kotlin/TestOptions.kt @@ -7,12 +7,15 @@ import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions /** Options used to configure tests. */ public interface TestOptions { - /** Flag for using Junit Jupiter Platform. Use functions [useJunit] or [useJunitPlatform]. */ + /** + * Flag for using Junit Jupiter Platform. + * Use functions [useJunitPlatform] and [useJunit] to change it. + */ public val useJunitPlatform: Provider - /** Specifies that JUnit Platform (JUnit 5) should be used to execute the tests. */ + /** Specifies that JUnit Platform (JUnit 5) should be used to execute tests. */ public fun useJunitPlatform(configure: JUnitPlatformOptions.() -> Unit = {}) - /** Specifies that JUnit should be used to execute the tests. */ + /** Specifies that JUnit 4 should be used to execute tests. */ public fun useJunit(configure: JUnitOptions.() -> Unit = {}) } diff --git a/infrastructure-kotlin/src/main/kotlin/kotlin/internal/Kotlin.kt b/infrastructure-kotlin/src/main/kotlin/kotlin/internal/Kotlin.kt deleted file mode 100644 index 2c248ec..0000000 --- a/infrastructure-kotlin/src/main/kotlin/kotlin/internal/Kotlin.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.redmadrobot.build.kotlin.internal - -import com.redmadrobot.build.InfrastructurePlugin -import com.redmadrobot.build.dsl.isRunningOnCi -import com.redmadrobot.build.dsl.kotlinCompile -import com.redmadrobot.build.internal.InternalGradleInfrastructureApi -import com.redmadrobot.build.internal.findBooleanProperty -import org.gradle.api.JavaVersion -import org.gradle.api.Project -import org.gradle.api.provider.Provider - -@InternalGradleInfrastructureApi -public fun InfrastructurePlugin.configureKotlin(jvmTargetProperty: Provider) { - val warningsAsErrors = project.getWarningsAsErrorsProperty() - project.kotlinCompile { - kotlinOptions { - jvmTarget = jvmTargetProperty.get().toString() - allWarningsAsErrors = warningsAsErrors - freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" - } - } -} - -/** Use property value if it exists or fallback to true if running on CI. */ -@OptIn(InternalGradleInfrastructureApi::class) -private fun Project.getWarningsAsErrorsProperty(): Boolean { - return findBooleanProperty("warningsAsErrors") ?: isRunningOnCi -} diff --git a/infrastructure-kotlin/src/main/kotlin/kotlin/internal/KotlinAccessors.kt b/infrastructure-kotlin/src/main/kotlin/kotlin/internal/KotlinAccessors.kt index 07e205a..f8df7fe 100644 --- a/infrastructure-kotlin/src/main/kotlin/kotlin/internal/KotlinAccessors.kt +++ b/infrastructure-kotlin/src/main/kotlin/kotlin/internal/KotlinAccessors.kt @@ -1,17 +1,14 @@ package com.redmadrobot.build.kotlin.internal -import com.redmadrobot.build.InfrastructurePlugin -import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.kotlin.dsl.getByName -import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile internal fun Project.java(configure: JavaPluginExtension.() -> Unit) { extensions.configure("java", configure) } -@InternalGradleInfrastructureApi -public val InfrastructurePlugin.kotlin: KotlinProjectExtension get() = project.kotlin - -internal val Project.kotlin: KotlinProjectExtension get() = extensions.getByName("kotlin") +internal inline fun Project.kotlinCompile(crossinline configure: KotlinJvmCompile.() -> Unit) { + tasks.withType().configureEach { configure() } +} diff --git a/infrastructure-publish/build.gradle.kts b/infrastructure-publish/build.gradle.kts index 964c711..5bdf013 100644 --- a/infrastructure-publish/build.gradle.kts +++ b/infrastructure-publish/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("gradle-plugin-commons") + convention.plugin } description = "Plugin to simplify common publication scenarios." diff --git a/infrastructure-publish/src/main/kotlin/publish/PublishPlugin.kt b/infrastructure-publish/src/main/kotlin/publish/PublishPlugin.kt index dccd60e..c9628fa 100644 --- a/infrastructure-publish/src/main/kotlin/publish/PublishPlugin.kt +++ b/infrastructure-publish/src/main/kotlin/publish/PublishPlugin.kt @@ -1,13 +1,12 @@ package com.redmadrobot.build.publish import com.android.build.api.dsl.LibraryExtension -import com.redmadrobot.build.InfrastructurePlugin import com.redmadrobot.build.dsl.isReleaseVersion -import com.redmadrobot.build.internal.InternalGradleInfrastructureApi import com.redmadrobot.build.publish.internal.isPluginAutomatedPublishing import com.redmadrobot.build.publish.internal.java import com.redmadrobot.build.publish.internal.publishing import com.redmadrobot.build.publish.internal.signing +import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.publish.maven.MavenPublication import org.gradle.kotlin.dsl.* @@ -18,10 +17,13 @@ import org.gradle.plugins.signing.Sign * * Tied to `com.redmadrobot.publish` plugin ID. */ -public open class PublishPlugin : InfrastructurePlugin() { +public open class PublishPlugin : Plugin { - @InternalGradleInfrastructureApi - override fun Project.configure() { + override fun apply(target: Project) { + target.configure() + } + + private fun Project.configure() { apply(plugin = "maven-publish") val configPlugin = plugins.apply(PublishConfigPlugin::class) diff --git a/publish.sh b/publish.sh deleted file mode 100755 index 9fd0701..0000000 --- a/publish.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# TODO: Configure publishing from CI - -set -e - -# Publication to OSSRH should not be run in parallel -./gradlew :infrastructure-common:publish -./gradlew :infrastructure-publish:publish -./gradlew :infrastructure-detekt:publish -./gradlew :infrastructure-kotlin:publish -./gradlew :infrastructure-android:publish - -# Publication to Gradle Plugins Portal -./gradlew publishPlugins diff --git a/samples/android-application-multi/app/build.gradle.kts b/samples/android-application-multi/app/build.gradle.kts index 642e2bf..db4d75e 100644 --- a/samples/android-application-multi/app/build.gradle.kts +++ b/samples/android-application-multi/app/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.redmadrobot.application") + convention.jvm } // Plugin "com.redmadrobot.application" configures build types, SDK versions, proguard and so on. @@ -12,14 +13,14 @@ android { versionCode = 1 versionName = "1.0" // If we need any additional configurations we still can add it. - // For example we need to run instrumentation tests. + // For example, specify instrumentation tests runner. testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } } dependencies { // Align Kotlin version across all dependencies - implementation(platform(kotlin("bom", version = "1.8.10"))) + implementation(platform(kotlin("bom", version = "2.0.0"))) // Kotlin components can be added without version specifying implementation(kotlin("stdlib")) @@ -27,14 +28,14 @@ dependencies { implementation(project(":module1")) implementation(project(":module2")) - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.8.0") + implementation("androidx.appcompat:appcompat:1.7.0") + implementation("com.google.android.material:material:1.12.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("androidx.navigation:navigation-fragment-ktx:2.5.3") - implementation("androidx.navigation:navigation-ui-ktx:2.5.3") + implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") + implementation("androidx.navigation:navigation-ui-ktx:2.7.7") testImplementation(kotlin("test-junit5")) - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") + androidTestImplementation("androidx.test.ext:junit:1.2.1") + androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") } diff --git a/samples/android-application-multi/build.gradle.kts b/samples/android-application-multi/build.gradle.kts index 07f596e..5a0ef82 100644 --- a/samples/android-application-multi/build.gradle.kts +++ b/samples/android-application-multi/build.gradle.kts @@ -1,15 +1,12 @@ plugins { - // Specify needed versions of AGP and KGP - id("com.android.application") version "7.4.2" apply false - kotlin("android") version "1.8.10" apply false - - id("com.redmadrobot.android-config") version "0.18.1" + // Versions of AGP and KGP are specified in buildSrc module + id("com.redmadrobot.android-config") version "0.19" } // Common configurations for all modules redmadrobot { android { - minSdk.set(24) - targetSdk.set(33) + minSdk = 24 + targetSdk = 34 } } diff --git a/samples/android-application-multi/buildSrc/build.gradle.kts b/samples/android-application-multi/buildSrc/build.gradle.kts new file mode 100644 index 0000000..781e848 --- /dev/null +++ b/samples/android-application-multi/buildSrc/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + `kotlin-dsl` +} + +dependencies { + implementation(kotlin("gradle-plugin", version = "2.0.0")) + implementation("com.android.tools.build:gradle:8.5.1") +} diff --git a/samples/android-application-multi/buildSrc/settings.gradle.kts b/samples/android-application-multi/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..e1e9b53 --- /dev/null +++ b/samples/android-application-multi/buildSrc/settings.gradle.kts @@ -0,0 +1,18 @@ +@file:Suppress("UnstableApiUsage") + +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + + repositories { + mavenCentral() + google { + content { + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + includeGroupAndSubgroups("androidx") + } + } + } +} + +rootProject.name = "buildSrc" diff --git a/samples/android-application-multi/buildSrc/src/main/kotlin/convention.jvm.gradle.kts b/samples/android-application-multi/buildSrc/src/main/kotlin/convention.jvm.gradle.kts new file mode 100644 index 0000000..95cc1e3 --- /dev/null +++ b/samples/android-application-multi/buildSrc/src/main/kotlin/convention.jvm.gradle.kts @@ -0,0 +1,4 @@ +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension + +// Align JVM target across all modules +kotlinExtension.jvmToolchain(17) diff --git a/samples/android-application-multi/gradle/wrapper/gradle-wrapper.jar b/samples/android-application-multi/gradle/wrapper/gradle-wrapper.jar index 249e583..2c35211 100644 Binary files a/samples/android-application-multi/gradle/wrapper/gradle-wrapper.jar and b/samples/android-application-multi/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/android-application-multi/gradle/wrapper/gradle-wrapper.properties b/samples/android-application-multi/gradle/wrapper/gradle-wrapper.properties index 59bc51a..09523c0 100644 --- a/samples/android-application-multi/gradle/wrapper/gradle-wrapper.properties +++ b/samples/android-application-multi/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/android-application-multi/gradlew b/samples/android-application-multi/gradlew index a69d9cb..f5feea6 100755 --- a/samples/android-application-multi/gradlew +++ b/samples/android-application-multi/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/master/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/. @@ -80,13 +82,12 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +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 @@ -133,22 +134,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/samples/android-application-multi/gradlew.bat b/samples/android-application-multi/gradlew.bat index f127cfd..9d21a21 100644 --- a/samples/android-application-multi/gradlew.bat +++ b/samples/android-application-multi/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 ########################################################################## @@ -26,6 +28,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -42,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 @@ -56,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/samples/android-application-multi/module1/build.gradle.kts b/samples/android-application-multi/module1/build.gradle.kts index edc112e..19162ee 100644 --- a/samples/android-application-multi/module1/build.gradle.kts +++ b/samples/android-application-multi/module1/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.redmadrobot.android-library") + convention.jvm } android { diff --git a/samples/android-application-multi/module2/build.gradle.kts b/samples/android-application-multi/module2/build.gradle.kts index d422491..92c8b08 100644 --- a/samples/android-application-multi/module2/build.gradle.kts +++ b/samples/android-application-multi/module2/build.gradle.kts @@ -1,8 +1,9 @@ plugins { id("com.redmadrobot.android-library") + convention.jvm } -// Explicit API is enabled by default, but we can disable it if need +// Explicit API is enabled by default, but we can disable it if needed kotlin.explicitApi = null android { diff --git a/samples/android-application-multi/settings.gradle.kts b/samples/android-application-multi/settings.gradle.kts index 9a3c7ee..b362da8 100644 --- a/samples/android-application-multi/settings.gradle.kts +++ b/samples/android-application-multi/settings.gradle.kts @@ -1,10 +1,34 @@ +@file:Suppress("UnstableApiUsage") + pluginManagement { repositories { // If we use SNAPSHOT version of infrastructure, // we should publish it to mavenLocal first mavenLocal() gradlePluginPortal() - google() + google { + content { + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + includeGroupAndSubgroups("androidx") + } + } + } +} + +// Configure repositories for all subprojects in one place +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + + repositories { + google { + content { + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + includeGroupAndSubgroups("androidx") + } + } + mavenCentral() } } diff --git a/samples/android-application/app/build.gradle.kts b/samples/android-application/app/build.gradle.kts index 7b73f9d..b64a153 100644 --- a/samples/android-application/app/build.gradle.kts +++ b/samples/android-application/app/build.gradle.kts @@ -1,6 +1,4 @@ -import com.redmadrobot.build.dsl.BUILD_TYPE_DEBUG -import com.redmadrobot.build.dsl.BUILD_TYPE_QA -import com.redmadrobot.build.dsl.addSharedSourceSetRoot +import com.redmadrobot.build.dsl.* plugins { id("com.redmadrobot.application") @@ -24,24 +22,28 @@ android { // we can add shared source set root. // In this case will be created directory "debugQa" // that will be included to debug and QA source sets. - addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) + sourceSets.addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA) +} + +kotlin { + jvmToolchain(17) } dependencies { // Align Kotlin version across all dependencies - implementation(platform(kotlin("bom", version = "1.8.10"))) + implementation(platform(kotlin("bom", version = "2.0.0"))) // Kotlin components can be added without version specifying implementation(kotlin("stdlib")) - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.8.0") + implementation("androidx.appcompat:appcompat:1.7.0") + implementation("com.google.android.material:material:1.12.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("androidx.navigation:navigation-fragment-ktx:2.5.3") - implementation("androidx.navigation:navigation-ui-ktx:2.5.3") + implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") + implementation("androidx.navigation:navigation-ui-ktx:2.7.7") testImplementation(kotlin("test-junit5")) - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") + androidTestImplementation("androidx.test.ext:junit:1.2.1") + androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") } diff --git a/samples/android-application/build.gradle.kts b/samples/android-application/build.gradle.kts index f252dac..623aa73 100644 --- a/samples/android-application/build.gradle.kts +++ b/samples/android-application/build.gradle.kts @@ -1,7 +1,15 @@ plugins { // Specify needed versions of AGP and KGP - id("com.android.application") version "7.4.2" apply false - kotlin("android") version "1.8.10" apply false + id("com.android.application") version "8.5.1" apply false + kotlin("android") version "2.0.0" apply false - id("com.redmadrobot.android-config") version "0.18.1" + id("com.redmadrobot.android-config") version "0.19" +} + +// Common configurations for all modules +redmadrobot { + android { + minSdk = 21 + targetSdk = 34 + } } diff --git a/samples/android-application/gradle/wrapper/gradle-wrapper.jar b/samples/android-application/gradle/wrapper/gradle-wrapper.jar index c1962a7..2c35211 100644 Binary files a/samples/android-application/gradle/wrapper/gradle-wrapper.jar and b/samples/android-application/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/android-application/gradle/wrapper/gradle-wrapper.properties b/samples/android-application/gradle/wrapper/gradle-wrapper.properties index 0c85a1f..09523c0 100644 --- a/samples/android-application/gradle/wrapper/gradle-wrapper.properties +++ b/samples/android-application/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/android-application/gradlew b/samples/android-application/gradlew index aeb74cb..f5feea6 100755 --- a/samples/android-application/gradlew +++ b/samples/android-application/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/. @@ -83,7 +85,9 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +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 @@ -130,10 +134,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +205,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/samples/android-application/gradlew.bat b/samples/android-application/gradlew.bat index 93e3f59..9d21a21 100644 --- a/samples/android-application/gradlew.bat +++ b/samples/android-application/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/samples/android-application/settings.gradle.kts b/samples/android-application/settings.gradle.kts index b08db50..38c2078 100644 --- a/samples/android-application/settings.gradle.kts +++ b/samples/android-application/settings.gradle.kts @@ -1,10 +1,34 @@ +@file:Suppress("UnstableApiUsage") + pluginManagement { repositories { // If we use SNAPSHOT version of infrastructure, // we should publish it to mavenLocal first mavenLocal() gradlePluginPortal() - google() + google { + content { + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + includeGroupAndSubgroups("androidx") + } + } + } +} + +// Configure repositories for all subprojects in one place +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + + repositories { + google { + content { + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + includeGroupAndSubgroups("androidx") + } + } + mavenCentral() } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 7c1f343..40facc3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,7 +4,7 @@ rootProject.name = "gradle-infrastructure" @Suppress("UnstableApiUsage") dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS repositories { mavenCentral()