diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 4ebf69e81..000000000 --- a/app/build.gradle +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2021 The Hydra authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -apply plugin: 'com.android.application' -apply plugin: 'be.ugent.zeus.hydra.licenses' -apply plugin: 'com.google.gms.google-services' -apply plugin: 'com.google.firebase.crashlytics' - -// Read our properties, see bottom for details. -def props = loadProperties() -def versions = loadAndroidVersions() - -android { - // We need this for Nix flakes - //noinspection GrDeprecatedAPIUsage - buildToolsVersion versions.buildToolsVersions - - defaultConfig { - compileSdk versions.platformVersions as Integer - - applicationId "be.ugent.zeus.hydra" - minSdk 21 - targetSdk 34 - versionCode 37300 - versionName "3.7.3" - vectorDrawables.useSupportLibrary = true - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - resourceConfigurations += ['nl', 'en'] - - // For a description of what these do, see the config.properties file. - buildConfigField "boolean", "DEBUG_HOME_STREAM_PRIORITY", props.getProperty('hydra.debug.home.stream.priority') - buildConfigField "boolean", "DEBUG_HOME_STREAM_STALL", props.getProperty('hydra.debug.home.stream.stall') - buildConfigField "boolean", "DEBUG_ENABLE_STRICT_MODE", props.getProperty('hydra.debug.strict_mode') - buildConfigField "boolean", "DEBUG_ENABLE_ALL_SPECIALS", props.getProperty('hydra.debug.home.stream.specials') - buildConfigField "boolean", "DEBUG_TRACK_LEAKS", props.getProperty("hydra.debug.leaks") - buildConfigField "boolean", "DEBUG_ENABLE_REPORTING", props.getProperty("hydra.debug.reporting") - - // used by Room, to test migrations - javaCompileOptions { - annotationProcessorOptions { - arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] - } - } - } - - - if (props["signing"]) { - signingConfigs { - upload { - keyAlias "upload" - keyPassword props['keyPassword'] - storeFile file(props['storeFile']) - storePassword props['storePassword'] - v1SigningEnabled true - v2SigningEnabled true - } - } - } - - flavorDimensions = ["distribution"] - - productFlavors { - // Play Store and officially supported version - store { - isDefault = true - manifestPlaceholders = [ - google_maps_key: props.getProperty('mapsApiKey'), - ] - } - - open { - ext.enableCrashlytics = false - versionNameSuffix "-open" - applicationIdSuffix ".open" - firebaseCrashlytics { - mappingFileUploadEnabled false - } - } - } - - // used by Room, to test migrations - sourceSets { - test.resources.srcDirs += files("$projectDir/schemas".toString()) - } - - compileOptions { - coreLibraryDesugaringEnabled true - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - if (props["signing"]) { - signingConfig signingConfigs.upload - } - } - - debug { - // Disable crashlytics in debug builds if necessary. - ext.enableCrashlytics = Boolean.parseBoolean(props.getProperty("hydra.debug.reporting")) -// testCoverageEnabled true - } - } - - testOptions { - unitTests { - includeAndroidResources = true - returnDefaultValues = true - } - unitTests.all { - systemProperty 'robolectric.logging.enabled', 'true' - } - } - - buildFeatures { - viewBinding = true - buildConfig = true - } - - packagingOptions { - resources { - excludes += [ - 'META-INF/ASL2.0', - 'META-INF/LICENSE', - 'META-INF/DEPENDENCIES.txt', - 'META-INF/DEPENDENCIES', - 'META-INF/dependencies.txt', - 'META-INF/LICENSE.txt', - 'META-INF/LICENSE', - 'META-INF/license.txt', - 'META-INF/LGPL2.1', - 'META-INF/NOTICE.txt', - 'META-INF/NOTICE', - 'META-INF/notice.txt' - ] - } - } - - namespace 'be.ugent.zeus.hydra' - - lint { - disable 'RtlSymmetry', 'VectorPath', 'Overdraw', 'GradleDependency', 'NotificationPermission', 'OldTargetApi' - showAll true - warningsAsErrors true - } -} - -dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.2' - - implementation 'androidx.core:core:1.13.1' - implementation 'androidx.media:media:1.7.0' - implementation 'androidx.fragment:fragment:1.8.3' - implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'androidx.preference:preference:1.2.1' - implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.3.2' - implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'com.google.android.material:material:1.12.0' - implementation 'androidx.browser:browser:1.8.0' - implementation 'androidx.lifecycle:lifecycle-viewmodel:2.8.6' - implementation 'androidx.lifecycle:lifecycle-livedata:2.8.5' - implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.6' - implementation 'androidx.viewpager2:viewpager2:1.1.0' - implementation 'androidx.room:room-runtime:2.6.1' - annotationProcessor 'androidx.room:room-compiler:2.6.1' - implementation 'com.artemzin.rxjava:proguard-rules:1.3.3.0' - implementation 'com.squareup.okhttp3:okhttp:4.12.0' - implementation 'com.squareup.moshi:moshi:1.15.1' - implementation 'com.squareup.picasso:picasso:2.8' - implementation 'com.github.cachapa:ExpandableLayout:2.9.2' - implementation project(":material-intro") - implementation 'com.github.jonfinerty:Once:19fa6fa10d' - implementation 'com.github.esnaultdev:MaterialValues:v1.1.1' - implementation 'dev.chrisbanes.insetter:insetter:0.6.1' - implementation 'com.github.niqdev:ipcam-view:2.4.1' - - annotationProcessor 'io.soabase.record-builder:record-builder-processor:42' - compileOnly 'io.soabase.record-builder:record-builder-core:42' - - // Dependencies for the Play Store version. - storeImplementation 'com.google.android.gms:play-services-maps:19.0.0' - storeImplementation 'com.google.firebase:firebase-analytics:22.1.0' - storeImplementation 'com.google.firebase:firebase-crashlytics:19.2.0' - storeImplementation 'com.google.android.gms:play-services-code-scanner:16.1.0' - - // Dependencies for open version. - openImplementation 'org.osmdroid:osmdroid-android:6.1.20' - openImplementation 'com.journeyapps:zxing-android-embedded:4.3.0' - - if (props.getProperty("hydra.debug.leaks").toBoolean()) { - logger.info("Leak tracking enabled...") - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14' - } - - testImplementation 'junit:junit:4.13.2' - // Once final classes can be mocked, go back to mockito-core. - testImplementation 'org.mockito:mockito-inline:5.2.0' - testImplementation 'org.robolectric:robolectric:4.13' - testImplementation 'androidx.test:core:1.6.1' - testImplementation 'androidx.test.ext:junit:1.2.1' - testImplementation 'androidx.test:rules:1.6.1' - testImplementation 'androidx.test.espresso:espresso-core:3.6.1' - testImplementation 'androidx.test.espresso:espresso-intents:3.6.1' - testImplementation 'androidx.test.espresso:espresso-contrib:3.6.1' - testImplementation 'androidx.arch.core:core-testing:2.2.0' - testImplementation 'androidx.room:room-testing:2.6.1' - testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0' - testImplementation 'nl.jqno.equalsverifier:equalsverifier:3.17' - testImplementation 'com.shazam:shazamcrest:0.11' - testImplementation 'org.skyscreamer:jsonassert:1.5.3' - testImplementation 'com.github.niknetniko:easy-random:master-SNAPSHOT' - testImplementation 'org.apache.commons:commons-lang3:3.17.0' - testImplementation 'commons-validator:commons-validator:1.9.0' - testImplementation 'com.google.guava:guava:33.3.1-jre' -} - - -// Disable Google services for open variant. -android.applicationVariants.configureEach { variant -> - tasks.named("process${variant.name.capitalize()}GoogleServices").configure { - it.enabled = "open" != variant.flavorName - } -} - -/** - * Loads the default properties, and the user properties. This will also load the - * secret keys. - */ -def loadProperties() { - // Load the default properties. - def defaultProps = new Properties() - defaultProps.load(file("config.properties").newReader()) - - // Load custom properties if available - def customProps = new Properties(defaultProps) - def customFile = file("custom-config.properties") - if (customFile.exists()) { - customProps.load(customFile.newReader()) - } else { - logger.info('No custom-config.properties file was found.') - } - - // Load the secret example secret keys. - def exampleKeys = new Properties(customProps) - exampleKeys.load(file('secrets.properties.example').newReader()) - - // Load the actual keys if present - def actualKeys = new Properties(exampleKeys) - def actualKeyFile = file('secrets.properties') - if (actualKeyFile.exists()) { - actualKeys.load(actualKeyFile.newReader()) - } else { - logger.warn('A secrets.properties file was not found.') - } - - return actualKeys -} - -/** - * Loads the default properties, and the user properties. This will also load the - * secret keys. - */ -def loadAndroidVersions() { - def defaultProps = new Properties() - defaultProps.load(file("../android-versions.toml").newReader()) - - def strippedProps = new Properties() - for (e in defaultProps) { - strippedProps.setProperty(e.key, e.value.replaceAll('"', '')) - } - - return strippedProps -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 000000000..4f4ef23f4 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2021 The Hydra authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +import java.util.Properties +import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension +import com.google.gms.googleservices.GoogleServicesPlugin +import java.io.FileInputStream + +plugins { + id(libs.plugins.android.build.tool.get().pluginId) + id("be.ugent.zeus.hydra.licenses") + alias(libs.plugins.gms) + alias(libs.plugins.firebase.crashlytics.gradle) +} + +// Read our properties, see bottom for details. +val props = loadProperties() +val versions = loadAndroidVersions() + +android { + namespace = "be.ugent.zeus.hydra" + + // We need this for Nix flakes + buildToolsVersion = versions.getProperty("buildToolsVersions") + + defaultConfig { + compileSdk = versions.getProperty("platformVersions").toInt() + applicationId = "be.ugent.zeus.hydra" + minSdk = 21 + targetSdk = 34 + versionCode = 37300 + versionName = "3.7.3" + vectorDrawables.useSupportLibrary = true + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + resourceConfigurations += listOf("nl", "en") + + // For a description of what these do, see the config.properties file. + buildConfigField("boolean", "DEBUG_HOME_STREAM_PRIORITY", props.getProperty("hydra.debug.home.stream.priority")) + buildConfigField("boolean", "DEBUG_HOME_STREAM_STALL", props.getProperty("hydra.debug.home.stream.stall")) + buildConfigField("boolean", "DEBUG_ENABLE_STRICT_MODE", props.getProperty("hydra.debug.strict_mode")) + buildConfigField("boolean", "DEBUG_ENABLE_ALL_SPECIALS", props.getProperty("hydra.debug.home.stream.specials")) + buildConfigField("boolean", "DEBUG_TRACK_LEAKS", props.getProperty("hydra.debug.leaks")) + buildConfigField("boolean", "DEBUG_ENABLE_REPORTING", props.getProperty("hydra.debug.reporting")) + + // used by Room, to test migrations + javaCompileOptions { + annotationProcessorOptions { + argument("room.schemaLocation", "$projectDir/schemas") + } + } + } + + + if (props.getProperty("signing").toBoolean()) { + signingConfigs { + create("upload") { + keyAlias = "upload" + keyPassword = props.getProperty("keyPassword") + storeFile = file(props.getProperty("storeFile")) + storePassword = props.getProperty("storePassword") + enableV1Signing = true + enableV2Signing = true + } + } + } + + flavorDimensions += "distribution" + + productFlavors { + // Play Store and officially supported version + create("store") { + isDefault = true + manifestPlaceholders["google_maps_key"] = props.getProperty("mapsApiKey", "") + } + + create("open") { + extra["enableCrashlytics"] = false + versionNameSuffix = "-open" + applicationIdSuffix = ".open" + configure { + mappingFileUploadEnabled = false + } + } + } + + // used by Room, to test migrations + sourceSets.getByName("test") { + resources.srcDir(files("$projectDir/schemas")) + } + + compileOptions { + isCoreLibraryDesugaringEnabled = true + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + buildTypes { + getByName("release") { + isMinifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + if (props.getProperty("signing").toBoolean()) { + signingConfig = signingConfigs.getByName("upload") + } + } + + getByName("debug") { + // Disable crashlytics in debug builds if necessary. + configure { + mappingFileUploadEnabled = false + } + isDebuggable = true + } + } + + @Suppress("UnstableApiUsage") + testOptions { + unitTests { + isIncludeAndroidResources = true + isReturnDefaultValues = true + } + unitTests.all { + it.systemProperty("robolectric.logging.enabled", "true") + } + } + + buildFeatures { + viewBinding = true + buildConfig = true + } + + packaging { + resources { + excludes += listOf( + "META-INF/ASL2.0", + "META-INF/LICENSE", + "META-INF/DEPENDENCIES.txt", + "META-INF/DEPENDENCIES", + "META-INF/dependencies.txt", + "META-INF/LICENSE.txt", + "META-INF/LICENSE", + "META-INF/license.txt", + "META-INF/LGPL2.1", + "META-INF/NOTICE.txt", + "META-INF/NOTICE", + "META-INF/notice.txt" + ) + } + } + + lint { + disable += listOf( + "RtlSymmetry", "VectorPath", "Overdraw", "GradleDependency", "NotificationPermission", "OldTargetApi", "AndroidGradlePluginVersion" + ) + showAll = true + warningsAsErrors = true + } +} + +dependencies { + coreLibraryDesugaring(libs.desugar) + + implementation(libs.androidx.core) + implementation(libs.androidx.media) + implementation(libs.androidx.fragment) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.preference) + implementation(libs.androidx.cardview) + implementation(libs.androidx.recyclerview) + implementation(libs.androidx.swiperefreshlayout) + implementation(libs.androidx.constraintlayout) + implementation(libs.material) + implementation(libs.androidx.browser) + implementation(libs.bundles.androidx.lifecycle) + implementation(libs.androidx.viewpager2) + implementation(libs.androidx.room.runtime) + annotationProcessor(libs.androidx.room.compiler) + implementation(libs.rxjava.rules) + implementation(libs.okhttp3) + implementation(libs.moshi) + implementation(libs.picasso) + implementation(libs.cachapa) + implementation(project(":material-intro")) + implementation(libs.once) + implementation(libs.materialvalues) + implementation(libs.insetter) + implementation(libs.ipcam) + + annotationProcessor(libs.recordbuilder.processor) + compileOnly(libs.recordbuilder.core) + + // Dependencies for the Play Store version. + "storeImplementation"(libs.play.maps) + "storeImplementation"(libs.firebase.analytics) + "storeImplementation"(libs.firebase.crashlytics) + "storeImplementation"(libs.play.codescanner) + + // Dependencies for open version. + "openImplementation"(libs.osmdroid) + "openImplementation"(libs.zxing) + + if (props.getProperty("hydra.debug.leaks").toBoolean()) { + logger.info("Leak tracking enabled...") + debugImplementation(libs.leakcanary) + } + + testImplementation(libs.junit) + // Once final classes can be mocked, go back to mockito-core. + testImplementation(libs.mockito.inline) + testImplementation(libs.robolectric) + testImplementation(libs.androidx.test.core) + testImplementation(libs.androidx.junit) + testImplementation(libs.androidx.rules) + testImplementation(libs.androidx.espresso.core) + testImplementation(libs.androidx.espresso.intents) + testImplementation(libs.androidx.espresso.contrib) + testImplementation(libs.androidx.core.testing) + testImplementation(libs.androidx.room.testing) + testImplementation(libs.okhttp3.mockwebserver) + testImplementation(libs.equalsverifier) + testImplementation(libs.shazamcrest) + testImplementation(libs.jsonassert) + testImplementation(libs.easyrandom) + testImplementation(libs.commons.lang3) + testImplementation(libs.commons.validator) + testImplementation(libs.guava) +} + +// Disable the Google Services task for the "open" variants. +googleServices { + // The open variants do not need this, so allow this to fail. + missingGoogleServicesStrategy = GoogleServicesPlugin.MissingGoogleServicesStrategy.WARN +} + +/** + * Loads the default properties, and the user properties. This will also load the + * secret keys. + */ +fun loadProperties(): Properties { + // Load the default properties. + val defaultProps = Properties() + defaultProps.load(FileInputStream(file("config.properties"))) + + // Load custom properties if available + val customProps = Properties(defaultProps) + val customFile = file("custom-config.properties") + if (customFile.exists()) { + customProps.load(FileInputStream(customFile)) + } else { + logger.info("No custom-config.properties file was found.") + } + + // Load the secret example secret keys. + val exampleKeys = Properties(customProps) + exampleKeys.load(FileInputStream(file("secrets.properties.example"))) + + // Load the actual keys if present + val actualKeys = Properties(exampleKeys) + val actualKeyFile = file("secrets.properties") + if (actualKeyFile.exists()) { + actualKeys.load(FileInputStream(actualKeyFile)) + } else { + logger.warn("A secrets.properties file was not found.") + } + + return actualKeys +} + +/** + * Loads the default properties, and the user properties. This will also load the + * secret keys. + */ +fun loadAndroidVersions(): Properties { + val defaultProps = Properties() + defaultProps.load(FileInputStream(file("../android-versions.toml"))) + + val strippedProps = Properties() + defaultProps.forEach { k, v -> + strippedProps.setProperty(k.toString(), v.toString().replace("\"", "")) + } + + return strippedProps +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6e60505ff..61f80c257 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -23,7 +23,7 @@ # By default, the flags in this file are appended to flags specified # in /home/flash/Android/Sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. +# directive in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..889be1796 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015-2024 The Hydra authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + id(libs.plugins.android.build.tool.get().pluginId) apply false + alias(libs.plugins.gms) apply false + alias(libs.plugins.firebase.crashlytics.gradle) apply false +} + +// We want sources to improve IDE features inside our Gradle files. +tasks.wrapper { + distributionType = Wrapper.DistributionType.ALL +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index 6ae4f3ad8..000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -plugins { - id 'groovy' - id 'java' - id 'idea' - id 'java-gradle-plugin' -} - -repositories { - google() - mavenCentral() -} - -dependencies { - implementation gradleApi() - implementation localGroovy() - implementation 'com.android.tools.build:gradle:8.6.1' - implementation 'org.jetbrains:annotations:25.0.0' - testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.14.1' -} - -validatePlugins { - failOnWarning = true -} \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..f00d9e540 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + groovy + idea + `java-gradle-plugin` +} + +repositories { + google() + mavenCentral() +} + +dependencies { + implementation(gradleApi()) + implementation(localGroovy()) + implementation(libs.android.build.tool) + implementation(libs.jetbrains.annotations) + testImplementation(libs.junit) + testImplementation(libs.mockito.core) +} + +tasks.validatePlugins { + failOnWarning = true +} diff --git a/settings.gradle b/buildSrc/settings.gradle.kts similarity index 84% rename from settings.gradle rename to buildSrc/settings.gradle.kts index 056c2b590..1b47054f4 100644 --- a/settings.gradle +++ b/buildSrc/settings.gradle.kts @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015-2021 The Hydra authors - * + * Copyright (c) 2024 Niko Strijbol + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -20,5 +20,10 @@ * SOFTWARE. */ -include ':app' -include ':material-intro' \ No newline at end of file +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/flake.nix b/flake.nix index 0a85b588e..06c8e793a 100644 --- a/flake.nix +++ b/flake.nix @@ -41,6 +41,7 @@ "android-sdk-license" ]; }; + aapt2Override = "${androidComposition.androidsdk}/libexec/android-sdk/build-tools/${androidVersions.buildToolsVersions}/aapt2"; in { devShells = rec { @@ -61,7 +62,7 @@ } { name = "GRADLE_OPTS"; - eval = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidComposition.androidsdk}/libexec/android-sdk/build-tools/${androidVersions.buildToolsVersions}/aapt2"; + eval = "-Pandroid.aapt2FromMavenOverride=${aapt2Override}"; } { name = "GRADLE_HOME"; @@ -71,7 +72,7 @@ devshell.startup.link.text = '' mkdir -p "$PRJ_DATA_DIR/.gradle" cat < "$PRJ_DATA_DIR/.gradle/gradle.properties" - org.gradle.jvmargs="$GRADLE_OPTS" + android.aapt2FromMavenOverride=${aapt2Override} EOF ''; }; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..d3d26d059 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,77 @@ +[versions] +androidxTest = '1.6.1' +espresso = '3.6.1' +livedata = '2.8.6' +okhttp3 = '4.12.0' +recordbuilder = '42' +room = '2.6.1' +buildtool = '8.5.2' + +[libraries] +android-build-tool = { module = 'com.android.tools.build:gradle', version.ref = 'buildtool' } +androidx-appcompat = { module = 'androidx.appcompat:appcompat', version = '1.7.0' } +androidx-browser = { module = 'androidx.browser:browser', version = '1.8.0' } +androidx-cardview = { module = 'androidx.cardview:cardview', version = '1.0.0' } +androidx-constraintlayout = { module = 'androidx.constraintlayout:constraintlayout', version = '2.1.4' } +androidx-core = { module = 'androidx.core:core', version = '1.13.1' } +androidx-core-testing = { module = 'androidx.arch.core:core-testing', version = '2.2.0' } +androidx-espresso-contrib = { module = 'androidx.test.espresso:espresso-contrib', version.ref = 'espresso' } +androidx-espresso-core = { module = 'androidx.test.espresso:espresso-core', version.ref = 'espresso' } +androidx-espresso-intents = { module = 'androidx.test.espresso:espresso-intents', version.ref = 'espresso' } +androidx-fragment = { module = 'androidx.fragment:fragment', version = '1.8.3' } +androidx-junit = { module = 'androidx.test.ext:junit', version = '1.2.1' } +androidx-lifecycle-data = { module = 'androidx.lifecycle:lifecycle-livedata', version.ref = 'livedata' } +androidx-lifecycle-java = { module = 'androidx.lifecycle:lifecycle-common-java8', version.ref = 'livedata' } +androidx-lifecycle-vm = { module = 'androidx.lifecycle:lifecycle-viewmodel', version.ref = 'livedata' } +androidx-media = { module = 'androidx.media:media', version = '1.7.0' } +androidx-preference = { module = 'androidx.preference:preference', version = '1.2.1' } +androidx-recyclerview = { module = 'androidx.recyclerview:recyclerview', version = '1.3.2' } +androidx-room-compiler = { module = 'androidx.room:room-compiler', version.ref = 'room' } +androidx-room-runtime = { module = 'androidx.room:room-runtime', version.ref = 'room' } +androidx-room-testing = { module = 'androidx.room:room-testing', version.ref = 'room' } +androidx-rules = { module = 'androidx.test:rules', version.ref = 'androidxTest' } +androidx-swiperefreshlayout = { module = 'androidx.swiperefreshlayout:swiperefreshlayout', version = '1.1.0' } +androidx-test-core = { module = 'androidx.test:core', version.ref = 'androidxTest' } +androidx-viewpager2 = { module = 'androidx.viewpager2:viewpager2', version = '1.1.0' } +cachapa = { module = 'com.github.cachapa:ExpandableLayout', version = '2.9.2' } +commons-lang3 = { module = 'org.apache.commons:commons-lang3', version = '3.17.0' } +commons-validator = { module = 'commons-validator:commons-validator', version = '1.9.0' } +desugar = { module = 'com.android.tools:desugar_jdk_libs', version = '2.1.2' } +easyrandom = { module = 'org.jeasy:easy-random-core', version = '6.0.0-SNAPSHOT' } +equalsverifier = { module = 'nl.jqno.equalsverifier:equalsverifier', version = '3.17' } +firebase-analytics = { module = 'com.google.firebase:firebase-analytics', version = '22.1.0' } +firebase-crashlytics = { module = 'com.google.firebase:firebase-crashlytics', version = '19.2.0' } +guava = { module = 'com.google.guava:guava', version = '33.3.1-jre' } +insetter = { module = 'dev.chrisbanes.insetter:insetter', version = '0.6.1' } +ipcam = { module = 'com.github.niqdev:ipcam-view', version = '2.4.1' } +jetbrains-annotations = { module = 'org.jetbrains:annotations', version = '25.0.0' } +jsonassert = { module = 'org.skyscreamer:jsonassert', version = '1.5.3' } +junit = { module = 'junit:junit', version = '4.13.2' } +leakcanary = { module = 'com.squareup.leakcanary:leakcanary-android', version = '2.14' } +material = { module = 'com.google.android.material:material', version = '1.12.0' } +materialvalues = { module = 'com.github.esnaultdev:MaterialValues', version = 'v1.1.1' } +mockito-core = { module = 'org.mockito:mockito-core', version = '5.14.1' } +mockito-inline = { module = 'org.mockito:mockito-inline', version = '5.2.0' } +moshi = { module = 'com.squareup.moshi:moshi', version = '1.15.1' } +okhttp3 = { module = 'com.squareup.okhttp3:okhttp', version.ref = 'okhttp3' } +okhttp3-mockwebserver = { module = 'com.squareup.okhttp3:mockwebserver', version.ref = 'okhttp3' } +once = { module = 'com.github.jonfinerty:Once', version = '19fa6fa10d' } +osmdroid = { module = 'org.osmdroid:osmdroid-android', version = '6.1.20' } +picasso = { module = 'com.squareup.picasso:picasso', version = '2.8' } +play-codescanner = { module = 'com.google.android.gms:play-services-code-scanner', version = '16.1.0' } +play-maps = { module = 'com.google.android.gms:play-services-maps', version = '19.0.0' } +recordbuilder-core = { module = 'io.soabase.record-builder:record-builder-core', version.ref = 'recordbuilder' } +recordbuilder-processor = { module = 'io.soabase.record-builder:record-builder-processor', version.ref = 'recordbuilder' } +robolectric = { module = 'org.robolectric:robolectric', version = '4.13' } +rxjava-rules = { module = 'com.artemzin.rxjava:proguard-rules', version = '1.3.3.0' } +shazamcrest = { module = 'com.shazam:shazamcrest', version = '0.11' } +zxing = { module = 'com.journeyapps:zxing-android-embedded', version = '4.3.0' } + +[plugins] +android-build-tool = { id = 'com.android.application', version.ref = 'buildtool' } +android-build-library = { id = 'com.android.library', version.ref = 'buildtool' } +gms = 'com.google.gms.google-services:4.4.2' +firebase-crashlytics-gradle = 'com.google.firebase.crashlytics:3.0.2' + +[bundles] +androidx-lifecycle = ['androidx-lifecycle-vm', 'androidx-lifecycle-data', 'androidx-lifecycle-java'] diff --git a/material-intro/build.gradle b/material-intro/build.gradle deleted file mode 100644 index 100c4417a..000000000 --- a/material-intro/build.gradle +++ /dev/null @@ -1,53 +0,0 @@ -apply plugin: 'com.android.library' - -def versions = loadAndroidVersions() - -android { - // We need this for Nix flakes - //noinspection GrDeprecatedAPIUsage - buildToolsVersion versions.buildToolsVersions - - defaultConfig { - compileSdk versions.platformVersions as Integer - minSdk 21 - targetSdk 34 - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - namespace 'com.heinrichreimersoftware.materialintro' - - lint { - disable 'Overdraw', 'OldTargetApi', 'GradleDependency' - showAll true - warningsAsErrors true - } -} - -dependencies { - implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'com.google.android.material:material:1.12.0' -} - -// TODO: extract this duplicate code... -/** - * Loads the default properties, and the user properties. This will also load the - * secret keys. - */ -def loadAndroidVersions() { - def defaultProps = new Properties() - defaultProps.load(file("../android-versions.toml").newReader()) - - def strippedProps = new Properties() - for (e in defaultProps) { - strippedProps.setProperty(e.key, e.value.replaceAll('"', '')) - } - - return strippedProps -} \ No newline at end of file diff --git a/material-intro/build.gradle.kts b/material-intro/build.gradle.kts new file mode 100644 index 000000000..ee67915f8 --- /dev/null +++ b/material-intro/build.gradle.kts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Jan Heinrich Reimer + * Copyright (c) 2024 Niko Strijbol + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +import java.io.FileInputStream +import java.util.* + +plugins { + id(libs.plugins.android.build.library.get().pluginId) +} + +val versions = loadAndroidVersions() + +android { + namespace = "com.heinrichreimersoftware.materialintro" + + // We need this for Nix flakes + buildToolsVersion = versions.getProperty("buildToolsVersions") + + defaultConfig { + compileSdk = versions.getProperty("platformVersions").toInt() + minSdk = 21 + } + + buildTypes { + getByName("release") { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + } + } + + lint { + disable += listOf("Overdraw", "OldTargetApi", "GradleDependency") + showAll = true + warningsAsErrors = true + targetSdk = 34 + } +} + +dependencies { + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintlayout) + implementation(libs.material) +} + +// TODO: extract this duplicate code... +/** + * Loads the default properties, and the user properties. This will also load the + * secret keys. + */ +fun loadAndroidVersions(): Properties { + val defaultProps = Properties() + defaultProps.load(FileInputStream(file("../android-versions.toml"))) + + val strippedProps = Properties() + defaultProps.forEach { k, v -> + strippedProps.setProperty(k.toString(), v.toString().replace("\"", "")) + } + + return strippedProps +} \ No newline at end of file diff --git a/material-intro/proguard-rules.pro b/material-intro/proguard-rules.pro index d09df3fd4..5a1574f6e 100644 --- a/material-intro/proguard-rules.pro +++ b/material-intro/proguard-rules.pro @@ -2,7 +2,7 @@ # By default, the flags in this file are appended to flags specified # in C:\Users\Agando\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. +# directive in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/build.gradle b/settings.gradle.kts similarity index 63% rename from build.gradle rename to settings.gradle.kts index 802c184da..5b6101bcd 100644 --- a/build.gradle +++ b/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2022 The Hydra authors + * Copyright (c) 2015-2024 The Hydra authors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -19,36 +19,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -buildscript { + +pluginManagement { repositories { - // For Google-related dependencies + gradlePluginPortal() google() - // For the license plugin mavenCentral() } - dependencies { - classpath 'com.android.tools.build:gradle:8.6.1' - classpath 'com.google.gms:google-services:4.4.2' - classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.2' - } } -allprojects { +dependencyResolutionManagement { + @Suppress("UnstableApiUsage") repositories { - // Google libraries google() - // Other libraries mavenCentral() - // Some custom libraries - maven { url 'https://jitpack.io' } + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } + maven { url = uri("https://jitpack.io") } } } -tasks.register('clean', Delete) { - delete rootProject.layout.buildDirectory -} - -// We want sources to improve IDE features inside our Gradle files. -wrapper { - distributionType = Wrapper.DistributionType.ALL -} +include(":app") +include(":material-intro") \ No newline at end of file