diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 4b7ca3b2..16b4591e 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -16,10 +16,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Decrypt and validate decrypted data env: @@ -36,10 +36,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Decrypt and validate decrypted data env: @@ -79,10 +79,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Decrypt and validate decrypted data env: @@ -97,4 +97,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ matrix.fileName }} - path: ${{ matrix.filePath }} \ No newline at end of file + path: ${{ matrix.filePath }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3c7f2f57..263522d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,10 +14,10 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Decrypt and validate decrypted data env: @@ -52,10 +52,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Decrypt and validate decrypted data env: @@ -64,4 +64,4 @@ jobs: - name: Upload to Google Play run: | - ./gradlew publishGplayReleaseBundle \ No newline at end of file + ./gradlew publishGplayReleaseBundle diff --git a/.gitignore b/.gitignore index 972a6e7a..8693e3e8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ ci.properties project.properties /.project /tmp +.kotlin/ # Clojure .lsp/ diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index c1753f47..00000000 --- a/app/build.gradle +++ /dev/null @@ -1,327 +0,0 @@ -import com.github.triplet.gradle.androidpublisher.ReleaseStatus - -apply from: '../spotless.gradle' -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' -apply plugin: 'kotlin-parcelize' -apply plugin: 'com.github.triplet.play' - -def versionMajor = 1 -def versionMinor = 16 -def versionPatch = 0 - -def formattedVersionCode = (versionMajor * 10000 + versionMinor * 100 + versionPatch).toString() -def formattedVersionName = "${versionMajor}.${versionMinor}.${versionPatch}" - -def DEV_PROPERTIES_FILE = file("../project.properties") -def CI_PROPERTIES_FILE = file("../ci.properties") - -def PROPERTY_KEYSTORE_PASSWORD = 'KEYSTORE_PASSWORD' -def PROPERTY_KEYSTORE_ALIAS = 'KEYSTORE_ALIAS' - -def DEBUG_KEY_PATH = '../keys/debug.keystore' -def RELEASE_KEY_PATH = '../keys/release.keystore' -def PUBLIC_KEY_PATH = '../keys/public.keystore' -def GOOGLE_CLOUD_KEY_PATH = '../keys/google-cloud-key.json' - -def PUBLIC_KEY_PASSWORD = 'abc123' -def PUBLIC_KEY_ALIAS = 'testalias' - -project.ext.customProps = new Properties() -if (DEV_PROPERTIES_FILE.exists()) { - project.ext.customProps.load(new FileInputStream(DEV_PROPERTIES_FILE)) -} -if (CI_PROPERTIES_FILE.exists()) { - project.ext.customProps.load(new FileInputStream(CI_PROPERTIES_FILE)) -} - -String getCustomProperty(String key) { - return project.ext.customProps[key] ?: System.getenv(key) ?: "" -} - -task generateVersionPropertiesFile { - // This task is need only for F-Droid - def PROPERTY_VERSION_CODE = "versionCode" - def PROPERTY_VERSION_NAME = "versionName" - def VERSION_PROPERTIES_FILE = file("../version.properties") - - def versions = new Properties() - if (VERSION_PROPERTIES_FILE.exists()) { - versions.load(new FileInputStream(VERSION_PROPERTIES_FILE)) - } - - if (versions[PROPERTY_VERSION_CODE] != formattedVersionCode - || versions[PROPERTY_VERSION_NAME] != formattedVersionName) { - project.logger.lifecycle("Updating file: version.properties") - - versions.setProperty(PROPERTY_VERSION_CODE, formattedVersionCode) - versions.setProperty(PROPERTY_VERSION_NAME, formattedVersionName) - - versions.store(new BufferedWriter(new FileWriter(VERSION_PROPERTIES_FILE)), - "The content of this file is generated automatically for F-Droid") - } -} - -android { - def ext = rootProject.extensions.ext - - defaultConfig { - namespace 'com.ivanovsky.passnotes' - minSdkVersion ext.android.minSdk - compileSdk ext.android.compileSdk - targetSdkVersion ext.android.targetSdk - versionCode formattedVersionCode.toInteger() - versionName formattedVersionName - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - vectorDrawables.useSupportLibrary true - - project.logger.lifecycle("VersionName: $versionName") - project.logger.lifecycle("VersionCode: $versionCode") - } - - buildFeatures { - compose true - dataBinding true - viewBinding true - buildConfig true - } - - kapt { - arguments { - arg("room.schemaLocation", "$projectDir/schemas") - } - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - androidTest.java.srcDirs += 'src/androidTest/kotlin' - androidTest.assets.srcDirs += 'schemas' - test.java.srcDirs += 'src/test/kotlin' - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - - composeOptions { - kotlinCompilerExtensionVersion "1.5.14" - } - - kotlinOptions { - jvmTarget = JavaVersion.VERSION_17.toString() - } - - signingConfigs { - debug { - if (file(DEBUG_KEY_PATH).exists()) { - storeFile file(DEBUG_KEY_PATH) - } - } - release { - if (file(RELEASE_KEY_PATH).exists()) { - storeFile file(RELEASE_KEY_PATH) - storePassword getCustomProperty(PROPERTY_KEYSTORE_PASSWORD) - keyAlias getCustomProperty(PROPERTY_KEYSTORE_ALIAS) - keyPassword getCustomProperty(PROPERTY_KEYSTORE_PASSWORD) - } else { - // This signing config is used for CI builds on forked repos - storeFile file(PUBLIC_KEY_PATH) - storePassword PUBLIC_KEY_PASSWORD - keyAlias PUBLIC_KEY_ALIAS - keyPassword PUBLIC_KEY_PASSWORD - project.logger.lifecycle('Configure release build with public keystore') - } - } - } - - flavorDimensions "default" - productFlavors { - fdroid { - dimension "default" - } - gplay { - dimension "default" - } - } - - buildTypes { - debug { - debuggable true - minifyEnabled false - versionNameSuffix 'd' - signingConfig signingConfigs.debug - } - automation { - debuggable true - minifyEnabled false - signingConfig signingConfigs.debug - applicationIdSuffix '.automation' - } - release { - debuggable false - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig signingConfigs.release - } - } - - testOptions { - unitTests { - includeAndroidResources = true - } - } - - lintOptions { - checkReleaseBuilds true - abortOnError false - } - - packagingOptions { - exclude "plugin.properties" - } - - preBuild.dependsOn(generateVersionPropertiesFile) -} - -play { - serviceAccountCredentials.set(file(GOOGLE_CLOUD_KEY_PATH)) - track = "internal" - releaseStatus = ReleaseStatus.DRAFT - defaultToAppBundles = true - enabled = true -} - -def koinVersion = '3.5.0' -def roomVersion = '2.6.1' -def lifecycleExtensionVersion = '2.2.0' -def lifecycleVersion = '2.7.0' -def appCompatVersion = '1.7.1' -def androidAnnotationVersion = '1.7.0' -def coroutinesVersion = '1.7.3' -def recyclerViewVersion = '1.3.2' -def materialVersion = '1.9.0' -def constrainLayoutVersion = '2.1.4' -def cardViewVersion = '1.0.0' -def coreKtxVersion = '1.10.1' -def activityKtxVersion = '1.7.2' -def preferenceKtxVersion = '1.2.1' -def biometricVersion = '1.2.0-alpha05' -def liveDataKtxVersion = '2.7.0' - -def okHttpVersion = '4.12.0' -def apacheCommonsLangVersion = '3.13.0' -def sardineAndroidVersion = '0.8' -def ciceroneVersion = '7.1' -def timberVersion = '5.0.1' -def treessenceVersion = '1.0.5' -def kotpassVersion = '0.10.0' -def treeDiffVersion = '0.4.0' -def treeBuilderVersion = '0.4.0' -def fzf4jVersion = '0.2.1' -// More latest version of jgit produce crash on Samsung -def jgitVersion = '6.2.0.202206071550-r' -def totpKtVersion = 'v1.0.0' -def composeIcons = '1.6.8' - -// Test -def jUnitVersion = '4.13.2' -def robolectricVersion = '4.10.3' -def androidXRulesVersion = '1.5.0' -def androidXJunitVersion = '1.1.5' -def mockkVersion = '1.13.8' -def truthVersion = '1.1.5' -def androidXArchVersion = '2.2.0' -def androidXCoreVersion = '1.5.0' - -dependencies { - // Test dependencies - testImplementation "junit:junit:$jUnitVersion" - testImplementation "io.mockk:mockk:$mockkVersion" - testImplementation "com.google.truth:truth:$truthVersion" - testImplementation "androidx.arch.core:core-testing:$androidXArchVersion" - testImplementation "androidx.test:core:$androidXCoreVersion" - testImplementation "org.robolectric:robolectric:$robolectricVersion" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion" - - // Android test dependencies - androidTestImplementation "androidx.test.ext:junit:$androidXJunitVersion" - androidTestImplementation "androidx.test:rules:$androidXRulesVersion" - androidTestImplementation "androidx.room:room-testing:$roomVersion" - androidTestImplementation "com.google.truth:truth:$truthVersion" - androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - - // DI - implementation "io.insert-koin:koin-android:$koinVersion" - implementation "io.insert-koin:koin-core:$koinVersion" -// implementation "io.insert-koin:koin-androidx-viewmodel:$koinVersion" - - // Room - implementation "androidx.room:room-runtime:$roomVersion" - kapt "androidx.room:room-compiler:$roomVersion" - androidTestImplementation "androidx.room:room-testing:$roomVersion" - - // AndroidX libraries - implementation "androidx.appcompat:appcompat:$appCompatVersion" - implementation "com.google.android.material:material:$materialVersion" - implementation "androidx.recyclerview:recyclerview:$recyclerViewVersion" - implementation "androidx.cardview:cardview:$cardViewVersion" - implementation "androidx.annotation:annotation:$androidAnnotationVersion" - implementation "androidx.constraintlayout:constraintlayout:$constrainLayoutVersion" - implementation "androidx.biometric:biometric:$biometricVersion" - implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleExtensionVersion" - implementation "androidx.core:core-ktx:$coreKtxVersion" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:$liveDataKtxVersion" - implementation "androidx.activity:activity-ktx:$activityKtxVersion" - implementation "androidx.preference:preference-ktx:$preferenceKtxVersion" - - // Compose - implementation platform("androidx.compose:compose-bom:2024.02.00") - implementation "androidx.compose.material3:material3" - implementation "androidx.activity:activity-compose" - implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycleVersion" - implementation "androidx.compose.runtime:runtime-livedata" - implementation "androidx.compose.material:material-icons-extended:$composeIcons" - - // Compose preview - implementation "androidx.compose.ui:ui-tooling-preview" - debugImplementation "androidx.compose.ui:ui-tooling" - - //Apache Commons Lang (TODO: remove) - implementation "org.apache.commons:commons-lang3:$apacheCommonsLangVersion" - - // Kotlin - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" - - // OkHttp - implementation "com.squareup.okhttp3:okhttp:$okHttpVersion" - implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion" - - // WebDAV client - implementation "com.github.thegrizzlylabs:sardine-android:$sardineAndroidVersion" - - //Cicerone - implementation "com.github.terrakok:cicerone:$ciceroneVersion" - - // Timber - implementation "com.jakewharton.timber:timber:$timberVersion" - implementation "com.github.bastienpaulfr:Treessence:$treessenceVersion" - - // JGit - implementation "org.eclipse.jgit:org.eclipse.jgit:$jgitVersion" - implementation "org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:$jgitVersion" - - // KeePass - implementation "app.keemobile:kotpass:$kotpassVersion" - implementation "com.github.aivanovski:keepass-tree-diff:$treeDiffVersion" - implementation "com.github.aivanovski:keepass-tree-builder:$treeBuilderVersion" - - // Fuzzy search - implementation "com.github.aivanovski:fzf4j:$fzf4jVersion" - - // TOTP + HOTP - implementation "com.github.robinohs:totp-kt:$totpKtVersion" -} \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 00000000..868f9f14 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,317 @@ +import com.github.triplet.gradle.androidpublisher.ReleaseStatus +import java.io.BufferedWriter +import java.io.FileInputStream +import java.io.FileWriter +import java.util.Properties + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.parcelize) + alias(libs.plugins.play.publisher) + alias(libs.plugins.spotless) + alias(libs.plugins.ksp) + alias(libs.plugins.kotlinSerialization) + alias(libs.plugins.room) +} + +val versionMajor = 1 +val versionMinor = 16 +val versionPatch = 0 + +val formattedVersionCode = (versionMajor * 10000 + versionMinor * 100 + versionPatch).toString() +val formattedVersionName = "$versionMajor.$versionMinor.$versionPatch" + +val devPropertiesFile = file("../project.properties") +val ciPropertiesFile = file("../ci.properties") + +val propertyKeystorePassword = "KEYSTORE_PASSWORD" +val propertyKeystoreAlias = "KEYSTORE_ALIAS" + +val debugKeyPath = "../keys/debug.keystore" +val releaseKeyPath = "../keys/release.keystore" +val publicKeyPath = "../keys/public.keystore" +val googleCloudKeyPath = "../keys/google-cloud-key.json" + +val publicKeyPassword = "abc123" +val publicKeyAlias = "testalias" + +val customProps = Properties().apply { + if (devPropertiesFile.exists()) { + FileInputStream(devPropertiesFile).use(::load) + } + if (ciPropertiesFile.exists()) { + FileInputStream(ciPropertiesFile).use(::load) + } +} + +fun getCustomProperty(key: String): String { + return customProps.getProperty(key) ?: System.getenv(key).orEmpty() +} + +val generateVersionPropertiesFile by tasks.registering { + description = "Generates version.properties for F-Droid." + + doLast { + val propertyVersionCode = "versionCode" + val propertyVersionName = "versionName" + val versionPropertiesFile = file("../version.properties") + + val versions = Properties() + if (versionPropertiesFile.exists()) { + FileInputStream(versionPropertiesFile).use(versions::load) + } + + if ( + versions[propertyVersionCode] != formattedVersionCode || + versions[propertyVersionName] != formattedVersionName + ) { + project.logger.lifecycle("Updating file: version.properties") + + versions.setProperty(propertyVersionCode, formattedVersionCode) + versions.setProperty(propertyVersionName, formattedVersionName) + + BufferedWriter(FileWriter(versionPropertiesFile)).use { + versions.store(it, "The content of this file is generated automatically for F-Droid") + } + } + } +} + +android { + namespace = "com.ivanovsky.passnotes" + compileSdk = 36 + + defaultConfig { + applicationId = "com.ivanovsky.passnotes" + minSdk = 26 + targetSdk = 36 + versionCode = formattedVersionCode.toInt() + versionName = formattedVersionName + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + vectorDrawables { + useSupportLibrary = true + } + + project.logger.lifecycle("VersionName: $versionName") + project.logger.lifecycle("VersionCode: $versionCode") + } + + buildFeatures { + compose = true + dataBinding = true + viewBinding = true + buildConfig = true + } + + kotlin { + compilerOptions { + jvmToolchain(21) + } + } + + room { + schemaDirectory("$projectDir/schemas") + } + + sourceSets { + getByName("main") { + java.srcDir("src/main/kotlin") + } + getByName("androidTest") { + java.srcDir("src/androidTest/kotlin") + assets.srcDir("schemas") + } + getByName("test") { + java.srcDir("src/test/kotlin") + } + } + + signingConfigs { + getByName("debug") { + if (file(debugKeyPath).exists()) { + storeFile = file(debugKeyPath) + } + } + create("release") { + if (file(releaseKeyPath).exists()) { + storeFile = file(releaseKeyPath) + storePassword = getCustomProperty(propertyKeystorePassword) + keyAlias = getCustomProperty(propertyKeystoreAlias) + keyPassword = getCustomProperty(propertyKeystorePassword) + } else { + // This signing config is used for CI builds on forked repos. + storeFile = file(publicKeyPath) + storePassword = publicKeyPassword + keyAlias = publicKeyAlias + keyPassword = publicKeyPassword + project.logger.lifecycle("Configure release build with public keystore") + } + } + } + + flavorDimensions += "default" + productFlavors { + create("fdroid") { + dimension = "default" + } + create("gplay") { + dimension = "default" + } + } + + buildTypes { + debug { + isDebuggable = true + isMinifyEnabled = false + versionNameSuffix = "d" + signingConfig = signingConfigs.getByName("debug") + } + create("automation") { + isDebuggable = true + isMinifyEnabled = false + signingConfig = signingConfigs.getByName("debug") + applicationIdSuffix = ".automation" + } + release { + isDebuggable = false + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + signingConfig = signingConfigs.getByName("release") + } + } + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } + + lint { + checkReleaseBuilds = true + abortOnError = false + } + + packaging { + resources { + excludes += "plugin.properties" + } + } +} + +tasks.named("preBuild") { + dependsOn(generateVersionPropertiesFile) +} + +play { + serviceAccountCredentials.set(file(googleCloudKeyPath)) + track.set("internal") + releaseStatus.set(ReleaseStatus.DRAFT) + defaultToAppBundles.set(true) + enabled.set(true) +} + +spotless { + kotlin { + target("**/*.kt") + ktlint(libs.versions.ktlint.get()).setEditorConfigPath("$projectDir/../.editorconfig") + indentWithSpaces() + trimTrailingWhitespace() + } + + java { + target("**/*.java") + googleJavaFormat().aosp() + removeUnusedImports() + trimTrailingWhitespace() + indentWithSpaces() + } + + format("misc") { + target("**/*.gradle", "**/*.gradle.kts", "**/*.md", "**/.gitignore") + indentWithSpaces() + trimTrailingWhitespace() + } + + format("xml") { + target("**/*.xml") + targetExclude("**/strings.xml") + indentWithSpaces() + trimTrailingWhitespace() + } +} + +dependencies { + testImplementation(libs.junit) + testImplementation(libs.mockk) + testImplementation(libs.truth) + testImplementation(libs.androidx.arch.core.testing) + testImplementation(libs.androidx.test.core) + testImplementation(libs.robolectric) + testImplementation(libs.kotlinx.coroutines.test) + + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.androidx.test.rules) + androidTestImplementation(libs.room.testing) + androidTestImplementation(libs.truth) + androidTestImplementation(libs.kotlin.reflect) + + implementation(libs.koin.android) + implementation(libs.koin.core) + + implementation(libs.room.runtime) + ksp(libs.room.compiler) + androidTestImplementation(libs.room.testing) + + implementation(libs.androidx.appcompat) + implementation(libs.androidx.material) + implementation(libs.androidx.recyclerview) + implementation(libs.androidx.cardview) + implementation(libs.androidx.annotation) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.biometric) + implementation(libs.androidx.lifecycle.extensions) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.livedata.ktx) + implementation(libs.androidx.activity.ktx) + implementation(libs.androidx.preference.ktx) + + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.androidx.compose.runtime.livedata) + implementation(libs.androidx.compose.material.icons.extended) + + implementation(libs.androidx.compose.ui.tooling.preview) + debugImplementation(libs.androidx.compose.ui.tooling) + + implementation(libs.apache.commons.lang3) + implementation(libs.kotlin.stdlib) + implementation(libs.kotlin.reflect) + implementation(libs.kotlinx.coroutines.android) + + implementation(libs.okhttp) + implementation(libs.okhttp.logging.interceptor) + + implementation(libs.sardine.android) + + implementation(libs.cicerone) + + implementation(libs.timber) + implementation(libs.treessence) + + implementation(libs.jgit) + implementation(libs.jgit.ssh.jsch) + + implementation(libs.kotpass) + implementation(libs.keepass.tree.diff) + implementation(libs.keepass.tree.builder) + + implementation(libs.fzf4j) + + implementation(libs.totp.kt) +} diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Buttons.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Buttons.kt index d7c515a7..3af99bba 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Buttons.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Buttons.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size -import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -31,7 +31,7 @@ fun ImageButton( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = false), + indication = ripple(bounded = false), onClick = onClick ) ) { diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/TextField.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/TextField.kt index e5fdd9f7..78b83b6c 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/TextField.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/TextField.kt @@ -5,12 +5,12 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextFieldColors import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -102,7 +102,7 @@ fun AppTextField( modifier = Modifier .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = false) + indication = ripple(bounded = false) ) { onPasswordToggleClicked?.invoke() } diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/util/StringExt.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/util/StringExt.kt index 0fbadb4e..cb924d23 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/util/StringExt.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/util/StringExt.kt @@ -98,7 +98,7 @@ fun String.toUUID(): UUID? { } private fun Char.isHex(): Boolean { - return isDigit() || (toLowerCase() in 'a'..'f') + return isDigit() || (lowercaseChar() in 'a'..'f') } // parses string containing date "2020-02-18" diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 3818ca76..00000000 --- a/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - mavenCentral() - google() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } - } - dependencies { - apply from: 'config.gradle' - classpath "com.android.tools.build:gradle:$gradlePluginVersion" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" - classpath "com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion" - classpath "com.github.triplet.gradle:play-publisher:$playPublisherVersion" - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - mavenCentral() - google() - maven { url 'https://jitpack.io' } - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..342efcae --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,7 @@ +subprojects { + repositories { + google() + mavenCentral() + maven("https://jitpack.io") + } +} \ No newline at end of file diff --git a/config.gradle b/config.gradle deleted file mode 100644 index d869beb5..00000000 --- a/config.gradle +++ /dev/null @@ -1,13 +0,0 @@ -ext { - android = [ - minSdk : 26, - targetSdk : 36, - compileSdk: 36 - ] - - kotlinVersion = '1.9.24' - gradlePluginVersion = '8.2.2' - playPublisherVersion = '3.9.1' - spotlessVersion = '6.22.0' - ktlintVersion = '0.48.2' -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..d3afc8ee --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,120 @@ +[versions] +androidGradlePlugin = "8.11.1" +kotlin = "2.2.0" +ksp = "2.2.0-2.0.2" +playPublisher = "3.9.1" +spotless = "6.22.0" +ktlint = "0.48.2" +koin = "3.5.0" +room = "2.8.4" +serializationJson = "1.9.0" +lifecycleExtensions = "2.2.0" +lifecycle = "2.7.0" +appCompat = "1.7.1" +androidAnnotation = "1.7.0" +coroutines = "1.7.3" +recyclerView = "1.3.2" +material = "1.9.0" +constraintLayout = "2.1.4" +cardView = "1.0.0" +coreKtx = "1.10.1" +activityKtx = "1.7.2" +preferenceKtx = "1.2.1" +biometric = "1.2.0-alpha05" +liveDataKtx = "2.7.0" +composeBom = "2026.01.01" +composeIcons = "1.6.8" + +okHttp = "4.12.0" +apacheCommonsLang = "3.13.0" +sardineAndroid = "0.8" +cicerone = "7.1" +timber = "5.0.1" +treessence = "1.0.5" +kotpass = "0.10.0" +treeDiff = "0.4.0" +treeBuilder = "0.4.0" +fzf4j = "0.2.1" +# More recent versions of JGit crash on Samsung devices. +jgit = "6.2.0.202206071550-r" +totpKt = "v1.0.0" + +junit = "4.13.2" +robolectric = "4.10.3" +androidXRules = "1.5.0" +androidXJunit = "1.1.5" +mockk = "1.13.8" +truth = "1.1.5" +androidXArch = "2.2.0" +androidXCore = "1.5.0" + +[plugins] +android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } +kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +play-publisher = { id = "com.github.triplet.play", version.ref = "playPublisher" } +spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +room = { id = "androidx.room", version.ref = "room" } + +[libraries] +junit = { module = "junit:junit", version.ref = "junit" } +mockk = { module = "io.mockk:mockk", version.ref = "mockk" } +truth = { module = "com.google.truth:truth", version.ref = "truth" } +androidx-arch-core-testing = { module = "androidx.arch.core:core-testing", version.ref = "androidXArch" } +androidx-test-core = { module = "androidx.test:core", version.ref = "androidXCore" } +robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } + +androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidXJunit" } +androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidXRules" } + +koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" } +koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } + +room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } +room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } +room-testing = { module = "androidx.room:room-testing", version.ref = "room" } + +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appCompat" } +androidx-material = { module = "com.google.android.material:material", version.ref = "material" } +androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerView" } +androidx-cardview = { module = "androidx.cardview:cardview", version.ref = "cardView" } +androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidAnnotation" } +androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintLayout" } +androidx-biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" } +androidx-lifecycle-extensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "lifecycleExtensions" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } +androidx-lifecycle-livedata-ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "liveDataKtx" } +androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activityKtx" } +androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version.ref = "preferenceKtx" } + +androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" } +androidx-compose-material3 = { module = "androidx.compose.material3:material3" } +androidx-activity-compose = { module = "androidx.activity:activity-compose" } +androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" } +androidx-compose-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata" } +androidx-compose-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "composeIcons" } +androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } +androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } + +apache-commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "apacheCommonsLang" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } +kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okHttp" } +okhttp-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okHttp" } +sardine-android = { module = "com.github.thegrizzlylabs:sardine-android", version.ref = "sardineAndroid" } +cicerone = { module = "com.github.terrakok:cicerone", version.ref = "cicerone" } +timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } +treessence = { module = "com.github.bastienpaulfr:Treessence", version.ref = "treessence" } +jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "jgit" } +jgit-ssh-jsch = { module = "org.eclipse.jgit:org.eclipse.jgit.ssh.jsch", version.ref = "jgit" } +kotpass = { module = "app.keemobile:kotpass", version.ref = "kotpass" } +keepass-tree-diff = { module = "com.github.aivanovski:keepass-tree-diff", version.ref = "treeDiff" } +keepass-tree-builder = { module = "com.github.aivanovski:keepass-tree-builder", version.ref = "treeBuilder" } +fzf4j = { module = "com.github.aivanovski:fzf4j", version.ref = "fzf4j" } +totp-kt = { module = "com.github.robinohs:totp-kt", version.ref = "totpKt" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..e8c6bf7b 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 1af9e093..0d4172f1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ +#Fri Feb 12 23:07:24 MSK 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip -networkTimeout=10000 -validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip diff --git a/gradlew b/gradlew index 1aa94a42..97fac783 100755 --- a/gradlew +++ b/gradlew @@ -1,127 +1,74 @@ -#!/bin/sh - -# -# 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. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# +#!/usr/bin/env bash ############################################################################## -# -# 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/. -# +## +## Gradle start up script for UN*X +## ############################################################################## -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -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 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" -# 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 +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum +MAX_FD="maximum" -warn () { +warn ( ) { echo "$*" -} >&2 +} -die () { +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 ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +# 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 +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. 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 @@ -130,120 +77,84 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - 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. + 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. 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 +if [ "$cygwin" = "false" -a "$darwin" = "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 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" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) +# 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 +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; 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 # Now convert the arguments - kludge to limit ourselves to /bin/sh - 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" ) + 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\"" fi - # 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 + i=$((i+1)) 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 +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" -# 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" "$@" +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat index 6689b85b..aec99730 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,20 +1,4 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off +@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -24,24 +8,20 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused +if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute +if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -55,7 +35,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto execute +if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -65,26 +45,44 @@ echo location of your Java installation. goto fail +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd +if "%ERRORLEVEL%"=="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! -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% +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/scripts/assemble.rb b/scripts/assemble.rb deleted file mode 100755 index 9f220366..00000000 --- a/scripts/assemble.rb +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env ruby - -DEBUG_GPLAY_APK_PATH = 'app/build/outputs/apk/gplay/debug/app-gplay-debug.apk'.freeze -RELEASE_GPLAY_APK_PATH = 'app/build/outputs/apk/gplay/release/app-gplay-release.apk'.freeze -RELEASE_GPLAY_AAB_PATH = 'app/build/outputs/bundle/gplayRelease/app-gplay-release.aab'.freeze - -DEBUG_FDROID_APK_PATH = 'app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk'.freeze -RELEASE_FDROID_APK_PATH = 'app/build/outputs/apk/fdroid/release/app-fdroid-release.apk'.freeze - -def project_directory? - `pwd | awk -F'/' '{print $NF}'`.strip == 'keepassvault' -end - -def dir_path - `pwd`.strip -end - -def check_conditions - if ARGV.empty? - puts 'Please specify output path' - exit 1 - end - - unless project_directory? - puts 'Script should be launched from project root' - exit 1 - end -end - -def remove_files(files) - files.each do |file| - if File.exist? file - puts "Removing file: #{file}" - `rm #{file}` - end - end -end - -def copy_files(sources, destinations) - for i in 0..(sources.size - 1) do - puts "Copying file to: #{destinations[i]}" - `cp "#{sources[i]}" "#{destinations[i]}"` - end -end - -def exists?(files) - files.all? { |file| File.exist? file } -end - -def get_app_version - major = `cat app/build.gradle | grep 'def versionMajor' | cut -d= -f2`.strip - minor = `cat app/build.gradle | grep 'def versionMinor' | cut -d= -f2`.strip - patch = `cat app/build.gradle | grep 'def versionPatch' | cut -d= -f2`.strip - "#{major}.#{minor}.#{patch}" -end - -def assemble - puts 'Assembling Gplay Debug...' - `./gradlew app:assembleGplayDebug` - - puts 'Assembling Gplay Release...' - `./gradlew app:assembleGplayRelease` - - puts 'Assembling Bundle Gplay Release...' - `./gradlew app:bundleGplayRelease` - - puts 'Assembling FDroid Debug...' - `./gradlew app:assembleFdroidDebug` - - puts 'Assembling FDroid Release...' - `./gradlew app:assembleFdroidRelease` -end - -def main - check_conditions - - files = [ - "#{dir_path}/#{DEBUG_GPLAY_APK_PATH}", - "#{dir_path}/#{RELEASE_GPLAY_APK_PATH}", - "#{dir_path}/#{RELEASE_GPLAY_AAB_PATH}", - "#{dir_path}/#{DEBUG_FDROID_APK_PATH}", - "#{dir_path}/#{RELEASE_FDROID_APK_PATH}", - ] - - remove_files(files) - assemble - - if exists?(files) - puts 'Success' - output_dir = ARGV[0].strip.gsub('~', '$HOME') - version = get_app_version - destinations = [ - "#{output_dir}/keepassvault-gplay-debug-#{version}.apk", - "#{output_dir}/keepassvault-gplay-release-#{version}.apk", - "#{output_dir}/keepassvault-gplay-release-#{version}.aab", - "#{output_dir}/keepassvault-fdroid-debug-#{version}.apk", - "#{output_dir}/keepassvault-fdroid-release-#{version}.apk", - ] - copy_files(files, destinations) - else - puts 'Failed' - end -end - -main diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index e7b4def4..00000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..721ced1e --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = "KeePassVault" +include(":app") diff --git a/spotless.gradle b/spotless.gradle deleted file mode 100644 index 40b2d623..00000000 --- a/spotless.gradle +++ /dev/null @@ -1,31 +0,0 @@ -apply plugin: 'com.diffplug.spotless' - -spotless { - kotlin { - target '**/*.kt' - ktlint("$ktlintVersion").setEditorConfigPath("$projectDir/../.editorconfig") - indentWithSpaces() - trimTrailingWhitespace() - } - - java { - target '**/*.java' - googleJavaFormat().aosp() - removeUnusedImports() - trimTrailingWhitespace() - indentWithSpaces() - } - - format 'misc', { - target '**/*.gradle', '**/*.md', '**/.gitignore' - indentWithSpaces() - trimTrailingWhitespace() - } - - format 'xml', { - target '**/*.xml' - targetExclude '**/strings.xml' - indentWithSpaces() - trimTrailingWhitespace() - } -}