Add a --write and --diff flag; require --write to be set before making any changes, for safety
This commit is contained in:
@@ -5,8 +5,12 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hexops/gotextdiff"
|
||||
"github.com/hexops/gotextdiff/myers"
|
||||
"github.com/hexops/gotextdiff/span"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -41,6 +45,9 @@ type Log struct {
|
||||
|
||||
func main() {
|
||||
configFile := flag.String("c", "./tesseract-staging.yaml", "Path to the YAML configuration file")
|
||||
wantDiff := flag.Bool("diff", false, "Show unified diff of changes")
|
||||
allowWrite := flag.Bool("write", false, "Allow writing files (required for actual file modifications)")
|
||||
noColor := flag.Bool("no-color", false, "Disable colored diff output")
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
@@ -51,15 +58,15 @@ func main() {
|
||||
|
||||
switch args[0] {
|
||||
case "gen-html":
|
||||
generateHTML(*configFile)
|
||||
generateHTML(*configFile, *wantDiff, *allowWrite, !*noColor)
|
||||
case "gen-env":
|
||||
generateEnv(*configFile)
|
||||
generateEnv(*configFile, *wantDiff, *allowWrite, !*noColor)
|
||||
case "gen-key":
|
||||
generateKeys(*configFile)
|
||||
generateKeys(*configFile, *wantDiff, *allowWrite, !*noColor)
|
||||
case "gen-nginx":
|
||||
generateNginx(*configFile)
|
||||
generateNginx(*configFile, *wantDiff, *allowWrite, !*noColor)
|
||||
case "gen-roots":
|
||||
generateRoots(args[1:])
|
||||
generateRoots(args[1:], *wantDiff, *allowWrite, !*noColor)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0])
|
||||
showHelp()
|
||||
@@ -97,17 +104,94 @@ func loadConfig(yamlFile string) Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func writeFileWithStatus(filename string, content []byte) error {
|
||||
// ANSI color codes
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorCyan = "\033[36m"
|
||||
)
|
||||
|
||||
// colorizeUnifiedDiff adds ANSI color codes to unified diff output
|
||||
func colorizeUnifiedDiff(diff string) string {
|
||||
lines := strings.Split(diff, "\n")
|
||||
var colorizedLines []string
|
||||
|
||||
for _, line := range lines {
|
||||
switch {
|
||||
case strings.HasPrefix(line, "---"):
|
||||
// File deletion header in cyan
|
||||
colorizedLines = append(colorizedLines, colorCyan+line+colorReset)
|
||||
case strings.HasPrefix(line, "+++"):
|
||||
// File addition header in cyan
|
||||
colorizedLines = append(colorizedLines, colorCyan+line+colorReset)
|
||||
case strings.HasPrefix(line, "@@"):
|
||||
// Hunk header in yellow
|
||||
colorizedLines = append(colorizedLines, colorYellow+line+colorReset)
|
||||
case strings.HasPrefix(line, "-"):
|
||||
// Deleted lines in red
|
||||
colorizedLines = append(colorizedLines, colorRed+line+colorReset)
|
||||
case strings.HasPrefix(line, "+"):
|
||||
// Added lines in green
|
||||
colorizedLines = append(colorizedLines, colorGreen+line+colorReset)
|
||||
default:
|
||||
// Context lines unchanged
|
||||
colorizedLines = append(colorizedLines, line)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(colorizedLines, "\n")
|
||||
}
|
||||
|
||||
func writeFileWithStatus(filename string, content []byte, wantDiff bool, allowWrite bool, useColor bool) error {
|
||||
existingContent, err := os.ReadFile(filename)
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Printf("Creating %s\n", filename)
|
||||
isNew := os.IsNotExist(err)
|
||||
isUnchanged := false
|
||||
|
||||
if isNew {
|
||||
if allowWrite {
|
||||
fmt.Printf("Creating %s\n", filename)
|
||||
} else {
|
||||
fmt.Printf("Would create %s\n", filename)
|
||||
}
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to read existing file %s: %v", filename, err)
|
||||
} else if string(existingContent) == string(content) {
|
||||
fmt.Printf("Unchanged %s\n", filename)
|
||||
return nil
|
||||
isUnchanged = true
|
||||
} else {
|
||||
fmt.Printf("Updating %s\n", filename)
|
||||
if allowWrite {
|
||||
fmt.Printf("Updating %s\n", filename)
|
||||
} else {
|
||||
fmt.Printf("Would update %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
if wantDiff && !isUnchanged {
|
||||
if isNew {
|
||||
// For new files, show the entire content as added
|
||||
edits := myers.ComputeEdits(span.URIFromPath(filename), "", string(content))
|
||||
diff := fmt.Sprint(gotextdiff.ToUnified("/dev/null", filename, "", edits))
|
||||
if useColor {
|
||||
fmt.Print(colorizeUnifiedDiff(diff))
|
||||
} else {
|
||||
fmt.Print(diff)
|
||||
}
|
||||
} else {
|
||||
// For existing files, show the diff
|
||||
edits := myers.ComputeEdits(span.URIFromPath(filename), string(existingContent), string(content))
|
||||
diff := fmt.Sprint(gotextdiff.ToUnified(filename, filename+".new", string(existingContent), edits))
|
||||
if useColor {
|
||||
fmt.Print(colorizeUnifiedDiff(diff))
|
||||
} else {
|
||||
fmt.Print(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isUnchanged || !allowWrite {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = os.WriteFile(filename, content, 0644)
|
||||
@@ -119,8 +203,17 @@ func writeFileWithStatus(filename string, content []byte) error {
|
||||
|
||||
func showHelp() {
|
||||
fmt.Printf("Usage: %s [options] <command>\n\n", os.Args[0])
|
||||
fmt.Printf("Note: Flags must come before the command name.\n\n")
|
||||
fmt.Printf("Options:\n")
|
||||
fmt.Printf(" -c <file> Path to YAML configuration file (default: ./tesseract-staging.yaml)\n\n")
|
||||
fmt.Printf(" -c <file> Path to YAML configuration file (default: ./tesseract-staging.yaml)\n")
|
||||
fmt.Printf(" --diff Show unified diff of changes without writing files\n")
|
||||
fmt.Printf(" --write Allow writing files (required for actual file modifications)\n")
|
||||
fmt.Printf(" --no-color Disable colored diff output\n\n")
|
||||
fmt.Printf("Examples:\n")
|
||||
fmt.Printf(" %s --diff gen-html # Show colored diffs without writing\n", os.Args[0])
|
||||
fmt.Printf(" %s --diff --no-color gen-html # Show plain diffs without writing\n", os.Args[0])
|
||||
fmt.Printf(" %s --write gen-html # Write files\n", os.Args[0])
|
||||
fmt.Printf(" %s --diff --write gen-html # Show colored diffs and write files\n\n", os.Args[0])
|
||||
fmt.Printf("Commands:\n")
|
||||
fmt.Printf(" gen-html Generate index.html and log.v3.json files in each log's localdirectory.\n")
|
||||
fmt.Printf(" Creates HTML pages with log information and CT log metadata JSON.\n")
|
||||
|
Reference in New Issue
Block a user