Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
`kotlin-dsl`
`java-gradle-plugin`
}

repositories {
google()
mavenCentral()
}

gradlePlugin {
plugins {
create("secretsPlugin") {
id = "secrets-plugin"
implementationClass = "SecretsPlugin"
}
}
}
1 change: 1 addition & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = "build-logic"
110 changes: 110 additions & 0 deletions build-logic/src/main/kotlin/SecretsPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSetContainer
import java.io.File
import java.util.Properties

abstract class SecretsPlugin : Plugin<Project> {
override fun apply(project: Project) {
fun String.asRootFile() =
project.rootProject.file(this)

val secrets = SECRETS_FILE.asRootFile()
val dir = project.layout.buildDirectory.dir(OUTPUT_DIR)

val generateSecrets = project.tasks.register(TASK_NAME) {
outputs.dir(dir)
doLast {
if (!secrets.exists())
error(MISSING_SECRET_PROPS_ERROR_MSG)

val props = secrets.asProps()
if(props.useLocalMocks())
println(USE_LOCAL_MOCKS_MSG)

dir.get().asFile.resolve("$OUTPUT_FILE.kt").apply {
parentFile.mkdirs()
val text = with(props) {
if(useLocalMocks()) asUseLocalMocksText() else asSecretsText()
}
writeText(text)
}
}
}

project.afterEvaluate {
project.extensions.configure<SourceSetContainer>("sourceSets") {
getByName("main").java.srcDir(dir)
}
tasks.matching { it.name.matches(Regex(".*[k|K](?:otlin|tlint).*")) }.configureEach {
dependsOn(generateSecrets)
}
}

}

companion object {
private const val SECRETS_FILE = "secrets.properties"
private const val KEY_USE_LOCAL_MOCKS = "USE_LOCAL_MOCKS"
private const val OUTPUT_DIR = "generated/secrets"
private const val OUTPUT_FILE = "Secrets"
private const val TASK_NAME = "generateSecrets"

private val USE_LOCAL_MOCKS_MSG = """
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ️ INFO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
This project's '${SECRETS_FILE}' either does not contain the key '$KEY_USE_LOCAL_MOCKS' or its value is
set to true.

To use a local instance of Supabase-CLI, set this property to false and follow the instructions on the Roky
Wiki page under 'Project Setup' → 'Setup Supabase CLI':
> https://github.com/PPartisan/Roky/wiki/Project-Setup#3-setup-supabase-cli
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
""".trimIndent()

private val MISSING_SECRET_PROPS_ERROR_MSG = """
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ WARNING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Your project does not contain a '$SECRETS_FILE' file. Roky requires this file to run locally as it contains
information about your local Supabase-CLI setup.

To build Roky, create a file named '$SECRETS_FILE' in the root directory of this project and add the values
specified in the Roky Wiki page under 'Project Setup' → 'Setup Supabase CLI':
> https://github.com/PPartisan/Roky/wiki/Project-Setup#3-setup-supabase-cli
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
""".trimIndent()

private fun File.asProps() : Properties = Properties().apply {
inputStream().use { load(it) }
}

private fun Properties.getBool(key: String, default: Boolean = true) =
getProperty(key)?.toBoolean()?:default
private fun Properties.useLocalMocks() =
getBool(KEY_USE_LOCAL_MOCKS)

private fun Properties.asSecretsText() : String = buildString {
header()
this@asSecretsText.forEach { it.writeTo(this) }
footer()
}

private fun Properties.asUseLocalMocksText() : String = buildString {
header()
(KEY_USE_LOCAL_MOCKS to getBool(KEY_USE_LOCAL_MOCKS)).writeTo(this)
footer()
}

private fun Map.Entry<*, *>.writeTo(builder: StringBuilder) =
(key to value).writeTo(builder)
private fun Pair<*, *>.writeTo(builder: StringBuilder) =
builder.appendLine(""" const val $first = "$second"""")

private fun StringBuilder.header() =
appendLine("object $OUTPUT_FILE {")
private fun StringBuilder.footer() =
appendLine("}")
}
}
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
id("org.jetbrains.kotlinx.kover").version("0.8.3")
id("io.gitlab.arturbosch.detekt").version("1.23.3")
id("org.jlleitschuh.gradle.ktlint").version("12.1.2")
id("secrets-plugin")
}

group = "com.github.ppartisan.roky"
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Oct 07 19:40:39 BST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
3 changes: 3 additions & 0 deletions secrets.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Determines whether this project should use hardcoded mocks or Supabase-CLI.
# See https://github.com/PPartisan/Roky/wiki/Project-Setup
USE_LOCAL_MOCKS=true
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}
includeBuild("build-logic")
rootProject.name = "Roky"
25 changes: 0 additions & 25 deletions src/main/kotlin/Secrets.kt

This file was deleted.