Absolutely butcher globbing to support absolute paths in globs
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"modify/logger"
|
"modify/logger"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bmatcuk/doublestar/v4"
|
"github.com/bmatcuk/doublestar/v4"
|
||||||
@@ -110,7 +111,7 @@ func AggregateGlobs(commands []ModifyCommand) map[string]struct{} {
|
|||||||
globs := make(map[string]struct{})
|
globs := make(map[string]struct{})
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
for _, glob := range command.Files {
|
for _, glob := range command.Files {
|
||||||
glob = strings.Replace(glob, "~", os.Getenv("HOME"), 1)
|
glob = strings.ReplaceAll(glob, "~", os.Getenv("USERPROFILE"))
|
||||||
glob = strings.ReplaceAll(glob, "\\", "/")
|
glob = strings.ReplaceAll(glob, "\\", "/")
|
||||||
globs[glob] = struct{}{}
|
globs[glob] = struct{}{}
|
||||||
}
|
}
|
||||||
@@ -130,10 +131,51 @@ func ExpandGLobs(patterns map[string]struct{}) ([]string, error) {
|
|||||||
|
|
||||||
logger.Debug("Expanding patterns from directory: %s", cwd)
|
logger.Debug("Expanding patterns from directory: %s", cwd)
|
||||||
for pattern := range patterns {
|
for pattern := range patterns {
|
||||||
|
root := pattern
|
||||||
|
if !filepath.IsAbs(pattern) {
|
||||||
|
root = filepath.Join(cwd, pattern)
|
||||||
|
}
|
||||||
|
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)
|
logger.Trace("Processing pattern: %s", pattern)
|
||||||
matches, _ := doublestar.Glob(os.DirFS(cwd), pattern)
|
matches, err := doublestar.Glob(os.DirFS(finalroot), 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)
|
logger.Debug("Found %d matches for pattern %s", len(matches), pattern)
|
||||||
for _, m := range matches {
|
for _, m := range matches {
|
||||||
|
m = filepath.Join(finalroot, 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)
|
||||||
|
Reference in New Issue
Block a user