plugins { id 'com.android.application' } apply from: 'constants.gradle' apply from: 'build-definitions.gradle' apply from: 'build-dictionaries.gradle' apply from: 'validate-languages.gradle' apply from: 'help-tools.gradle' apply from: 'status-icon-tools.gradle' apply from: 'version-tools.gradle' tasks.register('validateLanguages') { inputs.dir LANGUAGES_INPUT_DIR outputs.dir LANGUAGE_VALIDATION_DIR doLast { validateLanguageFiles(DEFINITIONS_INPUT_DIR, DICTIONARIES_INPUT_DIR, LANGUAGE_VALIDATION_DIR.get().asFile, ICONS_DIR) } } tasks.register('buildDefinition') { inputs.dir DEFINITIONS_INPUT_DIR outputs.file DEFINITIONS_OUTPUT_FILE doLast { mergeDefinitions(DEFINITIONS_INPUT_DIR, DEFINITIONS_OUTPUT_FILE) } } tasks.register('buildDictionaryDownloads') { inputs.dir LANGUAGES_INPUT_DIR outputs.dir DICTIONARIES_DOWNLOAD_DIR outputs.dir DICTIONARY_META_OUTPUT_DIR dependsOn validateLanguages mustRunAfter validateLanguages doLast { convertDictionaries(DEFINITIONS_INPUT_DIR, DICTIONARIES_INPUT_DIR, DICTIONARIES_DOWNLOAD_DIR, DICTIONARY_META_OUTPUT_DIR, ICONS_DIR) } } tasks.register('copyDownloadsToAssets', Copy) { from DICTIONARIES_DOWNLOAD_DIR include '**/*.zip' into DICTIONARIES_OUTPUT_DIR dependsOn buildDictionaryDownloads mustRunAfter buildDictionaryDownloads } tasks.register('generateDocs') { inputs.dir HELP_MARKDOWN_DIR inputs.file PRIVACY_POLICY_MARKDOWN outputs.dir DOCS_HTML_DIR doLast { convertDocs(HELP_MARKDOWN_DIR, PRIVACY_POLICY_MARKDOWN, DOCS_HTML_DIR) } } tasks.register('updateStatusIcons') { doLast { updateStatusIconCache(DEFINITIONS_INPUT_DIR, ICONS_DIR, ICONS_JAVA_FILE) } } tasks.register('updateManifest') { doLast { updateManifestVersion(getVersionCode(), getVersionName()) } } clean { delete LANGUAGES_OUTPUT_DIR delete DICTIONARIES_OUTPUT_DIR delete DICTIONARIES_DOWNLOAD_DIR delete DOCS_HTML_DIR } // using the exported Closures directly causes weird values, hence the extra wrappers here def getDonationUrl = { -> new File(FUNDING_FILE) .readLines().get(0).trim() .replaceFirst("^([^:]+)\\s*:\\s*([^\\n]+)", "https://\$1.com/\$2") .replace('_', '-') } def getVerCode = { -> return getVersionCode() } def getVerName = { -> return getVersionName() } def getVersionString = { flavor -> return flavor == 'debug' ? getDebugVersion() : getReleaseVersion() } android { namespace = PACKAGE_NAME compileSdk = 35 defaultConfig { applicationId = PACKAGE_NAME buildFeatures.buildConfig = true minSdk = 21 targetSdk = 35 versionCode = getVerCode() versionName = getVerName() buildConfigField 'String', 'DICTIONARY_EXTENSION', "\"${DICTIONARY_OUTPUT_EXTENSION}\"" buildConfigField 'String', 'DOCS_DIR', "\"${DOCS_DIR_NAME}\"" buildConfigField 'String', 'DONATION_URL', "\"${getDonationUrl()}\"" // F-droid hacks dependenciesInfo.includeInApk = false vectorDrawables.generatedDensities = [] } buildTypes { debug { buildConfigField 'String', 'VERSION_FULL', "\"${getVersionString('debug')}\"" } release { buildConfigField 'String', 'VERSION_FULL', "\"${getVersionString('release')}\"" debuggable = false jniDebuggable = false minifyEnabled = true shrinkResources = true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } flavorDimensions = ['app'] productFlavors { full { dimension 'app' buildConfigField 'Boolean', 'LITE', 'false' } lite { dimension 'app' buildConfigField 'Boolean', 'LITE', 'true' } } applicationVariants.configureEach { variant -> def variantName = variant.name.capitalize() tasks.named("javaPreCompile${variantName}")?.configure {dependsOn(updateStatusIcons) } [ "merge${variantName}Assets", "lintAnalyze${variantName}", "generate${variantName}LintReportModel", "lintVitalAnalyze${variantName}", "generate${variantName}LintVitalReportModel" ].each { taskName -> try { tasks.named(taskName)?.configure { dependsOn(buildDefinition, generateDocs, validateLanguages, buildDictionaryDownloads) } if (taskName.toLowerCase().contains("full")) { tasks.named(taskName)?.configure {dependsOn(copyDownloadsToAssets) } } } catch (UnknownTaskException ignored) {} } assembleLiteDebug.finalizedBy(updateManifest) assembleFullDebug.finalizedBy(updateManifest) assembleLiteRelease.finalizedBy(updateManifest) assembleFullRelease.finalizedBy(updateManifest) variant.outputs.configureEach { def fullSuffix = variant.flavorName == 'full' ? '-full' : '' def debugSuffix = variant.name.containsIgnoreCase('debug') ? '-debug' : '' outputFileName = "${APP_NAME}-v${getVerName()}${fullSuffix}${debugSuffix}.apk" } } } dependencies { implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.preference:preference:1.2.1' }