buildscript { repositories { mavenCentral() google() } dependencies { classpath 'com.android.tools.build:gradle:7.4.1' } } apply plugin: 'com.android.application' dependencies { implementation "androidx.core:core:1.9.0" implementation 'androidx.preference:preference:1.2.0' implementation "androidx.room:room-runtime:2.5.0" annotationProcessor "androidx.room:room-compiler:2.5.0" } repositories { mavenCentral() google() } def execThing ( String cmdStr ) { def stdout = new ByteArrayOutputStream() String prefix = System.getenv("GITCMDPREFIX") if (prefix != null) { String cmd = prefix + cmdStr exec { commandLine cmd.tokenize() standardOutput = stdout } } else { exec { commandLine cmdStr.tokenize() standardOutput = stdout } } return stdout.toString().trim() } def getCurrentGitHash = { -> return execThing('git log -1 --format=%h') } def getVersionCode = { -> String commitsCount = execThing("git rev-list --count HEAD") return Integer.valueOf(commitsCount) } def getVersionName = { -> // major version String versionTagsRaw = execThing('git tag --list v[0-9]*') int versionTagsCount = versionTagsRaw == "" ? 0 : versionTagsRaw.split('\n').size() // minor version String commitsSinceLastTag = "0" if (versionTagsCount > 1) { println "VERSION TAG: " + versionTagsCount String lastVersionTag = execThing('git describe --match v[0-9]* --tags --abbrev=0') String gitLogResult = execThing("git log $lastVersionTag..HEAD --oneline") commitsSinceLastTag = gitLogResult == '' ? "0" : gitLogResult.split('\n').size() } // the commit we are building from // beta string, if this is a beta String lastTagName = (execThing('git tag --list') == "") ? "" : execThing('git describe --tags --abbrev=0') String lastTagHash = (lastTagName == "") ? "" : execThing("git log -1 --format=%h $lastTagName") String betaString = lastTagHash == getCurrentGitHash() && lastTagName.contains("-beta") ? '-beta' : '' return "$versionTagsCount.$commitsSinceLastTag$betaString" } def getDebugVersion = { -> return "git-${getCurrentGitHash()} (debug)" } def getReleaseVersion = { -> return "${getVersionName()} (${getCurrentGitHash()})" } task validateDictionaries { inputs.dir fileTree(dir:'assets', excludes:['dict.properties']) outputs.file "${project.buildDir}/dict.validation.txt" doLast { final String csvDelimiter = ' ' // TAB String errors = "" int errorCount = 0 final MAX_ERRORS = 50 outputs.files.singleFile.text = "" inputs.getFiles().each {File file -> if (errorCount >= MAX_ERRORS) { return } println "Validating dictionary: " + file.name def geographicalName = ~"[A-Z]\\w+-[^\\n]+" def uniqueWords = [:] int lineNumber = 0 boolean isFileValid = true file.eachLine {line -> if (errorCount >= MAX_ERRORS) { return } lineNumber++ String[] parts = line.split(csvDelimiter, 2) String word = parts[0] String frequency = parts.length > 1 ? parts[1] : "" if (frequency.length() > 0 && !frequency.matches("^\\d+\$")) { isFileValid = false errorCount++ errors += "Dictionary '" + file.name + "' is invalid. Found out-of-range word frequency: '" + frequency + "' on line " + lineNumber + ". Frequency must be a non-negative integer. \n" } if (word.matches("(\\d.+?|.+?\\d|\\d)")) { isFileValid = false errorCount++ errors += "Dictionary '" + file.name + "' is invalid. Found numbers on line " + lineNumber + ". Please, remove all numbers.\n" } if (word.matches("^\\P{L}+\$")) { isFileValid = false errorCount++ errors += "Dictionary '" + file.name + "' is invalid. Found a garbage word: '" + word + "' on line " + lineNumber + ".\n" } if (word.matches("^.\$") && !Character.isUpperCase(word.charAt(0))) { isFileValid = false errorCount++ errors += "Dictionary '" + file.name + "' is invalid. Found a single letter: '" + word + "' on line " + lineNumber + ". Only uppercase single letters are allowed. The rest of the alphabet will be added automatically.\n" } String uniqueWordKey = word ==~ geographicalName ? word : word.toLowerCase() if (uniqueWords[uniqueWordKey] != null && uniqueWords[uniqueWordKey] == true) { isFileValid = false errorCount++ errors += "Dictionary '" + file.name + "' is invalid. Found a repeating word: '" + word + "' on line " + lineNumber + ". Ensure all words appear only once.\n" } else { uniqueWords[uniqueWordKey] = true } if (errorCount >= MAX_ERRORS ) { errors += "Too many errors! Aborting.\n" } } outputs.files.singleFile.text += file.name + " " + (isFileValid ? "OK" : "INVALID") + "\n" } if (errors != "") { throw new GradleException(errors) } } } android { buildToolsVersion "33.0.0" compileSdkVersion 33 namespace "io.github.sspanak.tt9" sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } // Move the build types to build-types/ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src//... which would // conflict with src/ being used by the main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') release.setRoot('build-types/release') } defaultConfig { minSdkVersion 19 targetSdk 30 versionCode getVersionCode() versionName getVersionName() } // http://stackoverflow.com/a/19130098 // signingConfigs { // release { // storeFile file(System.getenv("KEYSTORE")) // storePassword System.getenv("KEYSTORE_PASS") // keyAlias System.getenv("KEY_ALIAS") // keyPassword System.getenv("KEY_ALIAS_PASS") // } // } // buildTypes { debug { data -> data.buildConfigField 'String', 'VERSION_FULL', "\"${getDebugVersion()}\"" } release { data -> data.buildConfigField 'String', 'VERSION_FULL', "\"${getReleaseVersion()}\"" debuggable false jniDebuggable false renderscriptDebuggable false minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // signingConfig android.signingConfigs.release } } applicationVariants.all { variant -> tasks["merge${variant.name.capitalize()}Assets"].dependsOn(validateDictionaries) } }