From c52311ce5ff4ced16397366ddba9397aa84c9649 Mon Sep 17 00:00:00 2001 From: vickydotbat Date: Sat, 18 Apr 2026 11:13:25 +0200 Subject: [PATCH] Add build-wiki command for isolated wiki generation - Add BuildWikiWithOptions in native.go for building wiki from pre-existing topdata - Add runBuildWiki and parseBuildWikiArgs in app.go for CLI integration - Add --force flag to force rebuild even when output is current --- internal/app/app.go | 45 ++++++++++++++++++++++++++++++++++++++ internal/topdata/native.go | 35 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/internal/app/app.go b/internal/app/app.go index 3a4d841..acbf09e 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -88,6 +88,11 @@ var commands = []command{ description: "Convert between 2DA and native topdata JSON/module formats.", run: runConvertTopData, }, + { + name: "build-wiki", + description: "Build wiki pages from the current topdata state.", + run: runBuildWiki, + }, } func Run(args []string) (int, error) { @@ -550,6 +555,46 @@ func runConvertTopData(ctx context) error { return topdata.RunConvertCommand(ctx.args[1:], ctx.stdout) } +func runBuildWiki(ctx context) error { + p, err := loadProject(ctx.cwd) + if err != nil { + return err + } + + opts, err := parseBuildWikiArgs("build-wiki", ctx.args[1:]) + if err != nil { + return err + } + + result, err := topdata.BuildWikiWithOptions(p, opts, func(message string) { + fmt.Fprintf(ctx.stdout, "[build-wiki] %s\n", message) + }) + if err != nil { + return err + } + + fmt.Fprintf(ctx.stdout, "project: %s\n", p.Config.Module.Name) + fmt.Fprintf(ctx.stdout, "wiki output: %s\n", result.OutputDir) + fmt.Fprintf(ctx.stdout, "wiki pages: %d\n", result.PageCount) + fmt.Fprintf(ctx.stdout, "wiki status: %s\n", result.Status) + return nil +} + +func parseBuildWikiArgs(commandName string, args []string) (topdata.BuildWikiOptions, error) { + opts := topdata.BuildWikiOptions{} + for _, arg := range args { + switch arg { + case "--force": + opts.Force = true + case "-h", "--help": + return opts, fmt.Errorf("usage: %s [--force]", commandName) + default: + return opts, fmt.Errorf("unknown %s argument %q", commandName, arg) + } + } + return opts, nil +} + func loadProject(cwd string) (*project.Project, error) { root, err := project.FindRoot(cwd) if err != nil { diff --git a/internal/topdata/native.go b/internal/topdata/native.go index 69fa35d..fbb97fa 100644 --- a/internal/topdata/native.go +++ b/internal/topdata/native.go @@ -139,6 +139,41 @@ type NativeBuildOptions struct { BuildWiki bool } +type BuildWikiOptions struct { + Force bool +} + +func BuildWikiWithOptions(p *project.Project, opts BuildWikiOptions, progress func(string)) (wikiResult, error) { + if progress == nil { + progress = func(string) {} + } + if !p.HasTopData() { + return wikiResult{}, errors.New("topdata is not configured for this project") + } + + output2DA := compiled2DAOutputDir(p) + outputTLK := compiledTLKOutputDir(p) + if _, err := os.Stat(output2DA); os.IsNotExist(err) { + return wikiResult{}, fmt.Errorf("topdata build output missing: run build-topdata first") + } + if _, err := os.Stat(outputTLK); os.IsNotExist(err) { + return wikiResult{}, fmt.Errorf("topdata tlk output missing: run build-topdata first") + } + + nativeResult := BuildResult{ + Mode: "native", + Output2DADir: output2DA, + OutputTLKDir: outputTLK, + } + + wikiBuild, err := buildWiki(p, nativeResult, progress) + if err != nil { + return wikiResult{}, err + } + + return wikiBuild, nil +} + func BuildNative(p *project.Project, progress func(string)) (BuildResult, error) { return BuildNativeWithOptions(p, NativeBuildOptions{BuildWiki: true}, progress) }