diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 00000000..36adc78e
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,9 @@
+name: PR
+
+on:
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ call-pr-workflow:
+ uses: FossifyOrg/.github/.github/workflows/pr.yml@main
diff --git a/.github/workflows/testing-build.yml b/.github/workflows/testing-build.yml
new file mode 100644
index 00000000..33379f92
--- /dev/null
+++ b/.github/workflows/testing-build.yml
@@ -0,0 +1,10 @@
+name: Testing build (on PR)
+
+on:
+ pull_request:
+ branches: [ master ]
+ types: [ labeled, opened, synchronize, reopened ]
+
+jobs:
+ call-testing-build-workflow:
+ uses: FossifyOrg/.github/.github/workflows/testing-build.yml@main
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 8d70afbf..227beb1e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -6,6 +6,7 @@ plugins {
alias(libs.plugins.android)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.ksp)
+ alias(libs.plugins.detekt)
}
val keystorePropertiesFile: File = rootProject.file("keystore.properties")
@@ -100,12 +101,18 @@ android {
lint {
checkReleaseBuilds = false
- abortOnError = false
+ abortOnError = true
+ warningsAsErrors = true
+ baseline = file("lint-baseline.xml")
}
namespace = "com.fossify.calculator"
}
+detekt {
+ baseline = file("detekt-baseline.xml")
+}
+
dependencies {
implementation(libs.fossify.commons)
implementation(libs.auto.fit.text.view)
diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml
new file mode 100644
index 00000000..c3265462
--- /dev/null
+++ b/app/detekt-baseline.xml
@@ -0,0 +1,93 @@
+
+
+
+
+ CyclomaticComplexMethod:CalculatorImpl.kt$CalculatorImpl$fun handleOperation(operation: String)
+ CyclomaticComplexMethod:CalculatorImpl.kt$CalculatorImpl$private fun calculateResult()
+ CyclomaticComplexMethod:MyWidgetProvider.kt$MyWidgetProvider$private fun myAction(action: String, context: Context)
+ EmptyFunctionBlock:WidgetConfigureActivity.kt$WidgetConfigureActivity.<no name provided>${}
+ ForEachOnRange:Context.kt$(0 until cnt).map { viewGroup.getChildAt(it) }
+ FunctionNaming:SettingsScreen.kt$@Composable internal fun SettingsScreen( goBack: () -> Unit, customizeColors: () -> Unit, customizeWidgetColors: () -> Unit, preventPhoneFromSleeping: Boolean, onPreventPhoneFromSleeping: (Boolean) -> Unit, vibrateOnButtonPressFlow: Boolean, onVibrateOnButtonPressFlow: (Boolean) -> Unit, isOrWasThankYouInstalled: Boolean, onThankYou: () -> Unit, isUseEnglishEnabled: Boolean, isUseEnglishChecked: Boolean, onUseEnglishPress: (Boolean) -> Unit, onSetupLanguagePress: () -> Unit, useCommaAsDecimalMarkFlow: Boolean, onUseCommaAsDecimalMarkFlow: (Boolean) -> Unit, lockedCustomizeColorText: String, displayLanguage: String, featureLockedDialogState: AlertDialogState )
+ FunctionNaming:SettingsScreen.kt$@MyDevices @Composable private fun SettingsScreenPreview()
+ LongMethod:CalculatorImpl.kt$CalculatorImpl$private fun calculateResult()
+ LongMethod:SettingsScreen.kt$@Composable internal fun SettingsScreen( goBack: () -> Unit, customizeColors: () -> Unit, customizeWidgetColors: () -> Unit, preventPhoneFromSleeping: Boolean, onPreventPhoneFromSleeping: (Boolean) -> Unit, vibrateOnButtonPressFlow: Boolean, onVibrateOnButtonPressFlow: (Boolean) -> Unit, isOrWasThankYouInstalled: Boolean, onThankYou: () -> Unit, isUseEnglishEnabled: Boolean, isUseEnglishChecked: Boolean, onUseEnglishPress: (Boolean) -> Unit, onSetupLanguagePress: () -> Unit, useCommaAsDecimalMarkFlow: Boolean, onUseCommaAsDecimalMarkFlow: (Boolean) -> Unit, lockedCustomizeColorText: String, displayLanguage: String, featureLockedDialogState: AlertDialogState )
+ LongParameterList:SettingsScreen.kt$( goBack: () -> Unit, customizeColors: () -> Unit, customizeWidgetColors: () -> Unit, preventPhoneFromSleeping: Boolean, onPreventPhoneFromSleeping: (Boolean) -> Unit, vibrateOnButtonPressFlow: Boolean, onVibrateOnButtonPressFlow: (Boolean) -> Unit, isOrWasThankYouInstalled: Boolean, onThankYou: () -> Unit, isUseEnglishEnabled: Boolean, isUseEnglishChecked: Boolean, onUseEnglishPress: (Boolean) -> Unit, onSetupLanguagePress: () -> Unit, useCommaAsDecimalMarkFlow: Boolean, onUseCommaAsDecimalMarkFlow: (Boolean) -> Unit, lockedCustomizeColorText: String, displayLanguage: String, featureLockedDialogState: AlertDialogState )
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$100
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$100f
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$3
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$4
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$5
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$6
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$7
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$8
+ MagicNumber:CalculatorImpl.kt$CalculatorImpl$9
+ MagicNumber:ConverterView.kt$ConverterView$3
+ MagicNumber:ConverterView.kt$ConverterView$4
+ MagicNumber:ConverterView.kt$ConverterView$5
+ MagicNumber:ConverterView.kt$ConverterView$6
+ MagicNumber:ConverterView.kt$ConverterView$7
+ MagicNumber:ConverterView.kt$ConverterView$8
+ MagicNumber:ConverterView.kt$ConverterView$9
+ MagicNumber:NumberFormatHelper.kt$NumberFormatHelper$12
+ MagicNumber:WidgetConfigureActivity.kt$WidgetConfigureActivity$100
+ MaxLineLength:AreaConverter.kt$AreaConverter.Unit$sealed
+ MaxLineLength:CalculatorDatabase.kt$CalculatorDatabase.Companion$db
+ MaxLineLength:CalculatorImpl.kt$CalculatorImpl$// handle percents manually, it doesn't seem to be possible via net.objecthunter:exp4j. "%" is used only for modulo there
+ MaxLineLength:CalculatorImpl.kt$CalculatorImpl$History(id = null, formula = newFormula, result = result.format(), timestamp = System.currentTimeMillis())
+ MaxLineLength:CalculatorImpl.kt$CalculatorImpl$if
+ MaxLineLength:CalculatorImpl.kt$CalculatorImpl$value == "0" && !valueToCheck.contains(operationsRegex.toRegex()) -> inputDisplayedFormula = "0$decimalSeparator"
+ MaxLineLength:Context.kt$// we are reusing the same layout in the app and widget, but cannot use MyTextView etc in a widget, so color regular view types like this
+ MaxLineLength:Context.kt$val
+ MaxLineLength:ConverterView.kt$ConverterView$private
+ MaxLineLength:ConverterView.kt$ConverterView$val bgLayer = bgLayerList.findDrawableByLayerId(org.fossify.commons.R.id.button_pill_background_shape) as GradientDrawable
+ MaxLineLength:ConverterView.kt$ConverterView$val bgLayerList = drawable.findDrawableByLayerId(org.fossify.commons.R.id.button_pill_background_holder) as LayerDrawable
+ MaxLineLength:ConverterView.kt$ConverterView$val converted = convert(topUnit!!.withValue(formatter.removeGroupingSeparator(binding.topUnitText.text.toString()).toDouble()), bottomUnit!!).value
+ MaxLineLength:ConverterView.kt$ConverterView$val width = listOf(symbolHeight, binding.topUnitSymbol.measuredWidth, binding.bottomUnitSymbol.measuredWidth).max()
+ MaxLineLength:HistoryAdapter.kt$HistoryAdapter$class
+ MaxLineLength:LengthConverter.kt$LengthConverter.Unit$sealed
+ MaxLineLength:MainActivity.kt$MainActivity$arrayOf(btnPercent, btnPower, btnRoot, btnClear, btnReset, btnDivide, btnMultiply, btnPlus, btnMinus, btnEquals, btnDecimal)
+ MaxLineLength:MainActivity.kt$MainActivity$faqItems.add(FAQItem(org.fossify.commons.R.string.faq_2_title_commons, org.fossify.commons.R.string.faq_2_text_commons))
+ MaxLineLength:MainActivity.kt$MainActivity$faqItems.add(FAQItem(org.fossify.commons.R.string.faq_6_title_commons, org.fossify.commons.R.string.faq_6_text_commons))
+ MaxLineLength:MainActivity.kt$MainActivity$findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations)
+ MaxLineLength:MainActivity.kt$MainActivity$it?.background = ResourcesCompat.getDrawable(resources, org.fossify.commons.R.drawable.pill_background, theme)
+ MaxLineLength:MainActivity.kt$MainActivity$updateMaterialActivityViews(binding.mainCoordinator, null, useTransparentNavigation = false, useTopSearchMenu = false)
+ MaxLineLength:MassConverter.kt$MassConverter.Unit$sealed
+ MaxLineLength:MyWidgetProvider.kt$MyWidgetProvider$DECIMAL
+ MaxLineLength:MyWidgetProvider.kt$MyWidgetProvider$R.id.btn_7
+ MaxLineLength:MyWidgetProvider.kt$MyWidgetProvider$R.id.formula
+ MaxLineLength:SettingsActivity.kt$SettingsActivity$val preventPhoneFromSleeping by preferences.preventPhoneFromSleepingFlow.collectAsStateWithLifecycle(preferences.preventPhoneFromSleeping)
+ MaxLineLength:SettingsActivity.kt$SettingsActivity$val useCommaAsDecimalMarkFlow by preferences.useCommaAsDecimalMarkFlow.collectAsStateWithLifecycle(preferences.useCommaAsDecimalMark)
+ MaxLineLength:SettingsActivity.kt$SettingsActivity$val vibrateOnButtonPressFlow by preferences.vibrateOnButtonPressFlow.collectAsStateWithLifecycle(preferences.vibrateOnButtonPress)
+ MaxLineLength:SettingsActivity.kt$SettingsActivity$val wasUseEnglishToggledFlow by preferences.wasUseEnglishToggledFlow.collectAsStateWithLifecycle(preferences.wasUseEnglishToggled)
+ MaxLineLength:TemperatureConverter.kt$TemperatureConverter.Unit$sealed
+ MaxLineLength:TimeConverter.kt$TimeConverter.Unit$sealed
+ MaxLineLength:UnitConverterActivity.kt$UnitConverterActivity$it.background = ResourcesCompat.getDrawable(resources, org.fossify.commons.R.drawable.pill_background, theme)
+ MaxLineLength:UnitConverterActivity.kt$UnitConverterActivity$updateMaterialActivityViews(binding.unitConverterCoordinator, null, useTransparentNavigation = false, useTopSearchMenu = false)
+ MaxLineLength:UnitConverterPickerActivity.kt$UnitConverterPickerActivity$binding.unitTypesGrid.layoutManager = AutoGridLayoutManager(this, resources.getDimensionPixelSize(R.dimen.unit_type_size))
+ MaxLineLength:UnitConverterPickerActivity.kt$UnitConverterPickerActivity$updateMaterialActivityViews(binding.unitConverterPickerCoordinator, null, useTransparentNavigation = false, useTopSearchMenu = false)
+ MaxLineLength:UnitTypesAdapter.kt$UnitTypesAdapter.ViewHolder$layerDrawable.findDrawableByLayerId(R.id.background_shape).applyColorFilter(context.getProperBackgroundColor().darkenColor(2))
+ MaxLineLength:UnitTypesAdapter.kt$UnitTypesAdapter.ViewHolder$val rippleBg = ResourcesCompat.getDrawable(resources, R.drawable.unit_type_background, context.theme) as RippleDrawable
+ MaxLineLength:VolumeConverter.kt$VolumeConverter.Unit$sealed
+ MaxLineLength:WidgetConfigureActivity.kt$WidgetConfigureActivity$R.id.btn_9
+ MaxLineLength:WidgetConfigureActivity.kt$WidgetConfigureActivity$if
+ NestedBlockDepth:CalculatorImpl.kt$CalculatorImpl$fun handleOperation(operation: String)
+ NestedBlockDepth:CalculatorImpl.kt$CalculatorImpl$private fun calculateResult()
+ ReturnCount:CalculatorImpl.kt$CalculatorImpl$fun turnToNegative(): Boolean
+ ReturnCount:CalculatorImpl.kt$CalculatorImpl$private fun calculateResult()
+ SwallowedException:CalculatorImpl.kt$CalculatorImpl$e: Exception
+ TooGenericExceptionCaught:CalculatorImpl.kt$CalculatorImpl$e: Exception
+ TooGenericExceptionCaught:Context.kt$e: Exception
+ TooManyFunctions:CalculatorImpl.kt$CalculatorImpl
+ TooManyFunctions:ConverterView.kt$ConverterView : LinearLayout
+ TooManyFunctions:MainActivity.kt$MainActivity : SimpleActivityCalculator
+ TooManyFunctions:MyWidgetProvider.kt$MyWidgetProvider : AppWidgetProviderCalculator
+ UnusedPrivateMember:SettingsScreen.kt$@MyDevices @Composable private fun SettingsScreenPreview()
+ WildcardImport:ConverterView.kt$import org.fossify.calculator.helpers.*
+ WildcardImport:ConverterView.kt$import org.fossify.commons.extensions.*
+ WildcardImport:MainActivity.kt$import org.fossify.calculator.helpers.*
+ WildcardImport:MainActivity.kt$import org.fossify.commons.extensions.*
+ WildcardImport:SettingsActivity.kt$import org.fossify.commons.helpers.*
+ WildcardImport:UnitTypesAdapter.kt$import org.fossify.commons.extensions.*
+ WildcardImport:WidgetConfigureActivity.kt$import org.fossify.commons.extensions.*
+
+
diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml
new file mode 100644
index 00000000..647e2c11
--- /dev/null
+++ b/app/lint-baseline.xml
@@ -0,0 +1,2417 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 9a736eea..b7bc0032 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,4 +2,5 @@ plugins {
alias(libs.plugins.android).apply(false)
alias(libs.plugins.kotlinAndroid).apply(false)
alias(libs.plugins.ksp).apply(false)
+ alias(libs.plugins.detekt).apply(false)
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 30456587..89f9b817 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,6 +3,8 @@
kotlin = "1.9.24"
#KSP
ksp = "1.9.24-1.0.20"
+#Detekt
+detekt = "1.23.3"
#Androidx
androidx-customView = "1.2.0-alpha02"
androidx-customViewPooling = "1.0.0"
@@ -95,4 +97,4 @@ lifecycle = [
android = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
-
+detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }