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")
resetFlag = flag.Bool("reset", false, "Reset files to their original state")
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
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() {
flag.Usage = func() {
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")
}
flag.Parse()
args := flag.Args()
// Initialize logger with the specified log level
level := logger.ParseLevel(*logLevel)
logger.Init(level)
logger.Info("Initializing with log level: %s", level.String())
args := flag.Args()
// Cannot reset without git, right?
if *resetFlag {
*gitFlag = true
}
if len(args) < 3 {
logger.Error("At least %d arguments are required", 3)
commands := []ModifyCommand{}
var err error
commands, err = LoadCommandsFromCookFiles(*cookfile, commands)
if err != nil {
logger.Error("Failed to load commands from cook files: %v", err)
flag.Usage()
return
}
var pattern, luaExpr string
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)
commands, err = LoadCommandFromArgs(args, commands)
if err != nil {
logger.Error("Failed to expand file patterns: %v", err)
fmt.Fprintf(os.Stderr, "Error expanding file patterns: %v\n", err)
logger.Error("Failed to load commands from args: %v", err)
flag.Usage()
return
}
// Use this to clone loggers for individual commands
// logger.WithField("loglevel", level.String())
if len(files) == 0 {
logger.Warning("No files found matching the specified patterns")
fmt.Fprintf(os.Stderr, "No files found matching the specified patterns\n")
return
}
// 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
// }
// }
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
}
// logger.Debug("Expanding file patterns")
// files, err := expandFilePatterns(filePatterns)
// if err != nil {
// logger.Error("Failed to expand file patterns: %v", err)
// fmt.Fprintf(os.Stderr, "Error expanding file patterns: %v\n", err)
// return
// }
// if len(files) == 0 {
// logger.Warning("No files found matching the specified patterns")
// fmt.Fprintf(os.Stderr, "No files found matching the specified patterns\n")
// 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
var proc processor.Processor
switch {
default:
proc = &processor.RegexProcessor{}
logger.Info("Starting regex modifier with pattern %q, expression %q on %d files",
pattern, luaExpr, len(files))
}
var proc processor.Processor = &processor.RegexProcessor{}
var wg sync.WaitGroup
log.Printf("%#v", proc)
log.Printf("%#v", wg)
// Process each file
for _, file := range files {
wg.Add(1)
logger.SafeGoWithArgs(func(args ...interface{}) {
defer wg.Done()
fileToProcess := args[0].(string)
logger.Debug("Processing file: %s", fileToProcess)
// for _, file := range files {
// wg.Add(1)
// logger.SafeGoWithArgs(func(args ...interface{}) {
// defer wg.Done()
// fileToProcess := args[0].(string)
// 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
modCount, matchCount, err := processor.Process(proc, fileToProcess, pattern, luaExpr)
if err != nil {
logger.Error("Failed to process file %s: %v", fileToProcess, err)
fmt.Fprintf(os.Stderr, "Failed to process file %s: %v\n", fileToProcess, err)
stats.FailedFiles++
} else {
if modCount > 0 {
logger.Info("Successfully processed file %s: %d modifications from %d matches",
fileToProcess, modCount, matchCount)
} else if matchCount > 0 {
logger.Info("Found %d matches in file %s but made no modifications",
matchCount, fileToProcess)
} else {
logger.Debug("No matches found in file: %s", fileToProcess)
}
stats.ProcessedFiles++
stats.TotalMatches += matchCount
stats.TotalModifications += modCount
}
}, file)
}
wg.Wait()
// // 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)
// if err != nil {
// logger.Error("Failed to process file %s: %v", fileToProcess, err)
// fmt.Fprintf(os.Stderr, "Failed to process file %s: %v\n", fileToProcess, err)
// stats.FailedFiles++
// } else {
// if modCount > 0 {
// logger.Info("Successfully processed file %s: %d modifications from %d matches",
// fileToProcess, modCount, matchCount)
// } else if matchCount > 0 {
// logger.Info("Found %d matches in file %s but made no modifications",
// matchCount, fileToProcess)
// } else {
// logger.Debug("No matches found in file: %s", fileToProcess)
// }
// stats.ProcessedFiles++
// stats.TotalMatches += matchCount
// stats.TotalModifications += modCount
// }
// }, file)
// }
// wg.Wait()
// Print summary
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 {
cwd, err := os.Getwd()
if err != nil {