diff --git a/README.md b/README.md index 4256cfbfa..2396869e5 100644 --- a/README.md +++ b/README.md @@ -102,10 +102,14 @@ All your pull requests must pass the CI build only then, it will be allowed to m Sometimes, when the build doesn't pass you can use these commands in your local terminal and check for the errors,
**We've commited to use Material3 design in our project. And added lint check for not to use any M2 libraries in our project.
** -**And when adding new library, please make sure to follow the naming convention and place in sequential order(A->Z).** +**And when adding new library, please make sure to follow the naming convention and place in sequential order(A->Z).
** In MacOS, Windows or Linux, you should run the following commands before opening a PR, and make sure to pass all the commands: +**In order to enhance our development process, we have implemented Git hooks in our project. +To install these hooks locally, simply run the command `./gradlew installGitHooks`. +This will ensure that the Git hooks are installed on your local machine.**
+ * `./gradlew check -p build-logic` this checks build-logic configured properly.
* `./gradlew spotlessApply --no-configuration-cache` an check and apply formatting to any file.
* `./gradlew dependencyGuardBaseline` to generate dependency-guard baseline.
diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index f4bf1069d..6a0f9ea3b 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -28,6 +28,9 @@ dependencies { compileOnly(libs.kotlin.gradlePlugin) compileOnly(libs.ksp.gradlePlugin) compileOnly(libs.room.gradlePlugin) + compileOnly(libs.detekt.gradlePlugin) + compileOnly(libs.ktlint.gradlePlugin) + compileOnly(libs.spotless.gradle) implementation(libs.truth) } @@ -88,5 +91,25 @@ gradlePlugin { id = "mifospay.android.application.flavors" implementationClass = "AndroidApplicationFlavorsConventionPlugin" } + register("detekt") { + id = "mifos.detekt.plugin" + implementationClass = "MifosDetektConventionPlugin" + description = "Configures detekt for the project" + } + register("spotless") { + id = "mifos.spotless.plugin" + implementationClass = "MifosSpotlessConventionPlugin" + description = "Configures spotless for the project" + } + register("ktlint") { + id = "mifos.ktlint.plugin" + implementationClass = "MifosKtlintConventionPlugin" + description = "Configures kotlinter for the project" + } + register("gitHooks") { + id = "mifos.git.hooks" + implementationClass = "MifosGitHooksConventionPlugin" + description = "Installs git hooks for the project" + } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index b6df4f6c3..b4f907e05 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -17,6 +17,10 @@ class AndroidApplicationConventionPlugin : Plugin { apply("org.jetbrains.kotlin.android") apply("mifospay.android.lint") apply("com.dropbox.dependency-guard") + apply("mifos.detekt.plugin") + apply("mifos.spotless.plugin") + apply("mifos.ktlint.plugin") + apply("mifos.git.hooks") } extensions.configure { diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index a749b93e6..e3967793e 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -18,6 +18,9 @@ class AndroidLibraryConventionPlugin : Plugin { apply("com.android.library") apply("org.jetbrains.kotlin.android") apply("mifospay.android.lint") + apply("mifos.detekt.plugin") + apply("mifos.spotless.plugin") + apply("mifos.ktlint.plugin") } extensions.configure { diff --git a/build-logic/convention/src/main/kotlin/MifosDetektConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MifosDetektConventionPlugin.kt new file mode 100644 index 000000000..970e0fefd --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MifosDetektConventionPlugin.kt @@ -0,0 +1,23 @@ + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.mifospay.configureDetekt +import org.mifospay.detektGradle + +class MifosDetektConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + applyPlugins() + + detektGradle { + configureDetekt(this) + } + } + } + + private fun Project.applyPlugins() { + pluginManager.apply { + apply("io.gitlab.arturbosch.detekt") + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/MifosGitHooksConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MifosGitHooksConventionPlugin.kt new file mode 100644 index 000000000..18208729a --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MifosGitHooksConventionPlugin.kt @@ -0,0 +1,54 @@ + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.Exec +import org.gradle.kotlin.dsl.register +import java.util.Locale + +class MifosGitHooksConventionPlugin : Plugin { + override fun apply(project: Project) { + // Define a function to check if the OS is Linux or MacOS + fun isLinuxOrMacOs(): Boolean { + val osName = System.getProperty("os.name").lowercase(Locale.getDefault()) + return osName.contains("linux") || osName.contains("mac os") || osName.contains("macos") + } + + // Define the copyGitHooks task + project.tasks.register("copyGitHooks") { + description = "Copies the git hooks from /scripts to the .git/hooks folder." + from("${project.rootDir}/scripts/") { + include("**/*.sh") + rename { it.removeSuffix(".sh") } + } + into("${project.rootDir}/.git/hooks") + } + + // Define the installGitHooks task + project.tasks.register("installGitHooks") { + description = "Installs the pre-commit git hooks from the scripts directory." + group = "git hooks" + workingDir = project.rootDir + + if (isLinuxOrMacOs()) { + commandLine("chmod", "-R", "+x", ".git/hooks/") + }else { + commandLine("cmd", "/c", "attrib", "-R", "+X", ".git/hooks/*.*") + } + dependsOn(project.tasks.named("copyGitHooks")) + + doLast { + println("Git hooks installed successfully.") + } + } + + // Configure task dependencies after evaluation + project.afterEvaluate { + project.tasks.matching { + it.name in listOf("preBuild", "build", "assembleDebug", "assembleRelease", "installDebug", "installRelease", "clean") + }.configureEach { + dependsOn(project.tasks.named("installGitHooks")) + } + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/MifosKtlintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MifosKtlintConventionPlugin.kt new file mode 100644 index 000000000..68afeb46e --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MifosKtlintConventionPlugin.kt @@ -0,0 +1,16 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project + +class MifosKtlintConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + applyPlugins() + } + } + + private fun Project.applyPlugins() { + pluginManager.apply { + apply("org.jlleitschuh.gradle.ktlint") + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/MifosSpotlessConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MifosSpotlessConventionPlugin.kt new file mode 100644 index 000000000..37201ce3d --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MifosSpotlessConventionPlugin.kt @@ -0,0 +1,22 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.mifospay.configureSpotless +import org.mifospay.spotlessGradle + +class MifosSpotlessConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + applyPlugins() + + spotlessGradle { + configureSpotless(this) + } + } + } + + private fun Project.applyPlugins() { + pluginManager.apply { + apply("com.diffplug.spotless") + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt b/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt new file mode 100644 index 000000000..1059d2da3 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/org/mifospay/Detekt.kt @@ -0,0 +1,23 @@ +package org.mifospay + +import io.gitlab.arturbosch.detekt.Detekt +import io.gitlab.arturbosch.detekt.extensions.DetektExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.named + +internal fun Project.configureDetekt(extension: DetektExtension) = extension.apply { + tasks.named("detekt") { + reports { + xml.required.set(true) + html.required.set(true) + txt.required.set(true) + sarif.required.set(true) + md.required.set(true) + } + } + dependencies { + "detektPlugins"(libs.findLibrary("detekt-formatting").get()) + "detektPlugins"(libs.findLibrary("twitter-detekt-compose").get()) + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/ProjectExtensions.kt b/build-logic/convention/src/main/kotlin/org/mifospay/ProjectExtensions.kt index 083999627..28fd88c0c 100644 --- a/build-logic/convention/src/main/kotlin/org/mifospay/ProjectExtensions.kt +++ b/build-logic/convention/src/main/kotlin/org/mifospay/ProjectExtensions.kt @@ -1,9 +1,22 @@ package org.mifospay +import com.diffplug.gradle.spotless.SpotlessExtension +import io.gitlab.arturbosch.detekt.extensions.DetektExtension import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalog import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.getByType val Project.libs get(): VersionCatalog = extensions.getByType().named("libs") + +inline fun Project.detektGradle(crossinline configure: DetektExtension.() -> Unit) = + extensions.configure { + configure() + } + +inline fun Project.spotlessGradle(crossinline configure: SpotlessExtension.() -> Unit) = + extensions.configure { + configure() + } \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/org/mifospay/Spotless.kt b/build-logic/convention/src/main/kotlin/org/mifospay/Spotless.kt new file mode 100644 index 000000000..871aeaa34 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/org/mifospay/Spotless.kt @@ -0,0 +1,31 @@ +package org.mifospay + +import com.diffplug.gradle.spotless.SpotlessExtension +import org.gradle.api.Project + +val ktlintVersion = "1.0.1" + +internal fun Project.configureSpotless(extension: SpotlessExtension) = extension.apply { + kotlin { + target("**/*.kt") + targetExclude("**/build/**/*.kt") + ktlint(ktlintVersion).editorConfigOverride( + mapOf("android" to "true"), + ) + licenseHeaderFile(rootProject.file("spotless/copyright.kt")) + } + + format("kts") { + target("**/*.kts") + targetExclude("**/build/**/*.kts") + // Look for the first line that doesn't have a block comment (assumed to be the license) + licenseHeaderFile(rootProject.file("spotless/copyright.kts"), "(^(?![\\/ ]\\*).*$)") + } + + format("xml") { + target("**/*.xml") + targetExclude("**/build/**/*.xml") + // Look for the first XML tag that isn't a comment (