templatize_project.py packages an Android Studio project into a
Code On the Go (.cgt) template bundle by
applying the substitutions described in "Template Creation and
Installation". The original project directory is never modified — the
script copies it into a new bundle directory and templatizes the copy.
For each run, it:
- Creates a new output directory (default:
<project-dir>-cgt, next to the project). - Copies the project into that directory as a subdirectory (default name:
the project directory's name), skipping
.git. - Templatizes the copy:
- Replaces concrete values (Gradle/AGP/Kotlin versions, package name, app
name, SDK levels, Java compatibility levels) with Pebble tokens
(
${{ TOKEN }}). - Saves each modified file with a
.pebsuffix and removes the original. - Removes
build/directories. - Deletes common keystore files (
*.jks,*.keystore,*.p12) and flags other files that may contain machine-specific or personal information (local.properties,google-services.json,key.properties,GoogleService-Info.plist) for manual review.
- Replaces concrete values (Gradle/AGP/Kotlin versions, package name, app
name, SDK levels, Java compatibility levels) with Pebble tokens
(
- Writes a
templates.jsonat the top of the output directory, listing the template subdirectory. - Adds a
template/directory inside the copied project containingtemplate.json(the template's parameter/metadata schema) and a placeholdericon.png(replace with a real icon before shipping).
Both Kotlin DSL (build.gradle.kts) and Groovy DSL (build.gradle) projects
are supported.
python templatize_project.py <path-to-android-project> [--module app] [--dry-run] [--skip-cleanup] [--output-dir DIR] [--template-name NAME]
--module— app module directory name (default:app)--dry-run— preview changes against the original project directory without creating the output directory or writing/deleting anything--skip-cleanup— skipbuild/and keystore removal--output-dir— directory to create for the.cgtbundle (default:<project-dir>-cgt)--template-name— name of the template subdirectory /pathentry intemplates.json(default: the project directory's name)
gradle/wrapper/gradle-wrapper.properties— Gradle versionsettings.gradle.kts—rootProject.namebuild.gradle.kts/build.gradle(root) — AGP version<module>/build.gradle.kts/build.gradle— AGP/Kotlin plugin versions, namespace, applicationId, compileSdk, minSdk, targetSdk, Java source/target compatibility,kotlinOptions.jvmTarget<module>/src/main/res/values/strings.xml—app_name<module>/src/main/java/MainActivity.kt/MainActivity.java— package name
A line/segment that ends with a Pebble token must be followed by at least one character of whitespace, or the parser eats the next character (often a newline, quote, semicolon, or dot). The script inserts a sacrificial space after every inserted token — after the closing quote when the token is immediately followed by one, so the quote itself isn't eaten.
After running the script, inspect each generated .peb file in the output
directory to confirm the substitutions and spacing look right, replace the
placeholder icon.png, then package the output directory into a .cgt
file:
cd <output-dir> && zip -r -9 -D -X <destination>/<filename>.cgt *