mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-24 23:01:22 -04:00
143 lines
5.4 KiB
Kotlin
143 lines
5.4 KiB
Kotlin
/*
|
|
* Copyright (c) 2026 Meshtastic LLC
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
plugins {
|
|
alias(libs.plugins.meshtastic.kmp.feature)
|
|
alias(libs.plugins.meshtastic.kotlinx.serialization)
|
|
id("meshtastic.kmp.jvm.android")
|
|
}
|
|
|
|
kotlin {
|
|
android {
|
|
namespace = "org.meshtastic.feature.docs"
|
|
androidResources.enable = true
|
|
}
|
|
|
|
sourceSets {
|
|
commonMain.dependencies {
|
|
implementation(projects.core.common)
|
|
implementation(projects.core.navigation)
|
|
implementation(projects.core.resources)
|
|
implementation(projects.core.ui)
|
|
implementation(projects.core.di)
|
|
|
|
implementation(libs.kotlinx.collections.immutable)
|
|
implementation(libs.jetbrains.compose.material3.adaptive)
|
|
implementation(libs.jetbrains.compose.material3.adaptive.navigation3)
|
|
implementation(libs.coil)
|
|
implementation(libs.markdown.renderer)
|
|
implementation(libs.markdown.renderer.m3)
|
|
}
|
|
|
|
commonTest.dependencies { implementation(libs.compose.multiplatform.ui.test) }
|
|
|
|
jvmTest.dependencies { implementation(compose.desktop.currentOs) }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sync task: copies markdown docs from the canonical `docs/` source directory into the CMP composeResources location.
|
|
* This eliminates manual content duplication and ensures the in-app bundled docs always reflect the source-of-truth.
|
|
*
|
|
* Usage: ./gradlew :feature:docs:syncDocsToComposeResources
|
|
*
|
|
* This task runs automatically before resource generation tasks.
|
|
*/
|
|
val syncDocsToComposeResources by
|
|
tasks.registering(Sync::class) {
|
|
description = "Syncs docs/en/ markdown source into composeResources for in-app bundling"
|
|
group = "docs"
|
|
|
|
val docsEnDir = rootProject.layout.projectDirectory.dir("docs/en")
|
|
val screenshotsDir = rootProject.layout.projectDirectory.dir("docs/screenshots")
|
|
val composeResourcesTarget = layout.projectDirectory.dir("src/commonMain/composeResources/files/docs")
|
|
|
|
from(docsEnDir) {
|
|
include("user/**/*.md")
|
|
include("developer/**/*.md")
|
|
}
|
|
|
|
// FR-038: Bundle screenshots into assets/screenshots/ to match markdown image paths.
|
|
// Markdown references use `assets/screenshots/foo.png` (relative to the doc page).
|
|
// copyDocsScreenshots flattens reference PNGs into docs/screenshots/,
|
|
// so we remap them into assets/screenshots/ within the compose resource tree.
|
|
from(screenshotsDir) {
|
|
include("**/*.png")
|
|
into("assets/screenshots")
|
|
}
|
|
|
|
into(composeResourcesTarget)
|
|
|
|
// Preserve timestamps for up-to-date checks
|
|
preserve { include("**/.gitkeep") }
|
|
}
|
|
|
|
// Wire sync task to run before any resource generation
|
|
tasks
|
|
.matching {
|
|
it.name.contains("generateComposeResClass") ||
|
|
it.name.contains("copyNonXmlValueResources") ||
|
|
it.name.contains("convertXmlValueResources")
|
|
}
|
|
.configureEach { dependsOn(syncDocsToComposeResources) }
|
|
|
|
// FR-038: Ensure screenshots are generated before syncing docs resources
|
|
syncDocsToComposeResources.configure { dependsOn(":screenshot-tests:copyDocsScreenshots") }
|
|
|
|
val syncTranslatedDocsToComposeResources by
|
|
tasks.registering(Copy::class) {
|
|
description = "Syncs Crowdin-translated docs into locale-qualified composeResources"
|
|
group = "docs"
|
|
|
|
val docsDir = rootProject.layout.projectDirectory.dir("docs")
|
|
val targetBase = layout.projectDirectory.dir("src/commonMain/composeResources/files")
|
|
|
|
from(docsDir) {
|
|
// Crowdin outputs dirs in Android qualifier format (fr, pt-rBR, zh-rCN)
|
|
include("*/user/**/*.md")
|
|
exclude("en/**")
|
|
exclude("_*/**")
|
|
exclude("assets/**")
|
|
exclude("screenshots/**")
|
|
}
|
|
|
|
into(targetBase)
|
|
|
|
// Crowdin %android_code% already outputs CMP qualifier format (pt-rBR).
|
|
// Locale goes as a subdirectory *inside* files/ (CMP doesn't support qualifiers on files/).
|
|
eachFile {
|
|
val segments = relativePath.segments
|
|
if (segments.size >= 3) {
|
|
val qualifier = segments[0]
|
|
val rest = segments.drop(1).joinToString("/")
|
|
// Output: files/{locale}/docs/user/page.md
|
|
// English source lives at: docs/en/$rest
|
|
path = "$qualifier/docs/$rest"
|
|
}
|
|
}
|
|
includeEmptyDirs = false
|
|
}
|
|
|
|
// Wire translated docs sync to resource generation alongside the primary sync
|
|
tasks
|
|
.matching {
|
|
it.name.contains("generateComposeResClass") ||
|
|
it.name.contains("copyNonXmlValueResources") ||
|
|
it.name.contains("convertXmlValueResources")
|
|
}
|
|
.configureEach { dependsOn(syncTranslatedDocsToComposeResources) }
|