diff options
| author | 2023-04-28 01:36:55 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:55 +0800 | |
| commit | fc8c5fdce62fb229202659408798a7b6c98f6e8b (patch) | |
| tree | 7554f80e50de4af6fd255afa7c21bcdd58a7af34 /cli/internal/globby/globby.go | |
| parent | dd84b9d64fb98746a230cd24233ff50a562c39c9 (diff) | |
| download | HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.tar.gz HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.zip | |
Diffstat (limited to 'cli/internal/globby/globby.go')
| -rw-r--r-- | cli/internal/globby/globby.go | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/cli/internal/globby/globby.go b/cli/internal/globby/globby.go deleted file mode 100644 index 14c40d9..0000000 --- a/cli/internal/globby/globby.go +++ /dev/null @@ -1,187 +0,0 @@ -package globby - -import ( - "fmt" - "path/filepath" - "sort" - "strings" - - iofs "io/fs" - - "github.com/vercel/turbo/cli/internal/fs" - - "github.com/vercel/turbo/cli/internal/doublestar" - "github.com/vercel/turbo/cli/internal/util" -) - -// GlobAll returns an array of files and folders that match the specified set of glob patterns. -// The returned files and folders are absolute paths, assuming that basePath is an absolute path. -func GlobAll(basePath string, includePatterns []string, excludePatterns []string) ([]string, error) { - fsys := fs.CreateDirFSAtRoot(basePath) - fsysRoot := fs.GetDirFSRootPath(fsys) - output, err := globAllFs(fsys, fsysRoot, basePath, includePatterns, excludePatterns) - - // Because this is coming out of a map output is in no way ordered. - // Sorting will put the files in a depth-first order. - sort.Strings(output) - return output, err -} - -// GlobFiles returns an array of files that match the specified set of glob patterns. -// The return files are absolute paths, assuming that basePath is an absolute path. -func GlobFiles(basePath string, includePatterns []string, excludePatterns []string) ([]string, error) { - fsys := fs.CreateDirFSAtRoot(basePath) - fsysRoot := fs.GetDirFSRootPath(fsys) - output, err := globFilesFs(fsys, fsysRoot, basePath, includePatterns, excludePatterns) - - // Because this is coming out of a map output is in no way ordered. - // Sorting will put the files in a depth-first order. - sort.Strings(output) - return output, err -} - -// checkRelativePath ensures that the the requested file path is a child of `from`. -func checkRelativePath(from string, to string) error { - relativePath, err := filepath.Rel(from, to) - - if err != nil { - return err - } - - if strings.HasPrefix(relativePath, "..") { - return fmt.Errorf("the path you are attempting to specify (%s) is outside of the root", to) - } - - return nil -} - -// globFilesFs searches the specified file system to enumerate all files to include. -func globFilesFs(fsys iofs.FS, fsysRoot string, basePath string, includePatterns []string, excludePatterns []string) ([]string, error) { - return globWalkFs(fsys, fsysRoot, basePath, includePatterns, excludePatterns, false) -} - -// globAllFs searches the specified file system to enumerate all files to include. -func globAllFs(fsys iofs.FS, fsysRoot string, basePath string, includePatterns []string, excludePatterns []string) ([]string, error) { - return globWalkFs(fsys, fsysRoot, basePath, includePatterns, excludePatterns, true) -} - -// globWalkFs searches the specified file system to enumerate all files and folders to include. -func globWalkFs(fsys iofs.FS, fsysRoot string, basePath string, includePatterns []string, excludePatterns []string, includeDirs bool) ([]string, error) { - var processedIncludes []string - var processedExcludes []string - result := make(util.Set) - - for _, includePattern := range includePatterns { - includePath := filepath.Join(basePath, includePattern) - err := checkRelativePath(basePath, includePath) - - if err != nil { - return nil, err - } - - // fs.FS paths may not include leading separators. Calculate the - // correct path for this relative to the filesystem root. - // This will not error as it follows the call to checkRelativePath. - iofsRelativePath, _ := fs.IofsRelativePath(fsysRoot, includePath) - - // Includes only operate on files. - processedIncludes = append(processedIncludes, iofsRelativePath) - } - - for _, excludePattern := range excludePatterns { - excludePath := filepath.Join(basePath, excludePattern) - err := checkRelativePath(basePath, excludePath) - - if err != nil { - return nil, err - } - - // fs.FS paths may not include leading separators. Calculate the - // correct path for this relative to the filesystem root. - // This will not error as it follows the call to checkRelativePath. - iofsRelativePath, _ := fs.IofsRelativePath(fsysRoot, excludePath) - - // In case this is a file pattern and not a directory, add the exact pattern. - // In the event that the user has already specified /**, - if !strings.HasSuffix(iofsRelativePath, string(filepath.Separator)+"**") { - processedExcludes = append(processedExcludes, iofsRelativePath) - } - // TODO: we need to either document or change this behavior - // Excludes operate on entire folders, so we also exclude everything under this in case it represents a directory - processedExcludes = append(processedExcludes, filepath.Join(iofsRelativePath, "**")) - } - - // We start from a naive includePattern - includePattern := "" - includeCount := len(processedIncludes) - - // Do not use alternation if unnecessary. - if includeCount == 1 { - includePattern = processedIncludes[0] - } else if includeCount > 1 { - // We use alternation from the very root of the path. This avoids fs.Stat of the basePath. - includePattern = "{" + strings.Join(processedIncludes, ",") + "}" - } - - // We start with an empty string excludePattern which we only use if excludeCount > 0. - excludePattern := "" - excludeCount := len(processedExcludes) - - // Do not use alternation if unnecessary. - if excludeCount == 1 { - excludePattern = processedExcludes[0] - } else if excludeCount > 1 { - // We use alternation from the very root of the path. This avoids fs.Stat of the basePath. - excludePattern = "{" + strings.Join(processedExcludes, ",") + "}" - } - - // GlobWalk expects that everything uses Unix path conventions. - includePattern = filepath.ToSlash(includePattern) - excludePattern = filepath.ToSlash(excludePattern) - - err := doublestar.GlobWalk(fsys, includePattern, func(path string, dirEntry iofs.DirEntry) error { - if !includeDirs && dirEntry.IsDir() { - return nil - } - - // All files that are returned by doublestar.GlobWalk are relative to - // the fsys root. Go, however, has decided that `fs.FS` filesystems do - // not address the root of the file system using `/` and instead use - // paths without leading separators. - // - // We need to track where the `fsys` root is so that when we hand paths back - // we hand them back as the path addressable in the actual OS filesystem. - // - // As a consequence, when processing, we need to *restore* the original - // root to the file path after returning. This works because when we create - // the `os.dirFS` filesystem we do so at the root of the current volume. - if excludeCount == 0 { - // Reconstruct via string concatenation since the root is already pre-composed. - result.Add(fsysRoot + path) - return nil - } - - isExcluded, err := doublestar.Match(excludePattern, filepath.ToSlash(path)) - if err != nil { - return err - } - - if !isExcluded { - // Reconstruct via string concatenation since the root is already pre-composed. - result.Add(fsysRoot + path) - } - - return nil - }) - - // GlobWalk threw an error. - if err != nil { - return nil, err - } - - // Never actually capture the root folder. - // This is a risk because of how we rework the globs. - result.Delete(strings.TrimSuffix(basePath, "/")) - - return result.UnsafeListOfStrings(), nil -} |
