Factor out the glob butchery
This commit is contained in:
5
.vscode/launch.json
vendored
5
.vscode/launch.json
vendored
@@ -41,9 +41,8 @@
|
||||
"args": [
|
||||
"-loglevel",
|
||||
"trace",
|
||||
"(?-s)LightComponent!anyrange=\"(!num)\"",
|
||||
"*4",
|
||||
"**/Outpost*.xml"
|
||||
"-cook",
|
||||
"cookscoop.yml",
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@@ -120,62 +120,84 @@ func AggregateGlobs(commands []ModifyCommand) map[string]struct{} {
|
||||
return globs
|
||||
}
|
||||
|
||||
func FigureOutGlobRoot(inputPattern string) (root, pattern string, err error) {
|
||||
logger.Debug("Starting to figure out glob root for input pattern: %s", inputPattern)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
root = inputPattern
|
||||
if !filepath.IsAbs(inputPattern) {
|
||||
root = filepath.Join(cwd, inputPattern)
|
||||
logger.Info("Input pattern is not absolute. Using combined path: %s", 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
|
||||
// Where to start, what our FS will be
|
||||
// The best place would be the last sure entry
|
||||
// That is to say the final directory that is not a wildcard
|
||||
|
||||
finalroot := ""
|
||||
// TODO: This will probably explode on linux because oooooooooo we have to be clever oooooooooo / on linux \\ on windows ooooooooooo
|
||||
parts := strings.Split(root, "\\")
|
||||
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)
|
||||
// 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
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
part := parts[i]
|
||||
logger.Trace("Processing part: %s", part)
|
||||
if part == "*" || part == "**" || part == "?" || part == "[" {
|
||||
lastIndex = i
|
||||
logger.Debug("Found wildcard part: %s, updating lastIndex to: %d", part, lastIndex)
|
||||
break
|
||||
}
|
||||
// We can't use join here because it joins C: and Users as C:Users
|
||||
// Instead of C:/Users/
|
||||
// God damn it
|
||||
if finalroot != "" {
|
||||
finalroot = finalroot + "/" + part
|
||||
} else {
|
||||
finalroot = finalroot + part
|
||||
}
|
||||
}
|
||||
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
|
||||
// Which is, in "worst" case, only a file
|
||||
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)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get current working directory: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("Expanding patterns from directory: %s", cwd)
|
||||
for pattern := range patterns {
|
||||
root := pattern
|
||||
if !filepath.IsAbs(pattern) {
|
||||
root = filepath.Join(cwd, pattern)
|
||||
root, pattern, err := FigureOutGlobRoot(pattern)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to figure out glob root: %w", err)
|
||||
}
|
||||
root = filepath.Clean(root)
|
||||
// In either case (whatever our root may be), we have to figure out
|
||||
// Where to start, what our FS will be
|
||||
// The best place would be the last sure entry
|
||||
// That is to say the final directory that is not a wildcard
|
||||
|
||||
finalroot := ""
|
||||
// TODO: This will probably explode on linux because oooooooooo we have to be clever oooooooooo / on linux \\ on windows ooooooooooo
|
||||
parts := strings.Split(root, "\\")
|
||||
lastIndex := len(parts) - 1
|
||||
// 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
|
||||
// In any case we have to match files so they have to be the last part
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
part := parts[i]
|
||||
if part == "*" || part == "?" || part == "[" {
|
||||
lastIndex = i
|
||||
break
|
||||
}
|
||||
// We can't use join here because it joins C: and Users as C:Users
|
||||
// Instead of C:/Users/
|
||||
// God damn it
|
||||
if finalroot != "" {
|
||||
finalroot = finalroot + "/" + part
|
||||
} else {
|
||||
finalroot = finalroot + part
|
||||
}
|
||||
}
|
||||
finalroot = filepath.Clean(finalroot)
|
||||
// After all this juggling our pattern is whatever is left after the finalroot
|
||||
// Which is, in "worst" case, only a file
|
||||
pattern = strings.Join(parts[lastIndex:], "/")
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("failed to glob pattern %s: %w", pattern, err)
|
||||
}
|
||||
logger.Debug("Found %d matches for pattern %s", len(matches), pattern)
|
||||
for _, m := range matches {
|
||||
m = filepath.Join(finalroot, m)
|
||||
m = filepath.Join(root, m)
|
||||
info, err := os.Stat(m)
|
||||
if err != nil {
|
||||
logger.Warning("Error getting file info for %s: %v", m, err)
|
||||
|
Reference in New Issue
Block a user