// Copyright 2026 Alibaba Group // Licensed under the Apache License, Version 2.0 // Command cmd_command_path_fallbacks validates the reviewed recovery-only // command path table against the live distribution Cobra tree and writes the // deterministic runtime lookup source. It does not add paths to Cobra, Help, // Skill, Schema, or the stable CommandRegistry identity surface. package main import ( "bytes" "flag" "fmt" "go/format" "os" "strings" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/app" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/generator/outputguard" ) const defaultOutput = "internal/cli/command_path_fallbacks_generated.go" var ( newCommandFallbackRoot = app.NewSchemaSourceRootCommand reduceCommandFallbackEntries = cli.ReduceCommandPathFallbacks formatCommandFallbackSource = format.Source writeCommandFallbackFile = os.WriteFile exitCommandFallbackProcess = os.Exit ) func main() { var rootPath string var outputPath string flag.StringVar(&rootPath, "root", ".", "Repository root used to protect generator inputs") flag.StringVar(&outputPath, "output", defaultOutput, "Output generated command-path fallback table") flag.Parse() if err := generateCommandPathFallbacks(rootPath, outputPath); err != nil { fail(err) } } func generateCommandPathFallbacks(rootPath, outputPath string) error { if err := validateOutputIsolation(rootPath, outputPath); err != nil { return err } entries, err := reduceCommandFallbackEntries(newCommandFallbackRoot()) if err != nil { return err } source, err := renderCommandPathFallbacks(entries) if err != nil { return err } if err := writeCommandFallbackFile(outputPath, source, 0o644); err != nil { return fmt.Errorf("write generated command path fallbacks: %w", err) } _, _ = fmt.Fprintf(os.Stderr, "generated command path fallbacks: output=%s entries=%d\n", outputPath, len(entries)) return nil } func validateOutputIsolation(rootPath, outputPath string) error { inputs := []outputguard.Input{ {Name: "reviewed command path fallbacks", Path: "internal/cli/command_path_fallbacks.json"}, {Name: "reviewed command path fallback schema", Path: "internal/cli/command_path_fallbacks.schema.json"}, } target := outputguard.Target{Name: "--output", Path: outputPath} if err := outputguard.Validate(rootPath, inputs, []outputguard.Target{target}); err != nil { return err } return outputguard.ValidateRepoTargetAllowlist(rootPath, target, defaultOutput) } func renderCommandPathFallbacks(entries []cli.CommandPathFallback) ([]byte, error) { var b bytes.Buffer b.WriteString("// Copyright 2026 Alibaba Group\n") b.WriteString("// Licensed under the Apache License, Version 2.0\n\n") b.WriteString("// Code generated by cmd_command_path_fallbacks; DO NOT EDIT.\n") b.WriteString("// Source: internal/cli/command_path_fallbacks.json validated against the live Cobra tree.\n") b.WriteString("// Regenerate with `make generate-schema` (or `go generate ./internal/cli`).\n\n") b.WriteString("package cli\n\n") b.WriteString("var generatedCommandPathFallbacks = []CommandPathFallback{\n") for _, entry := range entries { b.WriteString("\t{\n") fmt.Fprintf(&b, "\t\tFrom: %q,\n", entry.From) fmt.Fprintf(&b, "\t\tMode: %q,\n", entry.Mode) if entry.To != "" { fmt.Fprintf(&b, "\t\tTo: %q,\n", entry.To) } if len(entry.Candidates) > 0 { fmt.Fprintf(&b, "\t\tCandidates: %s,\n", renderStringSlice(entry.Candidates)) } b.WriteString("\t\tReviewed: true,\n") fmt.Fprintf(&b, "\t\tReviewReason: %q,\n", entry.ReviewReason) b.WriteString("\t},\n") } b.WriteString("}\n\n") b.WriteString("func loadGeneratedCommandPathFallbacks() []CommandPathFallback {\n") b.WriteString("\treturn generatedCommandPathFallbacks\n") b.WriteString("}\n") formatted, err := formatCommandFallbackSource(b.Bytes()) if err != nil { return nil, fmt.Errorf("format generated command path fallbacks: %w", err) } return formatted, nil } func renderStringSlice(values []string) string { quoted := make([]string, len(values)) for index, value := range values { quoted[index] = fmt.Sprintf("%q", value) } return "[]string{" + strings.Join(quoted, ", ") + "}" } func fail(err error) { _, _ = fmt.Fprintln(os.Stderr, "error:", err) exitCommandFallbackProcess(1) }