Factor out the glob butchery

This commit is contained in:
2025-04-01 12:02:43 +02:00
parent 0fc5300786
commit d21e20d387
2 changed files with 67 additions and 46 deletions

5
.vscode/launch.json vendored
View File

@@ -41,9 +41,8 @@
"args": [ "args": [
"-loglevel", "-loglevel",
"trace", "trace",
"(?-s)LightComponent!anyrange=\"(!num)\"", "-cook",
"*4", "cookscoop.yml",
"**/Outpost*.xml"
] ]
} }
] ]

View File

@@ -120,22 +120,24 @@ func AggregateGlobs(commands []ModifyCommand) map[string]struct{} {
return globs return globs
} }
func ExpandGLobs(patterns map[string]struct{}) ([]string, error) { func FigureOutGlobRoot(inputPattern string) (root, pattern string, err error) {
var files []string logger.Debug("Starting to figure out glob root for input pattern: %s", inputPattern)
filesMap := make(map[string]bool)
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get current working directory: %w", err) logger.Error("Failed to get current working directory: %v", err)
return "", inputPattern, fmt.Errorf("failed to get current working directory: %w", err)
} }
logger.Trace("Current working directory: %s", cwd)
logger.Debug("Expanding patterns from directory: %s", cwd) root = inputPattern
for pattern := range patterns { if !filepath.IsAbs(inputPattern) {
root := pattern root = filepath.Join(cwd, inputPattern)
if !filepath.IsAbs(pattern) { logger.Info("Input pattern is not absolute. Using combined path: %s", root)
root = filepath.Join(cwd, pattern)
} }
root = filepath.Clean(root) root = filepath.Clean(root)
logger.Debug("Cleaned root path: %s", root)
// In either case (whatever our root may be), we have to figure out // In either case (whatever our root may be), we have to figure out
// Where to start, what our FS will be // Where to start, what our FS will be
// The best place would be the last sure entry // The best place would be the last sure entry
@@ -145,13 +147,17 @@ func ExpandGLobs(patterns map[string]struct{}) ([]string, error) {
// TODO: This will probably explode on linux because oooooooooo we have to be clever oooooooooo / on linux \\ on windows ooooooooooo // TODO: This will probably explode on linux because oooooooooo we have to be clever oooooooooo / on linux \\ on windows ooooooooooo
parts := strings.Split(root, "\\") parts := strings.Split(root, "\\")
lastIndex := len(parts) - 1 lastIndex := len(parts) - 1
logger.Debug("Split root into parts: %v", parts)
// In the case our pattern ends with a file (and many of them do) // In the case our pattern ends with a file (and many of them do)
// Look for only the folders, we cannot mount a file as a FS // Look for only the folders, we cannot mount a file as a FS
// In any case we have to match files so they have to be the last part // In any case we have to match files so they have to be the last part
for i := 0; i < len(parts)-1; i++ { for i := 0; i < len(parts)-1; i++ {
part := parts[i] part := parts[i]
if part == "*" || part == "?" || part == "[" { logger.Trace("Processing part: %s", part)
if part == "*" || part == "**" || part == "?" || part == "[" {
lastIndex = i lastIndex = i
logger.Debug("Found wildcard part: %s, updating lastIndex to: %d", part, lastIndex)
break break
} }
// We can't use join here because it joins C: and Users as C:Users // We can't use join here because it joins C: and Users as C:Users
@@ -164,18 +170,34 @@ func ExpandGLobs(patterns map[string]struct{}) ([]string, error) {
} }
} }
finalroot = filepath.Clean(finalroot) finalroot = filepath.Clean(finalroot)
logger.Debug("Final root after processing: %s", finalroot)
// After all this juggling our pattern is whatever is left after the finalroot // After all this juggling our pattern is whatever is left after the finalroot
// Which is, in "worst" case, only a file // Which is, in "worst" case, only a file
pattern = strings.Join(parts[lastIndex:], "/") pattern = strings.Join(parts[lastIndex:], "/")
logger.Info("Determined pattern: %s", pattern)
return finalroot, pattern, nil
}
func ExpandGLobs(patterns map[string]struct{}) ([]string, error) {
var files []string
filesMap := make(map[string]bool)
for pattern := range patterns {
root, pattern, err := FigureOutGlobRoot(pattern)
if err != nil {
return nil, fmt.Errorf("failed to figure out glob root: %w", err)
}
logger.Trace("Processing pattern: %s", pattern) logger.Trace("Processing pattern: %s", pattern)
matches, err := doublestar.Glob(os.DirFS(finalroot), pattern) matches, err := doublestar.Glob(os.DirFS(root), pattern)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to glob pattern %s: %w", pattern, err) return nil, fmt.Errorf("failed to glob pattern %s: %w", pattern, err)
} }
logger.Debug("Found %d matches for pattern %s", len(matches), pattern) logger.Debug("Found %d matches for pattern %s", len(matches), pattern)
for _, m := range matches { for _, m := range matches {
m = filepath.Join(finalroot, m) m = filepath.Join(root, m)
info, err := os.Stat(m) info, err := os.Stat(m)
if err != nil { if err != nil {
logger.Warning("Error getting file info for %s: %v", m, err) logger.Warning("Error getting file info for %s: %v", m, err)