@@ -13,6 +13,7 @@ import (
1313 "github.com/spf13/cobra"
1414 "github.com/steveyegge/gastown/internal/beads"
1515 "github.com/steveyegge/gastown/internal/config"
16+ "github.com/steveyegge/gastown/internal/formula"
1617 "github.com/steveyegge/gastown/internal/style"
1718 "github.com/steveyegge/gastown/internal/workspace"
1819 "golang.org/x/text/cases"
@@ -21,12 +22,15 @@ import (
2122
2223// Formula command flags
2324var (
24- formulaListJSON bool
25- formulaShowJSON bool
26- formulaRunPR int
27- formulaRunRig string
28- formulaRunDryRun bool
29- formulaCreateType string
25+ formulaListJSON bool
26+ formulaShowJSON bool
27+ formulaRunPR int
28+ formulaRunRig string
29+ formulaRunDryRun bool
30+ formulaCreateType string
31+ formulaFormatWrite bool
32+ formulaFormatCheck bool
33+ formulaFormatDiff bool
3034)
3135
3236var formulaCmd = & cobra.Command {
@@ -144,6 +148,26 @@ Examples:
144148 RunE : runFormulaCreate ,
145149}
146150
151+ var formulaFormatCmd = & cobra.Command {
152+ Use : "format [files...]" ,
153+ Short : "Format formula files for readable diffs" ,
154+ Long : `Format formula TOML files to use multi-line strings.
155+
156+ Converts single-line strings with \n escapes into triple-quoted
157+ multi-line strings, making diffs more readable.
158+
159+ By default, outputs formatted content to stdout. Use --write to
160+ modify files in-place.
161+
162+ Examples:
163+ gt formula format foo.formula.toml # Format to stdout
164+ gt formula format --write *.formula.toml # Format in-place
165+ gt formula format --check *.formula.toml # Check if formatting needed
166+ gt formula format --diff foo.formula.toml # Show diff of changes` ,
167+ Args : cobra .MinimumNArgs (1 ),
168+ RunE : runFormulaFormat ,
169+ }
170+
147171func init () {
148172 // List flags
149173 formulaListCmd .Flags ().BoolVar (& formulaListJSON , "json" , false , "Output as JSON" )
@@ -159,11 +183,17 @@ func init() {
159183 // Create flags
160184 formulaCreateCmd .Flags ().StringVar (& formulaCreateType , "type" , "task" , "Formula type: task, workflow, or patrol" )
161185
186+ // Format flags
187+ formulaFormatCmd .Flags ().BoolVar (& formulaFormatWrite , "write" , false , "Modify files in-place" )
188+ formulaFormatCmd .Flags ().BoolVar (& formulaFormatCheck , "check" , false , "Check if formatting needed (exit 1 if not formatted)" )
189+ formulaFormatCmd .Flags ().BoolVar (& formulaFormatDiff , "diff" , false , "Show diff of changes" )
190+
162191 // Add subcommands
163192 formulaCmd .AddCommand (formulaListCmd )
164193 formulaCmd .AddCommand (formulaShowCmd )
165194 formulaCmd .AddCommand (formulaRunCmd )
166195 formulaCmd .AddCommand (formulaCreateCmd )
196+ formulaCmd .AddCommand (formulaFormatCmd )
167197
168198 rootCmd .AddCommand (formulaCmd )
169199}
@@ -962,3 +992,74 @@ func promptYesNo(question string) bool {
962992 answer = strings .TrimSpace (strings .ToLower (answer ))
963993 return answer == "y" || answer == "yes"
964994}
995+
996+ // runFormulaFormat formats formula TOML files for readable diffs
997+ func runFormulaFormat (cmd * cobra.Command , args []string ) error {
998+ hasErrors := false
999+ needsFormatting := false
1000+
1001+ for _ , path := range args {
1002+ content , err := os .ReadFile (path )
1003+ if err != nil {
1004+ fmt .Fprintf (os .Stderr , "Error reading %s: %v\n " , path , err )
1005+ hasErrors = true
1006+ continue
1007+ }
1008+
1009+ formatted , changed , err := formula .FormatTOML (content )
1010+ if err != nil {
1011+ fmt .Fprintf (os .Stderr , "Error formatting %s: %v\n " , path , err )
1012+ hasErrors = true
1013+ continue
1014+ }
1015+
1016+ if formulaFormatCheck {
1017+ // Check mode: report if file needs formatting
1018+ if changed {
1019+ fmt .Printf ("%s needs formatting\n " , path )
1020+ needsFormatting = true
1021+ }
1022+ continue
1023+ }
1024+
1025+ if formulaFormatDiff {
1026+ // Diff mode: show what would change
1027+ if changed {
1028+ fmt .Printf ("--- %s (original)\n " , path )
1029+ fmt .Printf ("+++ %s (formatted)\n " , path )
1030+ // Simple diff: just show before/after
1031+ // For a real diff, we'd use a diff library
1032+ fmt .Println ("@@ changes @@" )
1033+ fmt .Println (string (formatted ))
1034+ } else {
1035+ fmt .Printf ("%s already formatted\n " , path )
1036+ }
1037+ continue
1038+ }
1039+
1040+ if formulaFormatWrite {
1041+ // Write mode: modify file in-place
1042+ if changed {
1043+ if err := os .WriteFile (path , formatted , 0644 ); err != nil {
1044+ fmt .Fprintf (os .Stderr , "Error writing %s: %v\n " , path , err )
1045+ hasErrors = true
1046+ continue
1047+ }
1048+ fmt .Printf ("%s Formatted %s\n " , style .Bold .Render ("✓" ), path )
1049+ } else {
1050+ fmt .Printf ("%s %s (no changes)\n " , style .Dim .Render ("-" ), path )
1051+ }
1052+ } else {
1053+ // Default: output to stdout
1054+ fmt .Print (string (formatted ))
1055+ }
1056+ }
1057+
1058+ if hasErrors {
1059+ return fmt .Errorf ("some files had errors" )
1060+ }
1061+ if formulaFormatCheck && needsFormatting {
1062+ return fmt .Errorf ("some files need formatting" )
1063+ }
1064+ return nil
1065+ }
0 commit comments