Public Access
Running `draft new monorepo` with the Vue client and then `docker compose build client` failed three separate ways, each found by actually doing it: - No Dockerfile: the Vue overlay never shipped one. The template now has an nginx-based image (project-template#4) and the client-vue sync job embeds it plus its nginx.conf.template, with the pnpm pin rewritten to the local version like the Nuxt overlay. - Stale root lockfile: the Vue scaffold wrote a pnpm-workspace.yaml into apps/client (to approve vue-demi's build script), which made it its own workspace, so the installs updated a nested lockfile and the root one kept describing the template's Nuxt client - pnpm install --frozen-lockfile then refused it. The file is only written when the client isn't already inside a workspace (standalone `draft new client`). - Missing component: the client-vue job listed components by name, so the AuthCard.vue that Login/Signup import was never embedded. It now embeds src/components/ as a whole. Co-Authored-By: Claude Fable 5.1 <[email protected]>
133 lines
3.1 KiB
Go
133 lines
3.1 KiB
Go
//go:build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
oldModuleName = "app_tmpl"
|
|
moduleTemplate = "{{ .ModuleName }}"
|
|
)
|
|
|
|
type syncJob struct {
|
|
templateName string // optional, for logging purposes
|
|
sourceDir string
|
|
targetDir string
|
|
excludePrefix string // relative-path prefix to skip, e.g. "apps/"; empty = sync everything
|
|
includePrefixes []string // if set, only paths with one of these prefixes sync; empty = sync everything
|
|
}
|
|
|
|
var jobs = []syncJob{
|
|
{
|
|
templateName: "api",
|
|
sourceDir: "assets/testdata/template/apps/api",
|
|
targetDir: "assets/embedded/api",
|
|
},
|
|
{
|
|
templateName: "monorepo-root",
|
|
sourceDir: "assets/testdata/template",
|
|
targetDir: "assets/embedded/monorepo-root",
|
|
excludePrefix: "apps/",
|
|
},
|
|
{
|
|
templateName: "client-nuxt",
|
|
sourceDir: "assets/testdata/template/apps/client",
|
|
targetDir: "assets/embedded/client-nuxt",
|
|
includePrefixes: []string{"app/", "public/", "Dockerfile"},
|
|
},
|
|
{
|
|
templateName: "client-vue",
|
|
sourceDir: "assets/testdata/template/apps/vue-client",
|
|
targetDir: "assets/embedded/client-vue",
|
|
includePrefixes: []string{
|
|
"src/App.vue",
|
|
"src/main.ts",
|
|
"src/router/",
|
|
"src/stores/",
|
|
"src/composables/",
|
|
"src/lib/api-client.ts",
|
|
"src/components/",
|
|
"src/views/",
|
|
"src/shared/",
|
|
".env.example",
|
|
"Dockerfile",
|
|
"nginx.conf.template",
|
|
},
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
log.Println("Syncing templates...")
|
|
for _, job := range jobs {
|
|
syncTemplates(job)
|
|
}
|
|
}
|
|
|
|
func syncTemplates(job syncJob) {
|
|
|
|
err := os.RemoveAll(job.targetDir)
|
|
if err != nil {
|
|
log.Fatalf("Error removing target directory: %v", err)
|
|
}
|
|
|
|
cmd := exec.Command("git", "-C", job.sourceDir, "ls-files")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
log.Fatalf("Error listing files in source directory: %v", err)
|
|
}
|
|
|
|
paths := strings.Split(strings.TrimSpace(string(output)), "\n")
|
|
|
|
for _, relPath := range paths {
|
|
|
|
if len(job.includePrefixes) > 0 {
|
|
included := false
|
|
for _, prefix := range job.includePrefixes {
|
|
if strings.HasPrefix(relPath, prefix) {
|
|
included = true
|
|
break
|
|
}
|
|
}
|
|
if !included {
|
|
continue
|
|
}
|
|
} else if job.excludePrefix != "" && strings.HasPrefix(relPath, job.excludePrefix) {
|
|
continue
|
|
}
|
|
|
|
srcPath := filepath.Join(job.sourceDir, relPath)
|
|
destPath := filepath.Join(job.targetDir, relPath)
|
|
|
|
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
|
|
log.Fatalf("Error creating destination directory: %v", err)
|
|
}
|
|
|
|
content, err := os.ReadFile(srcPath)
|
|
if err != nil {
|
|
log.Fatalf("Error reading source file: %v", err)
|
|
}
|
|
|
|
if filepath.Base(relPath) == "go.mod" || filepath.Base(relPath) == "go.sum" {
|
|
destPath += ".tmpl"
|
|
}
|
|
|
|
if filepath.Base(relPath) == "go.mod" {
|
|
strContent := string(content)
|
|
strContent = strings.Replace(strContent, oldModuleName, moduleTemplate, 1)
|
|
content = []byte(strContent)
|
|
}
|
|
|
|
if err := os.WriteFile(destPath, content, 0644); err != nil {
|
|
log.Fatalf("Error writing to destination file: %v", err)
|
|
}
|
|
}
|
|
|
|
log.Printf("Template %s synced successfully!", job.templateName)
|
|
}
|