Partially rework reading args to modify command loading

This commit is contained in:
2025-03-27 21:39:07 +01:00
parent 912950d463
commit 76457d22cf

226
main.go
View File

@@ -30,10 +30,36 @@ var (
gitFlag = flag.Bool("git", false, "Use git to manage files") gitFlag = flag.Bool("git", false, "Use git to manage files")
resetFlag = flag.Bool("reset", false, "Reset files to their original state") resetFlag = flag.Bool("reset", false, "Reset files to their original state")
logLevel = flag.String("loglevel", "INFO", "Set log level: ERROR, WARNING, INFO, DEBUG, TRACE") logLevel = flag.String("loglevel", "INFO", "Set log level: ERROR, WARNING, INFO, DEBUG, TRACE")
cookfile = flag.String("cook", "**/cook.yml", "Path to cook config files, can be globbed")
repo *git.Repository repo *git.Repository
worktree *git.Worktree worktree *git.Worktree
) )
type ModifyCommand struct {
Pattern string `yaml:"pattern"`
LuaExpr string `yaml:"lua"`
Files []string `yaml:"files"`
Git bool `yaml:"git"`
Reset bool `yaml:"reset"`
LogLevel string `yaml:"loglevel"`
}
func (c *ModifyCommand) Validate() error {
if c.Pattern == "" {
return fmt.Errorf("pattern is required")
}
if c.LuaExpr == "" {
return fmt.Errorf("lua expression is required")
}
if len(c.Files) == 0 {
return fmt.Errorf("at least one file is required")
}
if c.LogLevel == "" {
c.LogLevel = "INFO"
}
return nil
}
func main() { func main() {
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [options] <pattern> <lua_expression> <...files_or_globs>\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Usage: %s [options] <pattern> <lua_expression> <...files_or_globs>\n", os.Args[0])
@@ -56,112 +82,106 @@ func main() {
fmt.Fprintf(os.Stderr, " Glob patterns are supported for file selection (*.xml, data/**.xml, etc.)\n") fmt.Fprintf(os.Stderr, " Glob patterns are supported for file selection (*.xml, data/**.xml, etc.)\n")
} }
flag.Parse() flag.Parse()
args := flag.Args()
// Initialize logger with the specified log level
level := logger.ParseLevel(*logLevel) level := logger.ParseLevel(*logLevel)
logger.Init(level) logger.Init(level)
logger.Info("Initializing with log level: %s", level.String()) logger.Info("Initializing with log level: %s", level.String())
args := flag.Args() commands := []ModifyCommand{}
// Cannot reset without git, right? var err error
if *resetFlag { commands, err = LoadCommandsFromCookFiles(*cookfile, commands)
*gitFlag = true if err != nil {
} logger.Error("Failed to load commands from cook files: %v", err)
if len(args) < 3 {
logger.Error("At least %d arguments are required", 3)
flag.Usage() flag.Usage()
return return
} }
var pattern, luaExpr string commands, err = LoadCommandFromArgs(args, commands)
var filePatterns []string
pattern = args[0]
luaExpr = args[1]
filePatterns = args[2:]
if *gitFlag {
logger.Info("Git integration enabled, setting up git repository")
err := setupGit()
if err != nil {
logger.Error("Failed to setup git: %v", err)
fmt.Fprintf(os.Stderr, "Error setting up git: %v\n", err)
return
}
}
// Expand file patterns with glob support
logger.Debug("Expanding file patterns: %v", filePatterns)
files, err := expandFilePatterns(filePatterns)
if err != nil { if err != nil {
logger.Error("Failed to expand file patterns: %v", err) logger.Error("Failed to load commands from args: %v", err)
fmt.Fprintf(os.Stderr, "Error expanding file patterns: %v\n", err) flag.Usage()
return return
} }
// Use this to clone loggers for individual commands
// logger.WithField("loglevel", level.String())
if len(files) == 0 { // if *gitFlag {
logger.Warning("No files found matching the specified patterns") // logger.Info("Git integration enabled, setting up git repository")
fmt.Fprintf(os.Stderr, "No files found matching the specified patterns\n") // err := setupGit()
return // if err != nil {
} // logger.Error("Failed to setup git: %v", err)
// fmt.Fprintf(os.Stderr, "Error setting up git: %v\n", err)
// return
// }
// }
if *gitFlag { // logger.Debug("Expanding file patterns")
logger.Info("Cleaning up git files before processing") // files, err := expandFilePatterns(filePatterns)
err := cleanupGitFiles(files) // if err != nil {
if err != nil { // logger.Error("Failed to expand file patterns: %v", err)
logger.Error("Failed to cleanup git files: %v", err) // fmt.Fprintf(os.Stderr, "Error expanding file patterns: %v\n", err)
fmt.Fprintf(os.Stderr, "Error cleaning up git files: %v\n", err) // return
return // }
}
} // if len(files) == 0 {
if *resetFlag { // logger.Warning("No files found matching the specified patterns")
logger.Info("Files reset to their original state, nothing more to do") // fmt.Fprintf(os.Stderr, "No files found matching the specified patterns\n")
log.Printf("Files reset to their original state, nothing more to do") // return
return // }
}
// if *gitFlag {
// logger.Info("Cleaning up git files before processing")
// err := cleanupGitFiles(files)
// if err != nil {
// logger.Error("Failed to cleanup git files: %v", err)
// fmt.Fprintf(os.Stderr, "Error cleaning up git files: %v\n", err)
// return
// }
// }
// if *resetFlag {
// logger.Info("Files reset to their original state, nothing more to do")
// log.Printf("Files reset to their original state, nothing more to do")
// return
// }
// Create the processor based on mode // Create the processor based on mode
var proc processor.Processor var proc processor.Processor = &processor.RegexProcessor{}
switch {
default:
proc = &processor.RegexProcessor{}
logger.Info("Starting regex modifier with pattern %q, expression %q on %d files",
pattern, luaExpr, len(files))
}
var wg sync.WaitGroup var wg sync.WaitGroup
log.Printf("%#v", proc)
log.Printf("%#v", wg)
// Process each file // Process each file
for _, file := range files { // for _, file := range files {
wg.Add(1) // wg.Add(1)
logger.SafeGoWithArgs(func(args ...interface{}) { // logger.SafeGoWithArgs(func(args ...interface{}) {
defer wg.Done() // defer wg.Done()
fileToProcess := args[0].(string) // fileToProcess := args[0].(string)
logger.Debug("Processing file: %s", fileToProcess) // logger.Debug("Processing file: %s", fileToProcess)
// It's a bit fucked, maybe I could do better to call it from proc... But it'll do for now // // It's a bit fucked, maybe I could do better to call it from proc... But it'll do for now
modCount, matchCount, err := processor.Process(proc, fileToProcess, pattern, luaExpr) // modCount, matchCount, err := processor.Process(proc, fileToProcess, pattern, luaExpr)
if err != nil { // if err != nil {
logger.Error("Failed to process file %s: %v", fileToProcess, err) // logger.Error("Failed to process file %s: %v", fileToProcess, err)
fmt.Fprintf(os.Stderr, "Failed to process file %s: %v\n", fileToProcess, err) // fmt.Fprintf(os.Stderr, "Failed to process file %s: %v\n", fileToProcess, err)
stats.FailedFiles++ // stats.FailedFiles++
} else { // } else {
if modCount > 0 { // if modCount > 0 {
logger.Info("Successfully processed file %s: %d modifications from %d matches", // logger.Info("Successfully processed file %s: %d modifications from %d matches",
fileToProcess, modCount, matchCount) // fileToProcess, modCount, matchCount)
} else if matchCount > 0 { // } else if matchCount > 0 {
logger.Info("Found %d matches in file %s but made no modifications", // logger.Info("Found %d matches in file %s but made no modifications",
matchCount, fileToProcess) // matchCount, fileToProcess)
} else { // } else {
logger.Debug("No matches found in file: %s", fileToProcess) // logger.Debug("No matches found in file: %s", fileToProcess)
} // }
stats.ProcessedFiles++ // stats.ProcessedFiles++
stats.TotalMatches += matchCount // stats.TotalMatches += matchCount
stats.TotalModifications += modCount // stats.TotalModifications += modCount
} // }
}, file) // }, file)
} // }
wg.Wait() // wg.Wait()
// Print summary // Print summary
if stats.TotalModifications == 0 { if stats.TotalModifications == 0 {
@@ -175,6 +195,40 @@ func main() {
} }
} }
func LoadCommandFromArgs(args []string, commands []ModifyCommand) ([]ModifyCommand, error) {
// Cannot reset without git, right?
if *resetFlag {
*gitFlag = true
}
if len(args) < 3 {
logger.Error("At least %d arguments are required", 3)
flag.Usage()
return commands, fmt.Errorf("at least %d arguments are required", 3)
}
command := ModifyCommand{
Pattern: args[0],
LuaExpr: args[1],
Files: args[2:],
Git: *gitFlag,
Reset: *resetFlag,
LogLevel: *logLevel,
}
if err := command.Validate(); err != nil {
logger.Error("Invalid command: %v", err)
flag.Usage()
return commands, fmt.Errorf("invalid command: %v", err)
}
return append(commands, command), nil
}
func LoadCommandsFromCookFiles(s string, commands []ModifyCommand) ([]ModifyCommand, error) {
return commands, nil
}
func setupGit() error { func setupGit() error {
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {