diff --git a/.github/scripts/update_versions.sh b/.github/scripts/update_versions.sh new file mode 100644 index 00000000..6ce05972 --- /dev/null +++ b/.github/scripts/update_versions.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Define the initial script directory +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +project_dir="$(dirname "$script_dir")" +project_dir="$(dirname "$project_dir")" +echo "Project script directory: $project_dir" + +# Define the path to the target file +version_file="$project_dir/gradle/libs.versions.toml" + +# Check if the target file exists +if [ -f "$version_file" ]; then + echo "Target file found: $version_file" +else + echo "Target file not found" + exit 1 # Exit the script if the target file is not found +fi + +# Read versionName and versionCode from the file +version_name=$(awk -F '"' '/versionName = "/{print $2}' "$version_file") +version_code=$(awk -F '"' '/versionCode = "/{print $2}' "$version_file") + +# Increment versionCode by 1 +((version_code++)) + +# Increment versionName by 0.01 +version_name=$(echo "$version_name + 0.01" | bc) + +# Update the file with the new version information +sed "s/versionName = \".*\"/versionName = \"$version_name\"/" "$version_file" > "$version_file.tmp" +mv "$version_file.tmp" "$version_file" + +sed "s/versionCode = \".*\"/versionCode = \"$version_code\"/" "$version_file" > "$version_file.tmp" +mv "$version_file.tmp" "$version_file" + +echo "Updated versionName to $version_name and versionCode to $version_code in $version_file" + diff --git a/.github/workflows/android_deploy_beta.yml b/.github/workflows/android_deploy_beta.yml index a95b39c9..961cee2d 100644 --- a/.github/workflows/android_deploy_beta.yml +++ b/.github/workflows/android_deploy_beta.yml @@ -10,15 +10,18 @@ jobs: timeout-minutes: 60 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: | echo "${{ secrets.KEYSTORE }}" > keystore.jks.asc gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch keystore.jks.asc > keystore.jks - - uses: ruby/setup-ruby@v1.152.0 + - name: Update Version + run: bash ./.github/scripts/update_versions.sh + + - uses: ruby/setup-ruby@v1 with: - ruby-version: '2.7.0' + ruby-version: '3.3' - name: Cache Ruby - Bundler uses: actions/cache@v2 @@ -74,4 +77,16 @@ jobs: base64 -d -i play_config.json.b64 > play_config.json - name: Distribute app to Beta track 🚀 - run: bundle exec fastlane beta \ No newline at end of file + run: bundle exec fastlane beta + + - name: Commit files + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -a -m "update version" + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.PUSH_TOKEN }} + branch: ${{ github.ref }} \ No newline at end of file diff --git a/.github/workflows/android_deploy_prod.yml b/.github/workflows/android_deploy_prod.yml index 139880e3..5f7592a4 100644 --- a/.github/workflows/android_deploy_prod.yml +++ b/.github/workflows/android_deploy_prod.yml @@ -10,15 +10,18 @@ jobs: timeout-minutes: 60 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: | echo "${{ secrets.KEYSTORE }}" > keystore.jks.asc gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch keystore.jks.asc > keystore.jks - - uses: ruby/setup-ruby@v1.152.0 + - name: Update Version + run: bash ./.github/scripts/update_versions.sh + + - uses: ruby/setup-ruby@v1 with: - ruby-version: '2.7.0' + ruby-version: '3.3' - name: Cache Ruby - Bundler uses: actions/cache@v2 @@ -74,4 +77,16 @@ jobs: base64 -d -i play_config.json.b64 > play_config.json - name: Distribute app to Beta track 🚀 - run: bundle exec fastlane deploy \ No newline at end of file + run: bundle exec fastlane deploy + + - name: Commit files + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -a -m "update version" + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.PUSH_TOKEN }} + branch: ${{ github.ref }} \ No newline at end of file diff --git a/.github/workflows/android_jobs.yml b/.github/workflows/android_jobs.yml index 0fea3146..9744c1db 100644 --- a/.github/workflows/android_jobs.yml +++ b/.github/workflows/android_jobs.yml @@ -11,33 +11,17 @@ jobs: steps: - name: Checkout branch - uses: actions/checkout@v3 - + uses: actions/checkout@v4 - run: | echo "${{ secrets.KEYSTORE }}" > keystore.jks.asc gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch keystore.jks.asc > keystore.jks - - name: Set up JDK 17 + - name: set up JDK 17 uses: actions/setup-java@v3 with: + java-version: '17' distribution: 'temurin' - java-version: 17 - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Gradle Wrapper Validation - uses: gradle/wrapper-validation-action@v1 - - - name: Cache Gradle - uses: actions/cache@v3.0.2 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle-. + cache: gradle - name: Configure Keystore env: @@ -50,10 +34,25 @@ jobs: echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> keystore.properties echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> keystore.properties - - name: Build application - run: ./gradlew build --full-stacktrace + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: ~/.gradle/caches/ + key: cache-clean-gradle-${{ matrix.os }}-${{ matrix.jdk }} + + - name: Cache Gradle Wrapper + uses: actions/cache@v4 + with: + path: ~/.gradle/wrapper/ + key: cache-clean-wrapper-${{ matrix.os }}-${{ matrix.jdk }} + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew build --full-stacktrace - - name: Test + - name: Junit tests with Gradle run: ./gradlew testDebugUnitTest --full-stacktrace - name: Publish Test Results diff --git a/.github/workflows/testReportJob.yml b/.github/workflows/testReportJob.yml index ace430a1..0f9b710e 100644 --- a/.github/workflows/testReportJob.yml +++ b/.github/workflows/testReportJob.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: | echo "${{ secrets.KEYSTORE }}" > keystore.jks.asc diff --git a/.gitignore b/.gitignore index eda1dc9b..205e52a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,15 @@ *.iml .gradle +.idea +.kotlin /local.properties -/.idea .DS_Store /build /captures .externalNativeBuild .cxx local.properties -keystore.* play_config.* +keystore.* +Gemfile.lock +build diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 75cddfa1..d0098fb8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,5 +13,3 @@ dependencies { implementation(project(":feature:edit")) implementation(project(":feature:edit-label")) } - -android.namespace = "com.stslex93.notes" diff --git a/build-logic/dependencies/build.gradle.kts b/build-logic/dependencies/build.gradle.kts index 3619e43d..f8cae3e1 100644 --- a/build-logic/dependencies/build.gradle.kts +++ b/build-logic/dependencies/build.gradle.kts @@ -5,9 +5,18 @@ plugins { group = "com.stslex93.notes.buildlogic" dependencies { - implementation(libs.android.gradlePlugin) - implementation(libs.kotlin.gradlePlugin) - implementation(libs.kotlin.serialization) + compileOnly(libs.android.gradlePlugin) + compileOnly(libs.kotlin.gradlePlugin) + compileOnly(libs.kotlin.serialization) + compileOnly(libs.composeCompiler.gradlePlugin) + compileOnly(libs.android.tools.common) +} + +tasks { + validatePlugins { + enableStricterValidation = true + failOnWarning = true + } } gradlePlugin { diff --git a/build-logic/dependencies/src/main/kotlin/AndroidApplicationComposePlugin.kt b/build-logic/dependencies/src/main/kotlin/AndroidApplicationComposePlugin.kt index 460083fa..fab26999 100644 --- a/build-logic/dependencies/src/main/kotlin/AndroidApplicationComposePlugin.kt +++ b/build-logic/dependencies/src/main/kotlin/AndroidApplicationComposePlugin.kt @@ -1,3 +1,5 @@ +import AppExt.findPluginId +import AppExt.libs import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import com.stslex93.notes.configureAndroidCompose import org.gradle.api.Plugin @@ -8,6 +10,8 @@ class AndroidApplicationComposePlugin : Plugin { override fun apply(target: Project) { with(target) { pluginManager.apply("com.android.application") + pluginManager.apply(libs.findPluginId("kotlin")) + pluginManager.apply(libs.findPluginId("composeCompiler")) val extension = extensions.getByType() configureAndroidCompose(extension) } diff --git a/build-logic/dependencies/src/main/kotlin/AndroidApplicationPlugin.kt b/build-logic/dependencies/src/main/kotlin/AndroidApplicationPlugin.kt index 15d4ed69..a23cadd4 100644 --- a/build-logic/dependencies/src/main/kotlin/AndroidApplicationPlugin.kt +++ b/build-logic/dependencies/src/main/kotlin/AndroidApplicationPlugin.kt @@ -1,3 +1,7 @@ +import AppExt.APP_PREFIX +import AppExt.findVersionInt +import AppExt.findVersionString +import AppExt.libs import com.android.build.api.dsl.ApplicationExtension import com.stslex93.notes.configureKotlinAndroid import org.gradle.api.Plugin @@ -20,13 +24,13 @@ class AndroidApplicationPlugin : Plugin { extensions.configure { configureKotlinAndroid(this) - namespace = "com.stslex93.notes" + namespace = APP_PREFIX defaultConfig.apply { - applicationId = "com.stslex93.notes" - targetSdk = 34 - versionCode = AppVersion.VERSION_CODE - versionName = AppVersion.VERSION_NAME + applicationId = APP_PREFIX + targetSdk = libs.findVersionInt("targetSdk") + versionName = libs.findVersionString("versionName") + versionCode = libs.findVersionInt("versionCode") signingConfigs { val keystoreProperties = diff --git a/build-logic/dependencies/src/main/kotlin/AndroidLibraryComposePlugin.kt b/build-logic/dependencies/src/main/kotlin/AndroidLibraryComposePlugin.kt index 9fcd55ae..66df44bf 100644 --- a/build-logic/dependencies/src/main/kotlin/AndroidLibraryComposePlugin.kt +++ b/build-logic/dependencies/src/main/kotlin/AndroidLibraryComposePlugin.kt @@ -1,3 +1,5 @@ +import AppExt.findPluginId +import AppExt.libs import com.android.build.api.dsl.LibraryExtension import com.stslex93.notes.configureAndroidCompose import org.gradle.api.Plugin @@ -8,6 +10,8 @@ class AndroidLibraryComposePlugin : Plugin { override fun apply(target: Project) { with(target) { pluginManager.apply("com.android.library") + pluginManager.apply(libs.findPluginId("kotlin")) + pluginManager.apply(libs.findPluginId("composeCompiler")) val extension = extensions.getByType() configureAndroidCompose(extension) } diff --git a/build-logic/dependencies/src/main/kotlin/AppExt.kt b/build-logic/dependencies/src/main/kotlin/AppExt.kt new file mode 100644 index 00000000..f2d012d0 --- /dev/null +++ b/build-logic/dependencies/src/main/kotlin/AppExt.kt @@ -0,0 +1,138 @@ +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType + +object AppExt { + + const val APP_PREFIX = "com.stslex93.notes" + + /** + * Get the version catalog for the project + * */ + val Project.libs: VersionCatalog + get() = extensions.getByType().named("libs") + + /** + * Find the version of the library + */ + fun VersionCatalog.findVersionInt(name: String) = findVersionString(name).toInt() + + /** + * Find the version of the library + */ + fun VersionCatalog.findVersionString(name: String) = findVersion(name).get().toString() + + /** + * Find the plugin id + */ + fun VersionCatalog.findPluginId(alias: String) = findPlugin(alias).get().get().pluginId + + /** + * Find the library by alias + */ + fun Project.implementation(vararg alias: String) { + dependencies { + alias.forEach { + add("implementation", libs.findLibrary(it).get()) + } + } + } + + fun Project.debugImplementation(vararg alias: String) { + dependencies { + alias.forEach { + add("debugImplementation", libs.findLibrary(it).get()) + } + } + } + + fun Project.implementationPlatform(vararg alias: String) { + dependencies { + alias.forEach { + add( + "debugImplementation", + platform(libs.findLibrary(it).get()) + ) + } + } + } + + /** + * Find the bundle by alias + */ + fun Project.implementationBundle(vararg alias: String) { + dependencies { + alias.forEach { + add("implementation", libs.findBundle(it).get()) + } + } + } + + /** + * Find the library by alias + */ + fun Project.androidTestImplementation(vararg alias: String) { + dependencies { + alias.forEach { + add("androidTestImplementation", libs.findLibrary(it).get()) + } + } + } + + /** + * Find the library by alias + */ + fun Project.androidTestImplementationBundle(vararg alias: String) { + dependencies { + alias.forEach { + add("androidTestImplementation", libs.findBundle(it).get()) + } + } + } + + fun Project.androidTestImplementationPlatform(vararg alias: String) { + dependencies { + alias.forEach { + add( + "androidTestImplementation", + dependencies.platform(libs.findLibrary(it).get()) + ) + } + } + } + + /** + * Find the library by alias + */ + fun Project.testImplementationBundle(vararg alias: String) { + dependencies { + alias.forEach { + add("testImplementation", libs.findBundle(it).get()) + } + } + } + + /** + * Find the library by alias + */ + fun Project.coreLibraryDesugaring(vararg alias: String) { + dependencies { + alias.forEach { + add("coreLibraryDesugaring", libs.findLibrary(it).get()) + } + } + } + + /** + * Find the library by alias + */ + fun Project.ksp(vararg alias: String) { + dependencies { + alias.forEach { + add("ksp", libs.findLibrary(it).get()) + } + } + } +} \ No newline at end of file diff --git a/build-logic/dependencies/src/main/kotlin/AppVersion.kt b/build-logic/dependencies/src/main/kotlin/AppVersion.kt deleted file mode 100644 index c6c411fb..00000000 --- a/build-logic/dependencies/src/main/kotlin/AppVersion.kt +++ /dev/null @@ -1,4 +0,0 @@ -object AppVersion { - const val VERSION_CODE = 17 - const val VERSION_NAME = "1.17" -} diff --git a/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/AndroidCompose.kt b/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/AndroidCompose.kt index faefeb43..05b9b2df 100644 --- a/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/AndroidCompose.kt +++ b/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/AndroidCompose.kt @@ -12,17 +12,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile * Configure Compose-specific options */ internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, ) { val libs = extensions.getByType().named("libs") commonExtension.apply { buildFeatures.compose = true - composeOptions.kotlinCompilerExtensionVersion = libs - .findVersion("composeCompiler") - .get() - .toString() dependencies { val composeBom = libs.findLibrary("androidx-compose-bom").get() @@ -56,8 +52,8 @@ internal fun Project.configureAndroidCompose( } tasks.withType().configureEach { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs //+ buildComposeMetricsParameters() + compilerOptions { +// freeCompilerArgs.add(buildComposeMetricsParameters()) } } } diff --git a/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/KotlinAndroid.kt b/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/KotlinAndroid.kt index f62eaad9..74ce54f2 100644 --- a/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/KotlinAndroid.kt +++ b/build-logic/dependencies/src/main/kotlin/com.stslex93.notes/KotlinAndroid.kt @@ -1,6 +1,10 @@ package com.stslex93.notes +import AppExt.APP_PREFIX +import AppExt.findVersionInt +import AppExt.libs import com.android.build.api.dsl.CommonExtension +import com.android.build.gradle.AppExtension import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension @@ -8,30 +12,31 @@ import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile /** * Configure base Kotlin with Android options */ internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *, *>, -) { - commonExtension.apply { + commonExtension: CommonExtension<*, *, *, *, *, *>, +): Unit = with(commonExtension) { - compileSdk = 34 + compileSdk = libs.findVersionInt("compileSdk") - defaultConfig { - minSdk = 28 - buildFeatures.buildConfig = true - } + namespace = getNameSpace(commonExtension) - compileOptions { - // Up to Java 11 APIs are available through desugaring - // https://developer.android.com/studio/write/java11-minimal-support-table - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - isCoreLibraryDesugaringEnabled = true - } + defaultConfig { + minSdk = libs.findVersionInt("minSdk") + buildFeatures.buildConfig = true + } + + compileOptions { + // Up to Java 11 APIs are available through desugaring + // https://developer.android.com/studio/write/java11-minimal-support-table + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + isCoreLibraryDesugaringEnabled = true } configureKotlin() @@ -61,22 +66,29 @@ internal fun Project.configureKotlinAndroid( } } -/** - * Configure base Kotlin options - */ +private fun Project.getNameSpace( + commonExtension: CommonExtension<*, *, *, *, *, *>, +): String { + val isApp = commonExtension is AppExtension + val dropValue = if (isApp) 2 else 1 + val moduleName = path.split(":") + .drop(dropValue) + .joinToString(".") + .replace("-", "_") + return if (moduleName.isNotEmpty()) "$APP_PREFIX.$moduleName" else APP_PREFIX +} + private fun Project.configureKotlin() { // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947 tasks.withType().configureEach { - kotlinOptions { + compilerOptions { // Set JVM target to 11 - jvmTarget = JavaVersion.VERSION_11.toString() + jvmTarget.set(JvmTarget.JVM_17) // Treat all Kotlin warnings as errors (disabled by default) // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties val warningsAsErrors: String? by project - allWarningsAsErrors = warningsAsErrors.toBoolean() - freeCompilerArgs = freeCompilerArgs + listOf( - "-opt-in=kotlin.RequiresOptIn", - ) + allWarningsAsErrors.set(warningsAsErrors?.toBoolean() ?: false) + freeCompilerArgs.addAll("-opt-in=kotlin.RequiresOptIn", "-Xcontext-parameters") } } } \ No newline at end of file diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties index 6977b719..d8e073e8 100644 --- a/build-logic/gradle.properties +++ b/build-logic/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.parallel=true +#org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 882f502b..d5dfd425 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,6 +5,7 @@ plugins { alias(libs.plugins.library) apply false alias(libs.plugins.serialization) alias(libs.plugins.ksp) apply false + alias(libs.plugins.composeCompiler) apply false } buildscript { diff --git a/core/core/build.gradle.kts b/core/core/build.gradle.kts index a06f9992..c9f0fbcd 100644 --- a/core/core/build.gradle.kts +++ b/core/core/build.gradle.kts @@ -1,5 +1,3 @@ plugins { id("notes.android.library") } - -android.namespace = "com.stslex93.notes.core.core" \ No newline at end of file diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 16d4a7da..9237707a 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -15,4 +15,3 @@ ksp { arg("room.schemaLocation", "$projectDir/schemas") } -android.namespace = "com.stslex93.notes.core.database" diff --git a/core/label/build.gradle.kts b/core/label/build.gradle.kts index 4f7076f8..567051c1 100644 --- a/core/label/build.gradle.kts +++ b/core/label/build.gradle.kts @@ -2,8 +2,6 @@ plugins { id("notes.android.library") } -android.namespace = "com.stslex93.notes.core.label" - dependencies { implementation(project(":core:core")) implementation(project(":core:database")) diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts index 58974338..58c6b870 100644 --- a/core/navigation/build.gradle.kts +++ b/core/navigation/build.gradle.kts @@ -7,5 +7,3 @@ dependencies { implementation(project(":core:core")) implementation(project(":core:ui")) } - -android.namespace = "com.stslex93.notes.core.navigation" diff --git a/core/notes/build.gradle.kts b/core/notes/build.gradle.kts index ea0ef913..567051c1 100644 --- a/core/notes/build.gradle.kts +++ b/core/notes/build.gradle.kts @@ -2,8 +2,6 @@ plugins { id("notes.android.library") } -android.namespace = "com.stslex93.notes.core.notes" - dependencies { implementation(project(":core:core")) implementation(project(":core:database")) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 76fc8690..9f66cd29 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -1,6 +1,4 @@ plugins { id("notes.android.library") id("notes.android.library.compose") -} - -android.namespace = "com.stslex93.notes.core.ui" \ No newline at end of file +} \ No newline at end of file diff --git a/feature/edit-label/build.gradle.kts b/feature/edit-label/build.gradle.kts index ddf76f51..40118c48 100644 --- a/feature/edit-label/build.gradle.kts +++ b/feature/edit-label/build.gradle.kts @@ -3,8 +3,6 @@ plugins { id("notes.android.library.compose") } -android.namespace = "com.stslex93.notes.feature.edit_label" - dependencies { implementation(project(":core:core")) implementation(project(":core:ui")) diff --git a/feature/edit-label/src/main/java/com/stslex93/notes/feature/edit_label/ui/EditLabelScreen.kt b/feature/edit-label/src/main/java/com/stslex93/notes/feature/edit_label/ui/EditLabelScreen.kt index e061a56b..0430cf7a 100644 --- a/feature/edit-label/src/main/java/com/stslex93/notes/feature/edit_label/ui/EditLabelScreen.kt +++ b/feature/edit-label/src/main/java/com/stslex93/notes/feature/edit_label/ui/EditLabelScreen.kt @@ -15,8 +15,8 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.Text import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.ElevatedButton import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -145,7 +145,7 @@ fun EditLabelToolbar( onClick = onBackPressed ) { Icon( - imageVector = Icons.Default.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "back", tint = MaterialTheme.colorScheme.onSurface ) diff --git a/feature/edit/build.gradle.kts b/feature/edit/build.gradle.kts index d1d04ae9..40118c48 100644 --- a/feature/edit/build.gradle.kts +++ b/feature/edit/build.gradle.kts @@ -3,8 +3,6 @@ plugins { id("notes.android.library.compose") } -android.namespace = "com.stslex93.notes.feature.edit" - dependencies { implementation(project(":core:core")) implementation(project(":core:ui")) diff --git a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/EditScreen.kt b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/EditScreen.kt index 9da80ece..f5b977ed 100644 --- a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/EditScreen.kt +++ b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/EditScreen.kt @@ -8,12 +8,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material3.Divider +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedCard import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable @@ -25,7 +23,6 @@ import com.stslex93.notes.core.ui.theme.AppDimens import com.stslex93.notes.core.ui.theme.AppTheme import com.stslex93.notes.feature.edit.R import com.stslex93.notes.feature.edit.ui.components.LabelsHeader -import com.stslex93.notes.feature.edit.ui.components.LabelsRow import com.stslex93.notes.feature.edit.ui.model.Label import com.stslex93.notes.feature.edit.ui.model.Note import com.stslex93.notes.feature.edit.ui.store.EditStore @@ -90,7 +87,7 @@ fun EditScreen( onClick = onBackButtonClicked ) { Icon( - imageVector = Icons.Filled.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "return" ) } diff --git a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/components/LabelsRow.kt b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/components/LabelsRow.kt index 020b638a..b990d164 100644 --- a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/components/LabelsRow.kt +++ b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/components/LabelsRow.kt @@ -7,9 +7,10 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Divider +import androidx.compose.material3.DividerDefaults import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedCard import androidx.compose.material3.Text @@ -59,7 +60,7 @@ fun LabelsHeader( AnimatedVisibility( visible = isExpanded ) { - Divider() + HorizontalDivider(Modifier, DividerDefaults.Thickness, DividerDefaults.color) LabelsRow( modifier = Modifier .fillMaxWidth() diff --git a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/init/InitEditScreen.kt b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/init/InitEditScreen.kt index cdee8d5d..bf2e152d 100644 --- a/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/init/InitEditScreen.kt +++ b/feature/edit/src/main/java/com/stslex93/notes/feature/edit/ui/init/InitEditScreen.kt @@ -6,9 +6,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner import com.stslex93.notes.feature.edit.ui.EditNoteViewModel import com.stslex93.notes.feature.edit.ui.EditScreen import com.stslex93.notes.feature.edit.ui.store.EditStore.Action diff --git a/feature/home/build.gradle.kts b/feature/home/build.gradle.kts index e0e32fdc..40118c48 100644 --- a/feature/home/build.gradle.kts +++ b/feature/home/build.gradle.kts @@ -3,8 +3,6 @@ plugins { id("notes.android.library.compose") } -android.namespace = "com.stslex93.notes.feature.home" - dependencies { implementation(project(":core:core")) implementation(project(":core:ui")) diff --git a/feature/home/src/main/java/com/stslex93/notes/feature/home/ui/components/HomeScreenNotes.kt b/feature/home/src/main/java/com/stslex93/notes/feature/home/ui/components/HomeScreenNotes.kt index 7033cb2e..f4407eee 100644 --- a/feature/home/src/main/java/com/stslex93/notes/feature/home/ui/components/HomeScreenNotes.kt +++ b/feature/home/src/main/java/com/stslex93/notes/feature/home/ui/components/HomeScreenNotes.kt @@ -30,7 +30,7 @@ fun HomeScreenNotes( ) { LazyVerticalStaggeredGrid( modifier = modifier, - columns = StaggeredGridCells.Fixed(2) + columns = StaggeredGridCells.Fixed(2), ) { items( count = items.itemCount, @@ -38,7 +38,7 @@ fun HomeScreenNotes( ) { index -> items[index]?.let { item -> HomeScreenItemNote( - modifier = Modifier.animateItemPlacement(), + modifier = Modifier.animateItem(), isSelected = selectedItems.contains(item.id), item = item, onClick = onClick, diff --git a/gradle.properties b/gradle.properties index 98bed167..56231301 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,9 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +#org.gradle.jvmargs=-Xms4g -Xmx18g -Dfile.encoding\=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx18g -XX:+UseG1GC -XX:MaxGCPauseMillis=400 -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx18g -Dfile.encoding=UTF-8 +kotlin.daemon.jvmargs=-Xms2g -Xmx18g # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eefa2099..f885ade4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,38 +1,47 @@ [versions] -androidDesugarJdkLibs = "2.0.3" -kotlin = "1.9.0" -androidGradlePlugin = "8.1.1" - -ktx = "1.10.1" -material = "1.9.0" -appcompat = "1.6.1" -immutableCollection = "0.3.5" -lifecycle = "2.6.1" - -composeCompiler = "1.5.1" -composeBom = "2023.08.00" -composeNavigation = "2.7.0" -accompanist = "0.30.0" -coilCompose = "2.4.0" -paging = "3.2.0" - -room = "2.5.2" -ksp = "1.9.0-1.0.13" -mockito = "2.19.0" - -dagger = "2.48" +androidDesugarJdkLibs = "2.1.5" +kotlin = "2.2.10" +androidGradlePlugin = "8.12.2" +androidTools = "31.12.2" + +minSdk = "28" +targetSdk = "36" +compileSdk = "36" +versionName = "1.18" +versionCode = "18" + +ktx = "1.17.0" +material = "1.12.0" +appcompat = "1.7.1" +immutableCollection = "0.4.0" +lifecycle = "2.9.3" + +composeBom = "2025.08.01" +composeGradle = "1.8.2" +composeNavigation = "2.9.3" +accompanist = "0.36.0" +coilCompose = "2.7.0" +paging = "3.3.6" + +room = "2.7.2" +ksp = "2.2.10-2.0.2" +mockito = "5.19.0" + +dagger = "2.57.1" junit = "4.13.2" -androidxJunit = "1.1.5" -espresso = "3.5.1" -robolectric = "4.9" -androidxTest = "1.5.0" +androidxJunit = "1.3.0" +espresso = "3.7.0" +robolectric = "4.16" +androidxTest = "1.7.0" [libraries] android-desugarJdkLibs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } android-gradlePlugin = { module = "com.android.tools.build:gradle", version.ref = "androidGradlePlugin" } kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } +composeCompiler-gradlePlugin = { group = "org.jetbrains.compose", name = "compose-gradle-plugin", version.ref = "composeGradle" } +android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } kotlinx-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "immutableCollection" } @@ -44,7 +53,7 @@ lifecycle-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel- androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } -androidx-compose-activity = "androidx.activity:activity-compose:1.7.2" +androidx-compose-activity = "androidx.activity:activity-compose:1.10.1" androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-compose-material = { group = "androidx.compose.material", name = "material" } androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } @@ -73,7 +82,7 @@ androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "a androidx-espresso = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" } robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" } androidx-test = { group = "androidx.test", name = "core-ktx", version.ref = "androidxTest" } -coroutine-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version = "1.7.3" } +coroutine-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version = "1.10.2" } androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "room" } @@ -90,6 +99,7 @@ serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref application = { id = "com.android.application", version.ref = "androidGradlePlugin" } library = { id = "com.android.library", version.ref = "androidGradlePlugin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } [bundles] lifecycle = [ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c0..d64cd491 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 2b4d6afd..d4081da4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Tue Jun 15 14:00:18 MSK 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,99 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# 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 +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$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"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the 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. + JAVACMD=java + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +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 fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# 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" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index ac1b06f9..6689b85b 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal