aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cli/internal/globby
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:55 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:55 +0800
commitfc8c5fdce62fb229202659408798a7b6c98f6e8b (patch)
tree7554f80e50de4af6fd255afa7c21bcdd58a7af34 /cli/internal/globby
parentdd84b9d64fb98746a230cd24233ff50a562c39c9 (diff)
downloadHydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.tar.gz
HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.zip
Diffstat (limited to 'cli/internal/globby')
-rw-r--r--cli/internal/globby/globby.go187
-rw-r--r--cli/internal/globby/globby_test.go832
2 files changed, 0 insertions, 1019 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
-}
diff --git a/cli/internal/globby/globby_test.go b/cli/internal/globby/globby_test.go
deleted file mode 100644
index 2fdd613..0000000
--- a/cli/internal/globby/globby_test.go
+++ /dev/null
@@ -1,832 +0,0 @@
-package globby
-
-import (
- "io/fs"
- "path/filepath"
- "reflect"
- "sort"
- "testing"
-
- "testing/fstest"
-)
-
-// setup prepares the test file system contents and returns the file system.
-func setup(fsysRoot string, files []string) fs.FS {
- fsys := fstest.MapFS{}
- for _, file := range files {
- // We're populating a `fs.FS` filesytem which requires paths to have no
- // leading slash. As a consequence we strip it during creation.
- iofsRelativePath := file[1:]
-
- fsys[iofsRelativePath] = &fstest.MapFile{Mode: 0666}
- }
-
- return fsys
-}
-
-func TestGlobFilesFs(t *testing.T) {
- type args struct {
- basePath string
- includePatterns []string
- excludePatterns []string
- }
- tests := []struct {
- name string
- files []string
- args args
- wantAll []string
- wantFiles []string
- wantErr bool
- }{
- {
- name: "hello world",
- files: []string{"/test.txt"},
- args: args{
- basePath: "/",
- includePatterns: []string{"*.txt"},
- excludePatterns: []string{},
- },
- wantAll: []string{"/test.txt"},
- wantFiles: []string{"/test.txt"},
- },
- {
- name: "bullet files",
- files: []string{
- "/test.txt",
- "/subdir/test.txt",
- "/other/test.txt",
- },
- args: args{
- basePath: "/",
- includePatterns: []string{"subdir/test.txt", "test.txt"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/subdir/test.txt",
- "/test.txt",
- },
- wantFiles: []string{
- "/subdir/test.txt",
- "/test.txt",
- },
- },
- {
- name: "finding workspace package.json files",
- files: []string{
- "/external/file.txt",
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/bower_components/readline/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/node_modules/gulp/bower_components/readline/package.json",
- "/repos/some-app/node_modules/react/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/test/mocks/kitchen-sink/package.json",
- "/repos/some-app/tests/mocks/kitchen-sink/package.json",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"packages/*/package.json", "apps/*/package.json"},
- excludePatterns: []string{"**/node_modules/", "**/bower_components/", "**/test/", "**/tests/"},
- },
- wantAll: []string{
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- },
- wantFiles: []string{
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- },
- },
- {
- name: "excludes unexpected workspace package.json files",
- files: []string{
- "/external/file.txt",
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/bower_components/readline/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/node_modules/gulp/bower_components/readline/package.json",
- "/repos/some-app/node_modules/react/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/test/mocks/spanish-inquisition/package.json",
- "/repos/some-app/tests/mocks/spanish-inquisition/package.json",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**/package.json"},
- excludePatterns: []string{"**/node_modules/", "**/bower_components/", "**/test/", "**/tests/"},
- },
- wantAll: []string{
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- },
- wantFiles: []string{
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- },
- },
- {
- name: "nested packages work",
- files: []string{
- "/external/file.txt",
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/bower_components/readline/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/node_modules/gulp/bower_components/readline/package.json",
- "/repos/some-app/node_modules/react/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/node_modules/street-legal/package.json",
- "/repos/some-app/packages/xzibit/node_modules/paint-colors/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/node_modules/meme/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/node_modules/yo-dawg/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/test/mocks/spanish-inquisition/package.json",
- "/repos/some-app/tests/mocks/spanish-inquisition/package.json",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"packages/**/package.json"},
- excludePatterns: []string{"**/node_modules/", "**/bower_components/", "**/test/", "**/tests/"},
- },
- wantAll: []string{
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- },
- wantFiles: []string{
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- },
- },
- {
- name: "includes do not override excludes",
- files: []string{
- "/external/file.txt",
- "/repos/some-app/apps/docs/package.json",
- "/repos/some-app/apps/web/package.json",
- "/repos/some-app/bower_components/readline/package.json",
- "/repos/some-app/examples/package.json",
- "/repos/some-app/node_modules/gulp/bower_components/readline/package.json",
- "/repos/some-app/node_modules/react/package.json",
- "/repos/some-app/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/node_modules/street-legal/package.json",
- "/repos/some-app/packages/xzibit/node_modules/paint-colors/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/node_modules/meme/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/node_modules/yo-dawg/package.json",
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/test/mocks/spanish-inquisition/package.json",
- "/repos/some-app/tests/mocks/spanish-inquisition/package.json",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"packages/**/package.json", "tests/mocks/*/package.json"},
- excludePatterns: []string{"**/node_modules/", "**/bower_components/", "**/test/", "**/tests/"},
- },
- wantAll: []string{
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- },
- wantFiles: []string{
- "/repos/some-app/packages/colors/package.json",
- "/repos/some-app/packages/faker/package.json",
- "/repos/some-app/packages/left-pad/package.json",
- "/repos/some-app/packages/xzibit/package.json",
- "/repos/some-app/packages/xzibit/packages/yo-dawg/package.json",
- },
- },
- {
- name: "output globbing grabs the desired content",
- files: []string{
- "/external/file.txt",
- "/repos/some-app/src/index.js",
- "/repos/some-app/public/src/css/index.css",
- "/repos/some-app/.turbo/turbo-build.log",
- "/repos/some-app/.turbo/somebody-touched-this-file-into-existence.txt",
- "/repos/some-app/.next/log.txt",
- "/repos/some-app/.next/cache/db6a76a62043520e7aaadd0bb2104e78.txt",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- "/repos/some-app/public/dist/css/index.css",
- "/repos/some-app/public/dist/images/rick_astley.jpg",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{".turbo/turbo-build.log", "dist/**", ".next/**", "public/dist/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/.next",
- "/repos/some-app/.next/cache",
- "/repos/some-app/.next/cache/db6a76a62043520e7aaadd0bb2104e78.txt",
- "/repos/some-app/.next/log.txt",
- "/repos/some-app/.turbo/turbo-build.log",
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- "/repos/some-app/public/dist",
- "/repos/some-app/public/dist/css",
- "/repos/some-app/public/dist/css/index.css",
- "/repos/some-app/public/dist/images",
- "/repos/some-app/public/dist/images/rick_astley.jpg",
- },
- wantFiles: []string{
- "/repos/some-app/.next/cache/db6a76a62043520e7aaadd0bb2104e78.txt",
- "/repos/some-app/.next/log.txt",
- "/repos/some-app/.turbo/turbo-build.log",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- "/repos/some-app/public/dist/css/index.css",
- "/repos/some-app/public/dist/images/rick_astley.jpg",
- },
- },
- {
- name: "passing ** captures all children",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "passing just a directory captures no children",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist"},
- excludePatterns: []string{},
- },
- wantAll: []string{"/repos/some-app/dist"},
- wantFiles: []string{},
- },
- {
- name: "redundant includes do not duplicate",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**/*", "dist/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "exclude everything, include everything",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**"},
- excludePatterns: []string{"**"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "passing just a directory to exclude prevents capture of children",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist/**"},
- excludePatterns: []string{"dist/js"},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- },
- },
- {
- name: "passing ** to exclude prevents capture of children",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist/**"},
- excludePatterns: []string{"dist/js/**"},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- },
- },
- {
- name: "exclude everything with folder . applies at base path",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**"},
- excludePatterns: []string{"./"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "exclude everything with traversal applies at a non-base path",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**"},
- excludePatterns: []string{"./dist"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "exclude everything with folder traversal (..) applies at base path",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**"},
- excludePatterns: []string{"dist/../"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "how do globs even work bad glob microformat",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**/**/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "directory traversal stops at base path",
- files: []string{
- "/repos/spanish-inquisition/index.html",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"../spanish-inquisition/**", "dist/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{},
- wantFiles: []string{},
- wantErr: true,
- },
- {
- name: "globs and traversal and globs do not cross base path",
- files: []string{
- "/repos/spanish-inquisition/index.html",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**/../../spanish-inquisition/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{},
- wantFiles: []string{},
- wantErr: true,
- },
- {
- name: "traversal works within base path",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist/js/../**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "self-references (.) work",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"dist/./././**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "depth of 1 includes handles folders properly",
- files: []string{
- "/repos/some-app/package.json",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"*"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/package.json",
- },
- wantFiles: []string{"/repos/some-app/package.json"},
- },
- {
- name: "depth of 1 excludes prevents capturing folders",
- files: []string{
- "/repos/some-app/package.json",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app/",
- includePatterns: []string{"**"},
- excludePatterns: []string{"dist/*"},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/package.json",
- },
- wantFiles: []string{"/repos/some-app/package.json"},
- },
- {
- name: "No-trailing slash basePath works",
- files: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"dist/**"},
- excludePatterns: []string{},
- },
- wantAll: []string{
- "/repos/some-app/dist",
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- wantFiles: []string{
- "/repos/some-app/dist/index.html",
- "/repos/some-app/dist/js/index.js",
- "/repos/some-app/dist/js/lib.js",
- "/repos/some-app/dist/js/node_modules/browserify.js",
- },
- },
- {
- name: "exclude single file",
- files: []string{
- "/repos/some-app/included.txt",
- "/repos/some-app/excluded.txt",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"*.txt"},
- excludePatterns: []string{"excluded.txt"},
- },
- wantAll: []string{
- "/repos/some-app/included.txt",
- },
- wantFiles: []string{
- "/repos/some-app/included.txt",
- },
- },
- {
- name: "exclude nested single file",
- files: []string{
- "/repos/some-app/one/included.txt",
- "/repos/some-app/one/two/included.txt",
- "/repos/some-app/one/two/three/included.txt",
- "/repos/some-app/one/excluded.txt",
- "/repos/some-app/one/two/excluded.txt",
- "/repos/some-app/one/two/three/excluded.txt",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"**"},
- excludePatterns: []string{"**/excluded.txt"},
- },
- wantAll: []string{
- "/repos/some-app/one/included.txt",
- "/repos/some-app/one/two/included.txt",
- "/repos/some-app/one/two/three/included.txt",
- "/repos/some-app/one",
- "/repos/some-app/one/two",
- "/repos/some-app/one/two/three",
- },
- wantFiles: []string{
- "/repos/some-app/one/included.txt",
- "/repos/some-app/one/two/included.txt",
- "/repos/some-app/one/two/three/included.txt",
- },
- },
- {
- name: "exclude everything",
- files: []string{
- "/repos/some-app/one/included.txt",
- "/repos/some-app/one/two/included.txt",
- "/repos/some-app/one/two/three/included.txt",
- "/repos/some-app/one/excluded.txt",
- "/repos/some-app/one/two/excluded.txt",
- "/repos/some-app/one/two/three/excluded.txt",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"**"},
- excludePatterns: []string{"**"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "exclude everything with slash",
- files: []string{
- "/repos/some-app/one/included.txt",
- "/repos/some-app/one/two/included.txt",
- "/repos/some-app/one/two/three/included.txt",
- "/repos/some-app/one/excluded.txt",
- "/repos/some-app/one/two/excluded.txt",
- "/repos/some-app/one/two/three/excluded.txt",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"**"},
- excludePatterns: []string{"**/"},
- },
- wantAll: []string{},
- wantFiles: []string{},
- },
- {
- name: "exclude everything with leading **",
- files: []string{
- "/repos/some-app/foo/bar",
- "/repos/some-app/some-foo",
- "/repos/some-app/some-foo/bar",
- "/repos/some-app/included",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"**"},
- excludePatterns: []string{"**foo"},
- },
- wantAll: []string{
- "/repos/some-app/included",
- },
- wantFiles: []string{
- "/repos/some-app/included",
- },
- },
- {
- name: "exclude everything with trailing **",
- files: []string{
- "/repos/some-app/foo/bar",
- "/repos/some-app/foo-file",
- "/repos/some-app/foo-dir/bar",
- "/repos/some-app/included",
- },
- args: args{
- basePath: "/repos/some-app",
- includePatterns: []string{"**"},
- excludePatterns: []string{"foo**"},
- },
- wantAll: []string{
- "/repos/some-app/included",
- },
- wantFiles: []string{
- "/repos/some-app/included",
- },
- },
- }
- for _, tt := range tests {
- fsysRoot := "/"
- fsys := setup(fsysRoot, tt.files)
-
- t.Run(tt.name, func(t *testing.T) {
- got, err := globFilesFs(fsys, fsysRoot, tt.args.basePath, tt.args.includePatterns, tt.args.excludePatterns)
-
- if (err != nil) != tt.wantErr {
- t.Errorf("globFilesFs() error = %v, wantErr %v", err, tt.wantErr)
- return
- }
-
- gotToSlash := make([]string, len(got))
- for index, path := range got {
- gotToSlash[index] = filepath.ToSlash(path)
- }
-
- sort.Strings(gotToSlash)
-
- if !reflect.DeepEqual(gotToSlash, tt.wantFiles) {
- t.Errorf("globFilesFs() = %v, want %v", gotToSlash, tt.wantFiles)
- }
- })
-
- t.Run(tt.name, func(t *testing.T) {
- got, err := globAllFs(fsys, fsysRoot, tt.args.basePath, tt.args.includePatterns, tt.args.excludePatterns)
-
- if (err != nil) != tt.wantErr {
- t.Errorf("globAllFs() error = %v, wantErr %v", err, tt.wantErr)
- return
- }
-
- gotToSlash := make([]string, len(got))
- for index, path := range got {
- gotToSlash[index] = filepath.ToSlash(path)
- }
-
- sort.Strings(gotToSlash)
- sort.Strings(tt.wantAll)
-
- if !reflect.DeepEqual(gotToSlash, tt.wantAll) {
- t.Errorf("globAllFs() = %v, want %v", gotToSlash, tt.wantAll)
- }
- })
- }
-}