[#3] Add skeleton Gradle project structure
|
@ -6,7 +6,7 @@ This code review checklist is intended to serve as a starting point for the auth
|
|||
- [ ] Automated tests: Did you add appropriate automated tests for any code changes?
|
||||
- [ ] Manual tests: Did you update the [manual tests](../blob/main/docs/testing/manual_testing) as appropriate? _While we aim for automated testing of the application, some aspects require manual testing. If you had to manually test something during development of this pull request, write those steps down._
|
||||
- [ ] Code coverage: Did you check the code coverage report for the automated tests? _While we are not looking for perfect coverage, the tool can point out potential cases that have been missed._
|
||||
- [ ] Documentation: Did you update documentation as appropiate? (e.g [README.md](../blob/main/README.md), etc.)
|
||||
- [ ] Documentation: Did you update documentation as appropriate? (e.g [README.md](../blob/main/README.md), etc.)
|
||||
- [ ] Run the app: Did you run the app and try the changes?
|
||||
- [ ] Screenshots: Did you provide before and after UI screenshots in the description of this pull request? _This is only applicable for changes that modify the UI._
|
||||
- [ ] Rebase and squash: Did you pull in the latest changes from the main branch and squash your commits before assigning a reviewer? _Having your code up to date and squashed will make it easier for others to review. Use best judgement when squashing commits, as some changes (such as refactoring) might be easier to review as a separate commit._
|
||||
|
|
|
@ -16,3 +16,4 @@ bin/
|
|||
build/
|
||||
gen/
|
||||
local.properties
|
||||
/.idea/deploymentTargetDropDown.xml
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
misc.xml
|
|
@ -0,0 +1 @@
|
|||
zcash-android-app
|
|
@ -0,0 +1,23 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="clean" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,23 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="dependencyUpdates" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="dependencyUpdates" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,23 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="detektAll" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="detektAll" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,23 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lint" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="lint" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
17
README.md
|
@ -9,9 +9,7 @@ While we aim to continue improving this sample, it is not an official product.
|
|||
If you'd like to compile this application from source, please see our [Setup Documentation](docs/Setup.md) to get started.
|
||||
|
||||
# Reporting an issue
|
||||
If you wish to report a security issue, please follow our [Responsible Disclosure guidelines](https://github.com/zcash/ZcashLightClientKit/blob/master/responsible_disclosure.md). See the [Wallet App Threat Model](https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_threat_model.html) for more information about the security and privacy limitations of the wallet. There are some known security and privacy limitations:
|
||||
- Traffic analysis, like in other cryptocurrency wallets, can leak some privacy of the user.
|
||||
- The wallet requires a trust in the server to display accurate transaction information.
|
||||
If you wish to report a security issue, please follow our [Responsible Disclosure guidelines](https://github.com/zcash/ZcashLightClientKit/blob/master/responsible_disclosure.md). See the [Wallet App Threat Model](https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_threat_model.html) for more information about the security and privacy limitations of the wallet.
|
||||
|
||||
If you'd like to report a technical issue or feature request for the Android Wallet, please file a [GitHub issue](https://github.com/zcash/secant-android-wallet/issues/new/choose).
|
||||
|
||||
|
@ -21,3 +19,16 @@ General Zcash questions and/or support requests and are best directed to either:
|
|||
|
||||
# Contributing
|
||||
Contributions are very much welcomed! Please read our [Contributing Guidelines](docs/CONTRIBUTING.md) to learn about our process.
|
||||
|
||||
# Forking
|
||||
If you plan to fork the project to create a new app of your own, please make the following changes. (If you're making a GitHub fork to contribute back to the project, these steps are not necessary.)
|
||||
|
||||
1. Change the app name under app/
|
||||
1. Remove any copyrighted ZCash or Electric Coin Company icons, logos, or assets
|
||||
1. Change the package name
|
||||
1. Under [app/build.gradle.kts](app/build.gradle.kts), change the package name of the application
|
||||
1. Under [app/proguard-project.txt](app/proguard-project.txt), change the `-repackageclasses` directive to your own package name
|
||||
|
||||
# Known Issues
|
||||
|
||||
1. During builds, a warning will be printed that says "Unable to detect AGP versions for included builds. All projects in the build should use the same AGP version." This can be safely ignored. The version under build-conventions is the same as the version used elsewhere in the application.
|
|
@ -0,0 +1,103 @@
|
|||
plugins {
|
||||
id("com.android.application")
|
||||
kotlin("android")
|
||||
id("kotlin-parcelize")
|
||||
id("androidx.navigation.safeargs")
|
||||
id("zcash.android-build-conventions")
|
||||
}
|
||||
|
||||
val packageName = "cash.z.ecc.android"
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
applicationId = packageName
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = libs.versions.compose.get()
|
||||
}
|
||||
|
||||
flavorDimensions.add("network")
|
||||
|
||||
productFlavors {
|
||||
// would rather name them "testnet" and "mainnet" but product flavor names cannot start with the word "test"
|
||||
create("zcashtestnet") {
|
||||
dimension = "network"
|
||||
applicationId = "$packageName.testnet" // allow to be installed alongside mainnet
|
||||
matchingFallbacks.addAll(listOf("zcashtestnet", "debug"))
|
||||
}
|
||||
|
||||
create("zcashmainnet") {
|
||||
dimension = "network"
|
||||
applicationId = packageName
|
||||
matchingFallbacks.addAll(listOf("zcashmainnet", "release"))
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("release").apply {
|
||||
isMinifyEnabled = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
|
||||
proguardFiles.addAll(
|
||||
listOf(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
File("proguard-project.txt")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
val releaseKeystorePath = project.property("ZCASH_RELEASE_KEYSTORE_PATH").toString()
|
||||
val releaseKeystorePassword = project.property("ZCASH_RELEASE_KEYSTORE_PASSWORD").toString()
|
||||
val releaseKeyAlias = project.property("ZCASH_RELEASE_KEY_ALIAS").toString()
|
||||
val releaseKeyAliasPassword =
|
||||
project.property("ZCASH_RELEASE_KEY_ALIAS_PASSWORD").toString()
|
||||
val isReleaseSigningConfigured = listOf(
|
||||
releaseKeystorePath,
|
||||
releaseKeystorePassword,
|
||||
releaseKeyAlias,
|
||||
releaseKeyAliasPassword
|
||||
).all { !it.isNullOrBlank() }
|
||||
|
||||
if (isReleaseSigningConfigured) {
|
||||
// If this block doesn't execute, the output will be unsigned
|
||||
create("release").apply {
|
||||
storeFile = File(releaseKeystorePath)
|
||||
storePassword = releaseKeystorePassword
|
||||
keyAlias = releaseKeyAlias
|
||||
keyPassword = releaseKeyAliasPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [#5]: Figure out how to move this into the build-conventions
|
||||
testCoverage {
|
||||
jacocoVersion = libs.versions.jacoco.get()
|
||||
}
|
||||
|
||||
// TODO [#6]: Figure out how to move this into the build-conventions
|
||||
kotlinOptions {
|
||||
jvmTarget = libs.versions.java.get()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.annotation)
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.bundles.androidx.compose)
|
||||
implementation(libs.google.material)
|
||||
implementation(libs.kotlin)
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.zcash)
|
||||
|
||||
androidTestImplementation(libs.bundles.androidx.test)
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
# This improves obfuscation.
|
||||
-repackageclasses 'cash.z.ecc.android'
|
||||
|
||||
# Ensure that stacktraces are reversible.
|
||||
-renamesourcefileattribute SourceFile
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Generate the combined proguard configuration for debugging.
|
||||
-printconfiguration build/outputs/proguard-config.txt
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cash.z.ecc.android.sdk.demoapp">
|
||||
|
||||
<application
|
||||
android:name="cash.z.ecc.android.app.App"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.MyApplication">
|
||||
|
||||
<!-- Alias acts as the entrypoint to the application.
|
||||
Using an alias ensures we can refactor the actual Activity without breaking
|
||||
clients. -->
|
||||
<activity-alias
|
||||
android:name=".LauncherActivity"
|
||||
android:label="@string/"
|
||||
android:targetActivity="cash.z.ecc.android.app.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name="cash.z.ecc.android.app.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.MyApplication"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,19 @@
|
|||
package cash.z.ecc.android.app
|
||||
|
||||
import android.app.Application
|
||||
import cash.z.ecc.android.sdk.demoapp.BuildConfig
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
|
||||
class App : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictModeHelper.enableStrictMode()
|
||||
}
|
||||
|
||||
Twig.plant(TroubleshootingTwig())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package cash.z.ecc.android.app
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import cash.z.ecc.android.app.ui.theme.MyApplicationTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
MyApplicationTheme {
|
||||
// A surface container using the 'background' color from the theme
|
||||
Surface(color = MaterialTheme.colors.background) {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Greeting(name: String) {
|
||||
Text(text = "Hello $name!")
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun DefaultPreview() {
|
||||
MyApplicationTheme {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package cash.z.ecc.android.app
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.StrictMode
|
||||
|
||||
|
||||
object StrictModeHelper {
|
||||
|
||||
fun enableStrictMode() {
|
||||
configureStrictMode()
|
||||
|
||||
// Workaround for Android bug
|
||||
// https://issuetracker.google.com/issues/36951662
|
||||
// Not needed if target O_MR1 and running on O_MR1
|
||||
// Don't really need to check target, because of Google Play enforcement on targetSdkVersion for app updates
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
|
||||
Handler(Looper.getMainLooper()).postAtFrontOfQueue { configureStrictMode() }
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun configureStrictMode() {
|
||||
StrictMode.enableDefaults()
|
||||
|
||||
StrictMode.setThreadPolicy(
|
||||
StrictMode.ThreadPolicy.Builder().apply {
|
||||
detectAll()
|
||||
penaltyLog()
|
||||
}.build()
|
||||
)
|
||||
|
||||
// Don't enable missing network tags, because those are noisy.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
StrictMode.setVmPolicy(
|
||||
StrictMode.VmPolicy.Builder().apply {
|
||||
detectActivityLeaks()
|
||||
detectCleartextNetwork()
|
||||
detectContentUriWithoutPermission()
|
||||
detectFileUriExposure()
|
||||
detectLeakedClosableObjects()
|
||||
detectLeakedRegistrationObjects()
|
||||
detectLeakedSqlLiteObjects()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
// Disable because this is mostly flagging Android X and Play Services
|
||||
// builder.detectNonSdkApiUsage();
|
||||
}
|
||||
}.build()
|
||||
)
|
||||
} else {
|
||||
StrictMode.setVmPolicy(
|
||||
StrictMode.VmPolicy.Builder().apply {
|
||||
detectAll()
|
||||
penaltyLog()
|
||||
}.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package cash.z.ecc.android.app.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val Purple200 = Color(0xFFBB86FC)
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val Purple500 = Color(0xFF6200EE)
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val Purple700 = Color(0xFF3700B3)
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
val Teal200 = Color(0xFF03DAC5)
|
|
@ -0,0 +1,11 @@
|
|||
package cash.z.ecc.android.app.ui.theme
|
||||
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Shapes
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val Shapes = Shapes(
|
||||
small = RoundedCornerShape(4.dp),
|
||||
medium = RoundedCornerShape(4.dp),
|
||||
large = RoundedCornerShape(0.dp)
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
package cash.z.ecc.android.app.ui.theme
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.darkColors
|
||||
import androidx.compose.material.lightColors
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
private val DarkColorPalette = darkColors(
|
||||
primary = Purple200,
|
||||
primaryVariant = Purple700,
|
||||
secondary = Teal200
|
||||
)
|
||||
|
||||
private val LightColorPalette = lightColors(
|
||||
primary = Purple500,
|
||||
primaryVariant = Purple700,
|
||||
secondary = Teal200
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color.White,
|
||||
surface = Color.White,
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.Black,
|
||||
onBackground = Color.Black,
|
||||
onSurface = Color.Black,
|
||||
*/
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun MyApplicationTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
content: @Composable() () -> Unit
|
||||
) {
|
||||
val colors = if (darkTheme) {
|
||||
DarkColorPalette
|
||||
} else {
|
||||
LightColorPalette
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colors = colors,
|
||||
typography = Typography,
|
||||
shapes = Shapes,
|
||||
content = content
|
||||
)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cash.z.ecc.android.app.ui.theme
|
||||
|
||||
import androidx.compose.material.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
body1 = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp
|
||||
)
|
||||
/* Other default text styles to override
|
||||
button = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.W500,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
caption = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
*/
|
||||
)
|
|
@ -0,0 +1,31 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108"
|
||||
android:width="108dp">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
|
@ -0,0 +1,171 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108"
|
||||
android:width="108dp">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
</vector>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,16 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">Demo App</string>
|
||||
</resources>
|
|
@ -0,0 +1,25 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.MyApplication.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.MyApplication.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<style name="Theme.MyApplication.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
</resources>
|
|
@ -0,0 +1,4 @@
|
|||
<resources>
|
||||
<string name="app_name">Mainnet Demo</string>
|
||||
<string name="network_name">Mainnet</string>
|
||||
</resources>
|
|
@ -0,0 +1,4 @@
|
|||
<resources>
|
||||
<string name="app_name">Testnet Demo</string>
|
||||
<string name="network_name">Testnet</string>
|
||||
</resources>
|
|
@ -0,0 +1,21 @@
|
|||
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
||||
implementation("com.android.tools.build:gradle:${getAndroidGradlePluginVersion()}")
|
||||
}
|
||||
|
||||
fun getAndroidGradlePluginVersion(): String {
|
||||
// A slightly gross way to use the root gradle.properties as the single source of truth for version numbers
|
||||
val properties = run {
|
||||
val rootPropertiesFile = File(project.projectDir.parentFile, "gradle.properties")
|
||||
loadProperties(rootPropertiesFile.path)
|
||||
}
|
||||
|
||||
return properties.getProperty("ANDROID_GRADLE_PLUGIN_VERSION")
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "build-conventions"
|
|
@ -0,0 +1,85 @@
|
|||
pluginManager.withPlugin("com.android.application") {
|
||||
project.the<com.android.build.gradle.AppExtension>().apply {
|
||||
configureBaseExtension()
|
||||
|
||||
defaultConfig {
|
||||
minSdk = (project.property("ANDROID_MIN_SDK_VERSION").toString().toInt())
|
||||
targetSdk = (project.property("ANDROID_TARGET_SDK_VERSION").toString().toInt())
|
||||
|
||||
// en_XA and ar_XB are pseudolocales for debugging.
|
||||
// The rest of the locales provides an explicit list of the languages to keep in the
|
||||
// final app. Doing this will strip out additional locales from libraries like
|
||||
// Google Play Services and Firebase, which add unnecessary bloat.
|
||||
resourceConfigurations.addAll(listOf("en", "en-rUS", "en-rGB", "en-rAU", "en_XA", "ar_XB"))
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
if (project.property("IS_USE_TEST_ORCHESTRATOR").toString().toBoolean()) {
|
||||
testInstrumentationRunnerArguments["clearPackageData"] = "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginManager.withPlugin("com.android.library") {
|
||||
project.the<com.android.build.gradle.LibraryExtension>().apply {
|
||||
configureBaseExtension()
|
||||
|
||||
defaultConfig {
|
||||
minSdk = project.property("ANDROID_MIN_SDK_VERSION").toString().toInt()
|
||||
targetSdk = project.property("ANDROID_TARGET_SDK_VERSION").toString().toInt()
|
||||
|
||||
// The last two are for support of pseudolocales in debug builds.
|
||||
// If we add other localizations, they should be included in this list.
|
||||
// By explicitly setting supported locales, we strip out unused localizations from third party
|
||||
// libraries (e.g. play services)
|
||||
resourceConfigurations.addAll(listOf("en", "en-rUS", "en-rGB", "en-rAU", "en_XA", "ar_XB"))
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles("proguard-consumer.txt")
|
||||
|
||||
if (project.property("IS_USE_TEST_ORCHESTRATOR").toString().toBoolean()) {
|
||||
testInstrumentationRunnerArguments["clearPackageData"] = "true"
|
||||
}
|
||||
}
|
||||
testCoverage {
|
||||
jacocoVersion = project.property("JACOCO_VERSION").toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun com.android.build.gradle.BaseExtension.configureBaseExtension() {
|
||||
compileSdkVersion(project.property("ANDROID_COMPILE_SDK_VERSION").toString().toInt())
|
||||
ndkVersion = project.property("ANDROID_NDK_VERSION").toString()
|
||||
|
||||
compileOptions {
|
||||
val javaVersion = JavaVersion.toVersion(project.property("ANDROID_JVM_TARGET").toString())
|
||||
sourceCompatibility = javaVersion
|
||||
targetCompatibility = javaVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("debug").apply {
|
||||
isTestCoverageEnabled = project.property("IS_COVERAGE_ENABLED").toString().toBoolean()
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
val debugKeystorePath = project.property("ZCASH_DEBUG_KEYSTORE_PATH").toString()
|
||||
val isExplicitDebugSigningEnabled = !debugKeystorePath.isNullOrBlank()
|
||||
if (isExplicitDebugSigningEnabled) {
|
||||
// If this block doesn't execute, the output will still be signed with the default keystore
|
||||
getByName("debug").apply {
|
||||
storeFile = File(debugKeystorePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testOptions {
|
||||
animationsDisabled = true
|
||||
|
||||
if (project.property("IS_USE_TEST_ORCHESTRATOR").toString().toBoolean()) {
|
||||
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import org.gradle.internal.impldep.org.junit.experimental.categories.Categories.CategoryFilter.exclude
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://jitpack.io")
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:${properties["ANDROID_GRADLE_PLUGIN_VERSION"]}")
|
||||
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:${properties["ANDROIDX_NAVIGATION_VERSION"]}")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("com.github.ben-manes.versions")
|
||||
id("io.gitlab.arturbosch.detekt")
|
||||
}
|
||||
|
||||
tasks {
|
||||
register("detektAll", io.gitlab.arturbosch.detekt.Detekt::class) {
|
||||
parallel = true
|
||||
setSource(files(projectDir))
|
||||
include("**/*.kt")
|
||||
include("**/*.kts")
|
||||
exclude("**/resources/**")
|
||||
exclude("**/build/**")
|
||||
exclude("**/commonTest/**")
|
||||
exclude("**/jvmTest/**")
|
||||
exclude("**/androidTest/**")
|
||||
config.setFrom(files("${rootProject.projectDir}/tools/detekt.yml"))
|
||||
buildUponDefaultConfig = true
|
||||
}
|
||||
|
||||
withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask> {
|
||||
gradleReleaseChannel = "current"
|
||||
|
||||
resolutionStrategy {
|
||||
componentSelection {
|
||||
all {
|
||||
if (isNonStable(candidate.version) && !isNonStable(currentVersion)) {
|
||||
reject("Unstable")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unstableKeywords = listOf("alpha", "beta", "rc", "m", "ea", "build")
|
||||
|
||||
fun isNonStable(version: String): Boolean {
|
||||
val versionLowerCase = version.toLowerCase()
|
||||
|
||||
return unstableKeywords.any { versionLowerCase.contains(it) }
|
||||
}
|
|
@ -1,2 +1,7 @@
|
|||
# Architecture
|
||||
TODO This is a placeholder for describing the app architecture.
|
||||
TODO This is a placeholder for describing the app architecture.
|
||||
## Gradle
|
||||
* Versions are declared in `gradle.properties`. There's still enough inconsistency in how versions are handled in Gradle, that this is as close as we can get to a universal system. A version catalog is used for dependencies and is configured in `settings.gradle.kts`, but other versions like Gradle Plug-ins, the NDK version, Java version, and Android SDK versions don't fit into the version catalog model and are read directly from the properties
|
||||
* Much of the Gradle configuration lives in `build-conventions` to prevent repetitive configuration as additional modules are added to the project
|
||||
* Build scripts are written in Kotlin, so that a single language is used across build and the app code bases
|
||||
* Only Gradle, Google, and JetBrains plug-ins are included in the critical path. Third party plug-ins can be used, but they're outside the critical path. For example, the Gradle Versions Plugin could be removed and wouldn't negative impact building, testing, or deploying the app
|
|
@ -1,8 +1,8 @@
|
|||
# Overall:
|
||||
|
||||
- Does the contribution referece an existing Issue?
|
||||
- Does the contribution reference an existing GitHub issue?
|
||||
- Are the requirements well defined?
|
||||
|
||||
- Does static analysis pass? (e.g. `./gradlew detektAll` and `./gradlew lint`)
|
||||
|
||||
# Specification:
|
||||
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
# Setup Guide
|
||||
## Gradle
|
||||
The app is built with Gradle and can be compiled on macOS, Windows, and Linux.
|
||||
The app is built with Gradle and can be compiled on macOS, Windows, and Linux. Development is typically done with the latest stable release of Android Studio.
|
||||
|
||||
Tip: On macOS and Linux, Gradle is invoked with `./gradlew`. On Windows, Gradle is invoked with `gradlew`. Throughout the documentation, the macOS and Linux syntax is used by default.
|
||||
|
||||
Tip: You do NOT need to install Gradle yourself. Running it from the command line or building the application within Android Studio will download the necessary dependencies automatically.
|
||||
|
||||
## Android Studio
|
||||
Development is typically done with the latest stable release of Android Studio.
|
||||
|
||||
## Step by Step
|
||||
To get set up for development, there are several steps that you need to go through. Going through these steps in order is important, as each step in the progression builds on the prior steps.
|
||||
|
||||
Start by making sure the command line with Gradle works first, because **all the Android Studio run configurations use Gradle internally.** The run configurations are not magic—they map directly to command line invocations with different arguments.
|
||||
|
||||
When troubleshooting, fall back to trying the command line. Android Studio is a large and complex application, although under the hood it uses Gradle. Sometimes Android Studio will have a bug or failure that is bypassed by using the Gradle command line directly.
|
||||
|
||||
1. Install Java
|
||||
1. Java 16 is currently recommended. Java 11 is the minimum requirement for Android Studio.
|
||||
1. To simplify installation, use [Oracle's JDK](https://www.oracle.com/java/technologies/javase-jdk15-downloads.html) installer that will place the Java installation in the right place
|
||||
1. To simplify installation, use [Oracle's JDK](https://www.oracle.com/java/technologies/javase-jdk16-downloads.html) installer that will place the Java installation in the right place
|
||||
1. Install Android Studio and the Android SDK
|
||||
1. Download the [stable release of Android Studio](https://developer.android.com/studio#downloads)
|
||||
1. TODO: Fill in step-by-step instructions for setting up a new environment and installing the Android SDK from within Android Studio.
|
||||
|
@ -31,14 +25,33 @@ When troubleshooting, fall back to trying the command line. Android Studio is a
|
|||
1. From within Android Studio, choose to open an existing project and navigate to the checked out repo
|
||||
1. After Android Studio finishes syncing with Gradle, look for the green "play" run button in the toolbar. To the left of it, choose the "App" run configuration under the dropdown menu. Then hit the run button
|
||||
|
||||
# Troubleshooting
|
||||
Sometimes during upgrades to Gradle or Kotlin, corruption or weird issues can happen with a build. Try troubleshooting with the following steps:
|
||||
|
||||
## Troubleshooting
|
||||
1. Try running from the command line instead of Android Studio, to rule out Android Studio issues. If it works from the command line, try this step to reset Android Studio
|
||||
1. Quit Android Studio
|
||||
2. Deleting the invisible `.idea` in the root directory of the project
|
||||
3. Relaunch Android Studio
|
||||
1. Quit Android Studio
|
||||
2. Deleting the invisible `.idea` in the root directory of the project
|
||||
3. Relaunch Android Studio
|
||||
2. Clean the individual Gradle project by running `./gradlew clean` which will purge local build outputs.
|
||||
3. Run Gradle with the flag `--rerun-tasks` which will effectively disable the build cache by re-running tasks and repopulating the cache. E.g. `./gradlew assemble --rerun-tasks`
|
||||
4. Reboot your computer, which will ensure that Gradle and Kotlin daemons are completely killed and relaunched
|
||||
5. Delete the global Gradle cache under `~/.gradle/caches`
|
||||
5. Delete the global Gradle cache under `~/.gradle/caches`
|
||||
|
||||
## Gradle Tasks
|
||||
A variety of Gradle tasks are set up within the project, and these tasks are also accessible in Android Studio as run configurations.
|
||||
`assemble` - Compiles the application
|
||||
`detektAll` - Performs static analysis with Detekt
|
||||
`lint` - Performs static analysis with Android lint
|
||||
`dependencyUpdates` - Checks for available dependency updates
|
||||
|
||||
## Gradle Properties
|
||||
A variety of Gradle properties can be used to configure the build.
|
||||
### Debug Signing
|
||||
By default, the application is signed by the developers automatically generated debug signing key. In a team of developers, it may be advantageous to share a debug key so that debug builds can access key-restricted services such as Firebase or Google Maps. For such a setup, the path to a shared debug signing key can be set with the property `ZCASH_DEBUG_KEYSTORE_PATH`.
|
||||
|
||||
### Release Signing
|
||||
To enable release signing, a release keystore needs to be provided during the build. This can be injected securely by setting the following Gradle properties.
|
||||
* ZCASH_RELEASE_KEYSTORE_PATH
|
||||
* ZCASH_RELEASE_KEYSTORE_PASSWORD
|
||||
* ZCASH_RELEASE_KEY_ALIAS
|
||||
* ZCASH_RELEASE_KEY_ALIAS_PASSWORD
|
||||
|
||||
On a developer machine, these might be set under the user's global properties (e.g. `~/.gradle/gradle.properties` on macOS and Linux). On a continuous integration machine, these can also be set using environment variables with the prefix `ORG_GRADLE_PROJECT_` (e.g. `ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PATH`). DO NOT set these in the gradle.properties inside the Git repository, as this will leak your keystore password.
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# Speed up builds. Keep these flags here for quick debugging of issues.
|
||||
org.gradle.vfs.watch=true
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
kapt.include.compile.classpath=false
|
||||
kapt.incremental.apt=true
|
||||
kapt.use.worker.api=true
|
||||
|
||||
android.useAndroidX=true
|
||||
android.builder.sdkDownload=true
|
||||
|
||||
# Optionally configure code coverage, as historically Jacoco has at times been buggy with respect to new Kotlin versions
|
||||
IS_COVERAGE_ENABLED=true
|
||||
|
||||
# Optionally configure test orchestrator.
|
||||
# It is disabled by default, because it causes tests to take about 2x longer to run.
|
||||
IS_USE_TEST_ORCHESTRATOR=false
|
||||
|
||||
# Optionally disable minification
|
||||
IS_MINIFY_ENABLED=true
|
||||
|
||||
# Set keystore details to enable build signing. Typically these
|
||||
# are overridden via ~/.gradle/gradle.properties to allow secure injection.
|
||||
# Debug keystore is useful if using Google Maps or Firebase, which require API keys to be linked
|
||||
# to a signing key. Without a debug keystore, the default Android debug keystore will be used.
|
||||
# Without a release signing configuration, the release output will not be signed.
|
||||
ZCASH_DEBUG_KEYSTORE_PATH=
|
||||
ZCASH_RELEASE_KEYSTORE_PATH=
|
||||
ZCASH_RELEASE_KEYSTORE_PASSWORD=
|
||||
ZCASH_RELEASE_KEY_ALIAS=
|
||||
ZCASH_RELEASE_KEY_ALIAS_PASSWORD=
|
||||
|
||||
# Versions
|
||||
ANDROID_MIN_SDK_VERSION=24
|
||||
ANDROID_TARGET_SDK_VERSION=31
|
||||
ANDROID_COMPILE_SDK_VERSION=31
|
||||
|
||||
ANDROID_NDK_VERSION=23.0.7599858
|
||||
|
||||
ANDROID_GRADLE_PLUGIN_VERSION=7.0.2
|
||||
DETEKT_VERSION=1.18.1
|
||||
GRADLE_VERSIONS_PLUGIN_VERSION=0.38.0
|
||||
|
||||
ANDROIDX_ACTIVITY_VERSION=1.3.1
|
||||
ANDROIDX_ANNOTATION_VERSION=1.2.0
|
||||
ANDROIDX_APPCOMPAT_VERSION=1.3.1
|
||||
ANDROIDX_COMPOSE_VERSION=1.0.2
|
||||
ANDROIDX_CORE_VERSION=1.6.0
|
||||
ANDROIDX_ESPRESSO_VERSION=3.4.0
|
||||
ANDROIDX_NAVIGATION_VERSION=2.3.5
|
||||
ANDROIDX_TEST_JUNIT_VERSION=1.1.3
|
||||
ANDROIDX_TEST_ORCHESTRATOR_VERSION=1.1.0-alpha1
|
||||
ANDROIDX_UI_AUTOMATOR_VERSION=2.2.0-alpha1
|
||||
GOOGLE_MATERIAL_VERSION=1.4.0
|
||||
JACOCO_VERSION=0.8.7
|
||||
KOTLINX_COROUTINES_VERSION=1.5.1
|
||||
KOTLIN_VERSION=1.5.21
|
||||
ZCASH_SDK_VERSION=1.3.0-beta18
|
||||
|
||||
# This shouldn't be changed, as Android doesn't support targets beyond Java 8
|
||||
ANDROID_JVM_TARGET=1.8
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,234 @@
|
|||
#!/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.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# 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/master/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
|
||||
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
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
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 ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
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
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
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.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
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" )
|
||||
|
||||
# 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" )
|
||||
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
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# 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" "$@"
|
|
@ -0,0 +1,89 @@
|
|||
@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
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
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%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
: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 %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
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!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
|
@ -0,0 +1,110 @@
|
|||
enableFeaturePreview("VERSION_CATALOGS")
|
||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
}
|
||||
|
||||
plugins {
|
||||
val detektVersion = extra["DETEKT_VERSION"].toString()
|
||||
val gradleVersionsPluginVersion = extra["GRADLE_VERSIONS_PLUGIN_VERSION"].toString()
|
||||
val kotlinVersion = extra["KOTLIN_VERSION"].toString()
|
||||
|
||||
kotlin("jvm") version (kotlinVersion)
|
||||
id("com.github.ben-manes.versions") version (gradleVersionsPluginVersion) apply (false)
|
||||
id("io.gitlab.arturbosch.detekt") version (detektVersion) apply (false)
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
@Suppress("UnstableApiUsage")
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://jitpack.io")
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage", "MaxLineLength")
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
val androidxActivityVersion = extra["ANDROIDX_ACTIVITY_VERSION"].toString()
|
||||
val androidxAnnotationVersion = extra["ANDROIDX_ANNOTATION_VERSION"].toString()
|
||||
val androidxAppcompatVersion = extra["ANDROIDX_APPCOMPAT_VERSION"].toString()
|
||||
val androidxComposeVersion = extra["ANDROIDX_COMPOSE_VERSION"].toString()
|
||||
val androidxCoreVersion = extra["ANDROIDX_CORE_VERSION"].toString()
|
||||
val androidxEspressoVersion = extra["ANDROIDX_ESPRESSO_VERSION"].toString()
|
||||
val androidxTestJunitVersion = extra["ANDROIDX_TEST_JUNIT_VERSION"].toString()
|
||||
val androidxTestOrchestratorVersion = extra["ANDROIDX_ESPRESSO_VERSION"].toString()
|
||||
val androidxUiAutomatorVersion = extra["ANDROIDX_UI_AUTOMATOR_VERSION"].toString()
|
||||
val googleMaterialVersion = extra["GOOGLE_MATERIAL_VERSION"].toString()
|
||||
val jacocoVersion = extra["JACOCO_VERSION"].toString()
|
||||
val javaVersion = extra["ANDROID_JVM_TARGET"].toString()
|
||||
val kotlinVersion = extra["KOTLIN_VERSION"].toString()
|
||||
val kotlinxCoroutinesVersion = extra["KOTLINX_COROUTINES_VERSION"].toString()
|
||||
val zcashSdkVersion = extra["ZCASH_SDK_VERSION"].toString()
|
||||
|
||||
// Standalone versions
|
||||
version("compose", androidxComposeVersion)
|
||||
version("jacoco", jacocoVersion)
|
||||
version("java", javaVersion)
|
||||
|
||||
// Aliases
|
||||
alias("androidx-activity").to("androidx.activity:activity-ktx:${androidxActivityVersion}")
|
||||
alias("androidx-activity-compose").to("androidx.activity:activity-compose:$androidxActivityVersion")
|
||||
alias("androidx-appcompat").to("androidx.appcompat:appcompat:$androidxAppcompatVersion")
|
||||
alias("androidx-annotation").to("androidx.annotation:annotation:${androidxAnnotationVersion}")
|
||||
alias("androidx-compose-foundation").to("androidx.compose.foundation:foundation:$androidxComposeVersion")
|
||||
alias("androidx-compose-material").to("androidx.compose.material:material:$androidxComposeVersion")
|
||||
alias("androidx-compose-material-icons-core").to("androidx.compose.material:material-icons-core:$androidxComposeVersion")
|
||||
alias("androidx-compose-tooling").to("androidx.compose.ui:ui-tooling-preview:$androidxComposeVersion")
|
||||
alias("androidx-compose-ui").to("androidx.compose.ui:ui:$androidxComposeVersion")
|
||||
alias("androidx-core").to("androidx.core:core-ktx:${androidxCoreVersion}")
|
||||
alias("androidx-viewmodel-compose").to("androidx.activity:activity-compose:$androidxActivityVersion")
|
||||
alias("google-material").to("com.google.android.material:material:${googleMaterialVersion}")
|
||||
alias("kotlin").to("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
|
||||
alias("kotlinx-coroutines-android").to("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinxCoroutinesVersion")
|
||||
alias("kotlinx-coroutines-core").to("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")
|
||||
alias("zcash").to("cash.z.ecc.android:zcash-android-sdk:${zcashSdkVersion}")
|
||||
|
||||
// Test libraries
|
||||
alias("androidx-espresso-contrib").to("androidx.test.espresso:espresso-contrib:${androidxEspressoVersion}")
|
||||
alias("androidx-espresso-core").to("androidx.test.espresso:espresso-core:${androidxEspressoVersion}")
|
||||
alias("androidx-espresso-intents").to("androidx.test.espresso:espresso-intents:${androidxEspressoVersion}")
|
||||
alias("androidx-junit").to("androidx.test.ext:junit:${androidxTestJunitVersion}")
|
||||
alias("androidx-testOrchestrator").to("androidx.test:orchestrator:${androidxTestOrchestratorVersion}")
|
||||
alias("androidx-uiAutomator").to("androidx.test.uiautomator:uiautomator-v18:${androidxUiAutomatorVersion}")
|
||||
alias("kotlinx-coroutines-test").to("org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinxCoroutinesVersion")
|
||||
|
||||
// Bundles
|
||||
bundle(
|
||||
"androidx-compose",
|
||||
listOf(
|
||||
"androidx-activity-compose",
|
||||
"androidx-compose-foundation",
|
||||
"androidx-compose-material",
|
||||
"androidx-compose-material-icons-core",
|
||||
"androidx-compose-tooling",
|
||||
"androidx-compose-ui",
|
||||
"androidx-viewmodel-compose"
|
||||
)
|
||||
)
|
||||
bundle(
|
||||
"androidx-test",
|
||||
listOf(
|
||||
"androidx-espresso-core",
|
||||
"androidx-espresso-intents",
|
||||
"androidx-espresso-contrib",
|
||||
"androidx-junit"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "zcash-android-app"
|
||||
|
||||
includeBuild("build-conventions")
|
||||
|
||||
include("app")
|
|
@ -0,0 +1,797 @@
|
|||
build:
|
||||
maxIssues: 0
|
||||
excludeCorrectable: false
|
||||
weights:
|
||||
# complexity: 2
|
||||
# LongParameterList: 1
|
||||
# style: 1
|
||||
# comments: 1
|
||||
|
||||
config:
|
||||
validation: true
|
||||
warningsAsErrors: false
|
||||
# when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
|
||||
excludes: ''
|
||||
|
||||
processors:
|
||||
active: true
|
||||
exclude:
|
||||
- 'DetektProgressListener'
|
||||
# - 'KtFileCountProcessor'
|
||||
# - 'PackageCountProcessor'
|
||||
# - 'ClassCountProcessor'
|
||||
# - 'FunctionCountProcessor'
|
||||
# - 'PropertyCountProcessor'
|
||||
# - 'ProjectComplexityProcessor'
|
||||
# - 'ProjectCognitiveComplexityProcessor'
|
||||
# - 'ProjectLLOCProcessor'
|
||||
# - 'ProjectCLOCProcessor'
|
||||
# - 'ProjectLOCProcessor'
|
||||
# - 'ProjectSLOCProcessor'
|
||||
# - 'LicenseHeaderLoaderExtension'
|
||||
|
||||
console-reports:
|
||||
active: true
|
||||
exclude:
|
||||
- 'ProjectStatisticsReport'
|
||||
- 'ComplexityReport'
|
||||
- 'NotificationReport'
|
||||
# - 'FindingsReport'
|
||||
- 'FileBasedFindingsReport'
|
||||
|
||||
output-reports:
|
||||
active: true
|
||||
exclude:
|
||||
# - 'TxtOutputReport'
|
||||
# - 'XmlOutputReport'
|
||||
# - 'HtmlOutputReport'
|
||||
|
||||
comments:
|
||||
active: true
|
||||
AbsentOrWrongFileLicense:
|
||||
active: false
|
||||
licenseTemplateFile: 'license.template'
|
||||
licenseTemplateIsRegex: false
|
||||
CommentOverPrivateFunction:
|
||||
active: false
|
||||
CommentOverPrivateProperty:
|
||||
active: false
|
||||
DeprecatedBlockTag:
|
||||
active: false
|
||||
EndOfSentenceFormat:
|
||||
active: false
|
||||
endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
|
||||
UndocumentedPublicClass:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
searchInNestedClass: true
|
||||
searchInInnerClass: true
|
||||
searchInInnerObject: true
|
||||
searchInInnerInterface: true
|
||||
UndocumentedPublicFunction:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
UndocumentedPublicProperty:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
|
||||
complexity:
|
||||
active: true
|
||||
ComplexCondition:
|
||||
active: true
|
||||
threshold: 4
|
||||
ComplexInterface:
|
||||
active: false
|
||||
threshold: 10
|
||||
includeStaticDeclarations: false
|
||||
includePrivateDeclarations: false
|
||||
ComplexMethod:
|
||||
active: true
|
||||
threshold: 15
|
||||
ignoreSingleWhenExpression: false
|
||||
ignoreSimpleWhenEntries: false
|
||||
ignoreNestingFunctions: false
|
||||
nestingFunctions:
|
||||
- 'also'
|
||||
- 'apply'
|
||||
- 'forEach'
|
||||
- 'isNotNull'
|
||||
- 'ifNull'
|
||||
- 'let'
|
||||
- 'run'
|
||||
- 'use'
|
||||
- 'with'
|
||||
LabeledExpression:
|
||||
active: false
|
||||
ignoredLabels: []
|
||||
LargeClass:
|
||||
active: true
|
||||
threshold: 600
|
||||
LongMethod:
|
||||
active: true
|
||||
threshold: 60
|
||||
ignoreAnnotated: []
|
||||
LongParameterList:
|
||||
active: true
|
||||
functionThreshold: 6
|
||||
constructorThreshold: 7
|
||||
ignoreDefaultParameters: false
|
||||
ignoreDataClasses: true
|
||||
ignoreAnnotated: []
|
||||
MethodOverloading:
|
||||
active: false
|
||||
threshold: 6
|
||||
NamedArguments:
|
||||
active: false
|
||||
threshold: 3
|
||||
NestedBlockDepth:
|
||||
active: true
|
||||
threshold: 4
|
||||
ReplaceSafeCallChainWithRun:
|
||||
active: false
|
||||
StringLiteralDuplication:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
threshold: 3
|
||||
ignoreAnnotation: true
|
||||
excludeStringsWithLessThan5Characters: true
|
||||
ignoreStringsRegex: '$^'
|
||||
TooManyFunctions:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
thresholdInFiles: 11
|
||||
thresholdInClasses: 11
|
||||
thresholdInInterfaces: 11
|
||||
thresholdInObjects: 11
|
||||
thresholdInEnums: 11
|
||||
ignoreDeprecated: false
|
||||
ignorePrivate: false
|
||||
ignoreOverridden: false
|
||||
|
||||
coroutines:
|
||||
active: true
|
||||
GlobalCoroutineUsage:
|
||||
active: false
|
||||
RedundantSuspendModifier:
|
||||
active: false
|
||||
SleepInsteadOfDelay:
|
||||
active: false
|
||||
SuspendFunWithFlowReturnType:
|
||||
active: false
|
||||
|
||||
empty-blocks:
|
||||
active: true
|
||||
EmptyCatchBlock:
|
||||
active: true
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
EmptyClassBlock:
|
||||
active: true
|
||||
EmptyDefaultConstructor:
|
||||
active: true
|
||||
EmptyDoWhileBlock:
|
||||
active: true
|
||||
EmptyElseBlock:
|
||||
active: true
|
||||
EmptyFinallyBlock:
|
||||
active: true
|
||||
EmptyForBlock:
|
||||
active: true
|
||||
EmptyFunctionBlock:
|
||||
active: true
|
||||
ignoreOverridden: false
|
||||
EmptyIfBlock:
|
||||
active: true
|
||||
EmptyInitBlock:
|
||||
active: true
|
||||
EmptyKtFile:
|
||||
active: true
|
||||
EmptySecondaryConstructor:
|
||||
active: true
|
||||
EmptyTryBlock:
|
||||
active: true
|
||||
EmptyWhenBlock:
|
||||
active: true
|
||||
EmptyWhileBlock:
|
||||
active: true
|
||||
|
||||
exceptions:
|
||||
active: true
|
||||
ExceptionRaisedInUnexpectedLocation:
|
||||
active: true
|
||||
methodNames:
|
||||
- 'equals'
|
||||
- 'finalize'
|
||||
- 'hashCode'
|
||||
- 'toString'
|
||||
InstanceOfCheckForException:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
NotImplementedDeclaration:
|
||||
active: false
|
||||
ObjectExtendsThrowable:
|
||||
active: false
|
||||
PrintStackTrace:
|
||||
active: true
|
||||
RethrowCaughtException:
|
||||
active: true
|
||||
ReturnFromFinally:
|
||||
active: true
|
||||
ignoreLabeled: false
|
||||
SwallowedException:
|
||||
active: true
|
||||
ignoredExceptionTypes:
|
||||
- 'InterruptedException'
|
||||
- 'MalformedURLException'
|
||||
- 'NumberFormatException'
|
||||
- 'ParseException'
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
ThrowingExceptionFromFinally:
|
||||
active: true
|
||||
ThrowingExceptionInMain:
|
||||
active: false
|
||||
ThrowingExceptionsWithoutMessageOrCause:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
exceptions:
|
||||
- 'ArrayIndexOutOfBoundsException'
|
||||
- 'Exception'
|
||||
- 'IllegalArgumentException'
|
||||
- 'IllegalMonitorStateException'
|
||||
- 'IllegalStateException'
|
||||
- 'IndexOutOfBoundsException'
|
||||
- 'NullPointerException'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
ThrowingNewInstanceOfSameException:
|
||||
active: true
|
||||
TooGenericExceptionCaught:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
exceptionNames:
|
||||
- 'ArrayIndexOutOfBoundsException'
|
||||
- 'Error'
|
||||
- 'Exception'
|
||||
- 'IllegalMonitorStateException'
|
||||
- 'IndexOutOfBoundsException'
|
||||
- 'NullPointerException'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
TooGenericExceptionThrown:
|
||||
active: true
|
||||
exceptionNames:
|
||||
- 'Error'
|
||||
- 'Exception'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
|
||||
formatting:
|
||||
active: true
|
||||
android: false
|
||||
autoCorrect: true
|
||||
AnnotationOnSeparateLine:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
AnnotationSpacing:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
ArgumentListWrapping:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
indentSize: 4
|
||||
maxLineLength: 120
|
||||
ChainWrapping:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
CommentSpacing:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
EnumEntryNameCase:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
Filename:
|
||||
active: true
|
||||
FinalNewline:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
insertFinalNewLine: true
|
||||
ImportOrdering:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
layout: '*,java.**,javax.**,kotlin.**,^'
|
||||
Indentation:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
indentSize: 4
|
||||
continuationIndentSize: 4
|
||||
MaximumLineLength:
|
||||
active: true
|
||||
maxLineLength: 120
|
||||
ignoreBackTickedIdentifier: false
|
||||
ModifierOrdering:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
MultiLineIfElse:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoBlankLineBeforeRbrace:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoConsecutiveBlankLines:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoEmptyClassBody:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoEmptyFirstLineInMethodBlock:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
NoLineBreakAfterElse:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoLineBreakBeforeAssignment:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoMultipleSpaces:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoSemicolons:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoTrailingSpaces:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoUnitReturn:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoUnusedImports:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoWildcardImports:
|
||||
active: true
|
||||
PackageName:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
ParameterListWrapping:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
indentSize: 4
|
||||
maxLineLength: 120
|
||||
SpacingAroundAngleBrackets:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
SpacingAroundColon:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundComma:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundCurly:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundDot:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundDoubleColon:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
SpacingAroundKeyword:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundOperators:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundParens:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundRangeOperator:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundUnaryOperator:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
SpacingBetweenDeclarationsWithAnnotations:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
SpacingBetweenDeclarationsWithComments:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
StringTemplate:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
|
||||
naming:
|
||||
active: true
|
||||
BooleanPropertyNaming:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
allowedPattern: '^(is|has|are)'
|
||||
ClassNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
classPattern: '[A-Z][a-zA-Z0-9]*'
|
||||
ConstructorParameterNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
privateParameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
ignoreOverridden: true
|
||||
EnumNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
|
||||
ForbiddenClassName:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
forbiddenName: []
|
||||
FunctionMaxLength:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
maximumFunctionNameLength: 30
|
||||
FunctionMinLength:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
minimumFunctionNameLength: 3
|
||||
FunctionNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
|
||||
excludeClassPattern: '$^'
|
||||
ignoreOverridden: true
|
||||
ignoreAnnotated:
|
||||
- 'Composable'
|
||||
FunctionParameterNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
ignoreOverridden: true
|
||||
InvalidPackageDeclaration:
|
||||
active: false
|
||||
excludes: ['**/*.kts']
|
||||
rootPackage: ''
|
||||
MatchingDeclarationName:
|
||||
active: true
|
||||
mustBeFirst: true
|
||||
MemberNameEqualsClassName:
|
||||
active: true
|
||||
ignoreOverridden: true
|
||||
NoNameShadowing:
|
||||
active: false
|
||||
NonBooleanPropertyPrefixedWithIs:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
ObjectPropertyNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
|
||||
PackageNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
|
||||
TopLevelPropertyNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
constantPattern: '[A-Z][_A-Z0-9]*'
|
||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
|
||||
VariableMaxLength:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
maximumVariableNameLength: 64
|
||||
VariableMinLength:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
minimumVariableNameLength: 1
|
||||
VariableNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
variablePattern: '[a-z][A-Za-z0-9]*'
|
||||
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
ignoreOverridden: true
|
||||
|
||||
performance:
|
||||
active: true
|
||||
ArrayPrimitive:
|
||||
active: true
|
||||
ForEachOnRange:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
SpreadOperator:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
UnnecessaryTemporaryInstantiation:
|
||||
active: true
|
||||
|
||||
potential-bugs:
|
||||
active: true
|
||||
AvoidReferentialEquality:
|
||||
active: false
|
||||
forbiddenTypePatterns:
|
||||
- 'kotlin.String'
|
||||
CastToNullableType:
|
||||
active: false
|
||||
Deprecation:
|
||||
active: false
|
||||
DontDowncastCollectionTypes:
|
||||
active: false
|
||||
DoubleMutabilityForCollection:
|
||||
active: false
|
||||
DuplicateCaseInWhenExpression:
|
||||
active: true
|
||||
EqualsAlwaysReturnsTrueOrFalse:
|
||||
active: true
|
||||
EqualsWithHashCodeExist:
|
||||
active: true
|
||||
ExitOutsideMain:
|
||||
active: false
|
||||
ExplicitGarbageCollectionCall:
|
||||
active: true
|
||||
HasPlatformType:
|
||||
active: false
|
||||
IgnoredReturnValue:
|
||||
active: false
|
||||
restrictToAnnotatedMethods: true
|
||||
returnValueAnnotations:
|
||||
- '*.CheckResult'
|
||||
- '*.CheckReturnValue'
|
||||
ignoreReturnValueAnnotations:
|
||||
- '*.CanIgnoreReturnValue'
|
||||
ImplicitDefaultLocale:
|
||||
active: true
|
||||
ImplicitUnitReturnType:
|
||||
active: false
|
||||
allowExplicitReturnType: true
|
||||
InvalidRange:
|
||||
active: true
|
||||
IteratorHasNextCallsNextMethod:
|
||||
active: true
|
||||
IteratorNotThrowingNoSuchElementException:
|
||||
active: true
|
||||
LateinitUsage:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
excludeAnnotatedProperties: []
|
||||
ignoreOnClassesPattern: ''
|
||||
MapGetWithNotNullAssertionOperator:
|
||||
active: false
|
||||
MissingWhenCase:
|
||||
active: true
|
||||
allowElseExpression: true
|
||||
NullableToStringCall:
|
||||
active: false
|
||||
RedundantElseInWhen:
|
||||
active: true
|
||||
UnconditionalJumpStatementInLoop:
|
||||
active: false
|
||||
UnnecessaryNotNullOperator:
|
||||
active: true
|
||||
UnnecessarySafeCall:
|
||||
active: true
|
||||
UnreachableCatchBlock:
|
||||
active: false
|
||||
UnreachableCode:
|
||||
active: true
|
||||
UnsafeCallOnNullableType:
|
||||
active: true
|
||||
UnsafeCast:
|
||||
active: true
|
||||
UnusedUnaryOperator:
|
||||
active: false
|
||||
UselessPostfixExpression:
|
||||
active: false
|
||||
WrongEqualsTypeParameter:
|
||||
active: true
|
||||
|
||||
style:
|
||||
active: true
|
||||
ClassOrdering:
|
||||
active: false
|
||||
CollapsibleIfStatements:
|
||||
active: false
|
||||
DataClassContainsFunctions:
|
||||
active: false
|
||||
conversionFunctionPrefix: 'to'
|
||||
DataClassShouldBeImmutable:
|
||||
active: false
|
||||
DestructuringDeclarationWithTooManyEntries:
|
||||
active: false
|
||||
maxDestructuringEntries: 3
|
||||
EqualsNullCall:
|
||||
active: true
|
||||
EqualsOnSignatureLine:
|
||||
active: false
|
||||
ExplicitCollectionElementAccessMethod:
|
||||
active: false
|
||||
ExplicitItLambdaParameter:
|
||||
active: false
|
||||
ExpressionBodySyntax:
|
||||
active: false
|
||||
includeLineWrapping: false
|
||||
ForbiddenComment:
|
||||
active: true
|
||||
values:
|
||||
- 'FIXME:'
|
||||
- 'STOPSHIP:'
|
||||
- 'TODO:'
|
||||
allowedPatterns: '\[[^\]]\d+\]'
|
||||
ForbiddenImport:
|
||||
active: false
|
||||
imports: []
|
||||
forbiddenPatterns: ''
|
||||
ForbiddenMethodCall:
|
||||
active: false
|
||||
methods:
|
||||
- 'kotlin.io.print'
|
||||
- 'kotlin.io.println'
|
||||
ForbiddenPublicDataClass:
|
||||
active: true
|
||||
excludes: ['**']
|
||||
ignorePackages:
|
||||
- '*.internal'
|
||||
- '*.internal.*'
|
||||
ForbiddenVoid:
|
||||
active: false
|
||||
ignoreOverridden: false
|
||||
ignoreUsageInGenerics: false
|
||||
FunctionOnlyReturningConstant:
|
||||
active: true
|
||||
ignoreOverridableFunction: true
|
||||
ignoreActualFunction: true
|
||||
excludedFunctions: ''
|
||||
excludeAnnotatedFunction:
|
||||
- 'dagger.Provides'
|
||||
LibraryCodeMustSpecifyReturnType:
|
||||
active: true
|
||||
excludes: ['**']
|
||||
LibraryEntitiesShouldNotBePublic:
|
||||
active: true
|
||||
excludes: ['**']
|
||||
LoopWithTooManyJumpStatements:
|
||||
active: true
|
||||
maxJumpCount: 1
|
||||
MagicNumber:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
ignoreNumbers:
|
||||
- '-1'
|
||||
- '0'
|
||||
- '1'
|
||||
- '2'
|
||||
ignoreHashCodeFunction: true
|
||||
ignorePropertyDeclaration: false
|
||||
ignoreLocalVariableDeclaration: false
|
||||
ignoreConstantDeclaration: true
|
||||
ignoreCompanionObjectPropertyDeclaration: true
|
||||
ignoreAnnotation: false
|
||||
ignoreNamedArgument: true
|
||||
ignoreEnums: false
|
||||
ignoreRanges: false
|
||||
ignoreExtensionFunctions: true
|
||||
MandatoryBracesIfStatements:
|
||||
active: false
|
||||
MandatoryBracesLoops:
|
||||
active: false
|
||||
MaxLineLength:
|
||||
active: true
|
||||
maxLineLength: 120
|
||||
excludePackageStatements: true
|
||||
excludeImportStatements: true
|
||||
excludeCommentStatements: false
|
||||
MayBeConst:
|
||||
active: true
|
||||
ModifierOrder:
|
||||
active: true
|
||||
MultilineLambdaItParameter:
|
||||
active: false
|
||||
NestedClassesVisibility:
|
||||
active: true
|
||||
NewLineAtEndOfFile:
|
||||
active: true
|
||||
NoTabs:
|
||||
active: false
|
||||
ObjectLiteralToLambda:
|
||||
active: false
|
||||
OptionalAbstractKeyword:
|
||||
active: true
|
||||
OptionalUnit:
|
||||
active: false
|
||||
OptionalWhenBraces:
|
||||
active: false
|
||||
PreferToOverPairSyntax:
|
||||
active: false
|
||||
ProtectedMemberInFinalClass:
|
||||
active: true
|
||||
RedundantExplicitType:
|
||||
active: false
|
||||
RedundantHigherOrderMapUsage:
|
||||
active: false
|
||||
RedundantVisibilityModifierRule:
|
||||
active: false
|
||||
ReturnCount:
|
||||
active: true
|
||||
max: 2
|
||||
excludedFunctions: 'equals'
|
||||
excludeLabeled: false
|
||||
excludeReturnFromLambda: true
|
||||
excludeGuardClauses: false
|
||||
SafeCast:
|
||||
active: true
|
||||
SerialVersionUIDInSerializableClass:
|
||||
active: true
|
||||
SpacingBetweenPackageAndImports:
|
||||
active: false
|
||||
ThrowsCount:
|
||||
active: true
|
||||
max: 2
|
||||
excludeGuardClauses: false
|
||||
TrailingWhitespace:
|
||||
active: false
|
||||
UnderscoresInNumericLiterals:
|
||||
active: false
|
||||
acceptableDecimalLength: 5
|
||||
UnnecessaryAbstractClass:
|
||||
active: true
|
||||
excludeAnnotatedClasses:
|
||||
- 'dagger.Module'
|
||||
UnnecessaryAnnotationUseSiteTarget:
|
||||
active: false
|
||||
UnnecessaryApply:
|
||||
active: true
|
||||
UnnecessaryFilter:
|
||||
active: false
|
||||
UnnecessaryInheritance:
|
||||
active: true
|
||||
UnnecessaryLet:
|
||||
active: false
|
||||
UnnecessaryParentheses:
|
||||
active: false
|
||||
UntilInsteadOfRangeTo:
|
||||
active: false
|
||||
UnusedImports:
|
||||
active: false
|
||||
UnusedPrivateClass:
|
||||
active: true
|
||||
UnusedPrivateMember:
|
||||
active: true
|
||||
allowedNames: '(_|ignored|expected|serialVersionUID)'
|
||||
UseArrayLiteralsInAnnotations:
|
||||
active: false
|
||||
UseCheckNotNull:
|
||||
active: false
|
||||
UseCheckOrError:
|
||||
active: false
|
||||
UseDataClass:
|
||||
active: false
|
||||
excludeAnnotatedClasses: []
|
||||
allowVars: false
|
||||
UseEmptyCounterpart:
|
||||
active: false
|
||||
UseIfEmptyOrIfBlank:
|
||||
active: false
|
||||
UseIfInsteadOfWhen:
|
||||
active: false
|
||||
UseIsNullOrEmpty:
|
||||
active: false
|
||||
UseOrEmpty:
|
||||
active: false
|
||||
UseRequire:
|
||||
active: false
|
||||
UseRequireNotNull:
|
||||
active: false
|
||||
UselessCallOnNotNull:
|
||||
active: true
|
||||
UtilityClassWithPublicConstructor:
|
||||
active: true
|
||||
VarCouldBeVal:
|
||||
active: true
|
||||
WildcardImport:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
excludeImports:
|
||||
- 'java.util.*'
|
||||
- 'kotlinx.android.synthetic.*'
|