From 6f898f06cfcfb65321a318eb017e3401af5f1ea0 Mon Sep 17 00:00:00 2001 From: Ibrahim AshShohail Date: Sun, 24 Sep 2017 18:49:06 +0300 Subject: [PATCH] internal/gps: refactor prune and filesystem functions This commit moves filesystemState from being a test struct to become part of gps. It's used to optimize the prune function by calculting the filesystem state and determining the files to prune in-memory. Signed-off-by: Ibrahim AshShohail --- internal/gps/filesystem.go | 77 +++++++ internal/gps/filesystem_test.go | 46 +---- internal/gps/prune.go | 193 ++++++------------ internal/gps/prune_test.go | 204 ++++++++++--------- internal/gps/strip_vendor_nonwindows_test.go | 72 +++---- internal/gps/strip_vendor_test.go | 26 +-- internal/gps/strip_vendor_windows_test.go | 74 +++---- 7 files changed, 348 insertions(+), 344 deletions(-) create mode 100644 internal/gps/filesystem.go diff --git a/internal/gps/filesystem.go b/internal/gps/filesystem.go new file mode 100644 index 0000000000..3a27e9bece --- /dev/null +++ b/internal/gps/filesystem.go @@ -0,0 +1,77 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gps + +import ( + "os" + "path/filepath" +) + +// filesystemState represents the state of a file system. +type filesystemState struct { + root string + dirs []string + files []string + links []fsLink +} + +// fsLink represents a symbolic link. +type fsLink struct { + path string + to string +} + +// calculateFilesystemState returns a filesystemState based on the state of +// the filesystem on root. +func calculateFilesystemState(root string) (filesystemState, error) { + fs := filesystemState{ + root: root, + } + + err := filepath.Walk(fs.root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if path == fs.root { + return nil + } + + relPath, err := filepath.Rel(fs.root, path) + if err != nil { + return err + } + + if (info.Mode() & os.ModeSymlink) != 0 { + eval, err := filepath.EvalSymlinks(path) + if err != nil { + return err + } + + fs.links = append(fs.links, fsLink{ + path: relPath, + to: eval, + }) + + return nil + } + + if info.IsDir() { + fs.dirs = append(fs.dirs, relPath) + + return nil + } + + fs.files = append(fs.files, relPath) + + return nil + }) + + if err != nil { + return filesystemState{}, err + } + + return fs, nil +} diff --git a/internal/gps/filesystem_test.go b/internal/gps/filesystem_test.go index faa4dd5f5c..f08b645a57 100644 --- a/internal/gps/filesystem_test.go +++ b/internal/gps/filesystem_test.go @@ -12,30 +12,10 @@ import ( // This file contains utilities for running tests around file system state. -// fspath represents a file system path in an OS-agnostic way. -type fsPath []string - -func (f fsPath) String() string { return filepath.Join(f...) } - -func (f fsPath) prepend(prefix string) fsPath { - p := fsPath{filepath.FromSlash(prefix)} - return append(p, f...) -} - type fsTestCase struct { before, after filesystemState } -// filesystemState represents the state of a file system. It has a setup method -// which inflates its state to the actual host file system, and an assert -// method which checks that the actual file system matches the described state. -type filesystemState struct { - root string - dirs []fsPath - files []fsPath - links []fsLink -} - // assert makes sure that the fs state matches the state of the actual host // file system func (fs filesystemState) assert(t *testing.T) { @@ -44,13 +24,13 @@ func (fs filesystemState) assert(t *testing.T) { linkMap := make(map[string]bool) for _, d := range fs.dirs { - dirMap[d.prepend(fs.root).String()] = true + dirMap[filepath.Join(fs.root, d)] = true } for _, f := range fs.files { - fileMap[f.prepend(fs.root).String()] = true + fileMap[filepath.Join(fs.root, f)] = true } for _, l := range fs.links { - linkMap[l.path.prepend(fs.root).String()] = true + linkMap[filepath.Join(fs.root, l.path)] = true } err := filepath.Walk(fs.root, func(path string, info os.FileInfo, err error) error { @@ -106,12 +86,6 @@ func (fs filesystemState) assert(t *testing.T) { } } -// fsLink represents a symbolic link. -type fsLink struct { - path fsPath - to string -} - // setup inflates fs onto the actual host file system func (fs filesystemState) setup(t *testing.T) { fs.setupDirs(t) @@ -121,8 +95,8 @@ func (fs filesystemState) setup(t *testing.T) { func (fs filesystemState) setupDirs(t *testing.T) { for _, dir := range fs.dirs { - p := dir.prepend(fs.root) - if err := os.MkdirAll(p.String(), 0777); err != nil { + p := filepath.Join(fs.root, dir) + if err := os.MkdirAll(p, 0777); err != nil { t.Fatalf("os.MkdirAll(%q, 0777) err=%q", p, err) } } @@ -130,8 +104,8 @@ func (fs filesystemState) setupDirs(t *testing.T) { func (fs filesystemState) setupFiles(t *testing.T) { for _, file := range fs.files { - p := file.prepend(fs.root) - f, err := os.Create(p.String()) + p := filepath.Join(fs.root, file) + f, err := os.Create(p) if err != nil { t.Fatalf("os.Create(%q) err=%q", p, err) } @@ -143,15 +117,15 @@ func (fs filesystemState) setupFiles(t *testing.T) { func (fs filesystemState) setupLinks(t *testing.T) { for _, link := range fs.links { - p := link.path.prepend(fs.root) + p := filepath.Join(fs.root, link.path) // On Windows, relative symlinks confuse filepath.Walk. This is golang/go // issue 17540. So, we'll just sigh and do absolute links, assuming they are // relative to the directory of link.path. - dir := filepath.Dir(p.String()) + dir := filepath.Dir(p) to := filepath.Join(dir, link.to) - if err := os.Symlink(to, p.String()); err != nil { + if err := os.Symlink(to, p); err != nil { t.Fatalf("os.Symlink(%q, %q) err=%q", to, p, err) } } diff --git a/internal/gps/prune.go b/internal/gps/prune.go index b67e01b1ff..82ff1acc4f 100644 --- a/internal/gps/prune.go +++ b/internal/gps/prune.go @@ -75,6 +75,11 @@ func Prune(baseDir string, options PruneOptions, l Lock, logger *log.Logger) err func PruneProject(baseDir string, lp LockedProject, options PruneOptions, logger *log.Logger) error { projectDir := filepath.Join(baseDir, string(lp.Ident().ProjectRoot)) + fs, err := calculateFilesystemState(projectDir) + if err != nil { + return errors.Wrap(err, "could not get filesystem state") + } + if (options & PruneNestedVendorDirs) != 0 { if err := pruneNestedVendorDirs(projectDir); err != nil { return err @@ -82,19 +87,19 @@ func PruneProject(baseDir string, lp LockedProject, options PruneOptions, logger } if (options & PruneUnusedPackages) != 0 { - if err := pruneUnusedPackages(lp, projectDir, logger); err != nil { + if err := pruneUnusedPackages(lp, fs, logger); err != nil { return errors.Wrap(err, "failed to prune unused packages") } } if (options & PruneNonGoFiles) != 0 { - if err := pruneNonGoFiles(projectDir, logger); err != nil { + if err := pruneNonGoFiles(fs, logger); err != nil { return errors.Wrap(err, "failed to prune non-Go files") } } if (options & PruneGoTestFiles) != 0 { - if err := pruneGoTestFiles(projectDir, logger); err != nil { + if err := pruneGoTestFiles(fs, logger); err != nil { return errors.Wrap(err, "failed to prune Go test files") } } @@ -107,152 +112,100 @@ func pruneNestedVendorDirs(baseDir string) error { return filepath.Walk(baseDir, stripVendor) } -// pruneUnusedPackages deletes unimported packages found within baseDir. +// pruneUnusedPackages deletes unimported packages found in fs. // Determining whether packages are imported or not is based on the passed LockedProject. -func pruneUnusedPackages(lp LockedProject, projectDir string, logger *log.Logger) error { +func pruneUnusedPackages(lp LockedProject, fs filesystemState, logger *log.Logger) error { pr := string(lp.Ident().ProjectRoot) logger.Printf("Calculating unused packages in %s to prune.\n", pr) - unusedPackages, err := calculateUnusedPackages(lp, projectDir) - if err != nil { - return errors.Wrapf(err, "could not calculate unused packages in %s", pr) - } + unusedPackages := calculateUnusedPackages(lp, fs) logger.Printf("Found the following unused packages in %s:\n", pr) for pkg := range unusedPackages { logger.Printf(" * %s\n", filepath.Join(pr, pkg)) } - unusedPackagesFiles, err := collectUnusedPackagesFiles(projectDir, unusedPackages) - if err != nil { - return errors.Wrapf(err, "could not collect unused packages' files in %s", pr) - } + toDelete := collectUnusedPackagesFiles(fs, unusedPackages) - if err := deleteFiles(unusedPackagesFiles); err != nil { - return errors.Wrapf(err, "") + if err := deleteFiles(toDelete); err != nil { + return errors.Wrapf(err, "could not prune unused packages files") } return nil } // calculateUnusedPackages generates a list of unused packages in lp. -func calculateUnusedPackages(lp LockedProject, projectDir string) (map[string]struct{}, error) { - // TODO(ibrasho): optimize this... +func calculateUnusedPackages(lp LockedProject, fs filesystemState) map[string]struct{} { unused := make(map[string]struct{}) imported := make(map[string]struct{}) + for _, pkg := range lp.Packages() { imported[pkg] = struct{}{} } - err := filepath.Walk(projectDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Ignore anything that's not a directory. - if !info.IsDir() { - return nil - } + // Add the root package if it's not imported. + if _, ok := imported["."]; !ok { + unused["."] = struct{}{} + } - pkg, err := filepath.Rel(projectDir, path) - if err != nil { - return errors.Wrap(err, "unexpected error while calculating unused packages") - } + for _, dirPath := range fs.dirs { + pkg := filepath.ToSlash(dirPath) - pkg = filepath.ToSlash(pkg) if _, ok := imported[pkg]; !ok { unused[pkg] = struct{}{} } + } - return nil - }) - - return unused, err + return unused } -// collectUnusedPackagesFiles returns a slice of all files in the unused packages in projectDir. -func collectUnusedPackagesFiles(projectDir string, unusedPackages map[string]struct{}) ([]string, error) { +// collectUnusedPackagesFiles returns a slice of all files in the unused packages based on fs. +func collectUnusedPackagesFiles(fs filesystemState, unusedPackages map[string]struct{}) []string { // TODO(ibrasho): is this useful? files := make([]string, 0, len(unusedPackages)) - err := filepath.Walk(projectDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Ignore directories. - if info.IsDir() { - return nil - } - - // Ignore perserved files. - if isPreservedFile(info.Name()) { - return nil + for _, path := range fs.files { + // Keep perserved files. + if isPreservedFile(filepath.Base(path)) { + continue } - pkg, err := filepath.Rel(projectDir, filepath.Dir(path)) - if err != nil { - return errors.Wrap(err, "unexpected error while calculating unused packages") - } + pkg := filepath.ToSlash(filepath.Dir(path)) - pkg = filepath.ToSlash(pkg) if _, ok := unusedPackages[pkg]; ok { - files = append(files, path) + files = append(files, filepath.Join(fs.root, path)) } + } - return nil - }) - - return files, err + return files } -// pruneNonGoFiles delete all non-Go files existing within baseDir. +// pruneNonGoFiles delete all non-Go files existing in fs. // Files with names that are prefixed by any entry in preservedNonGoFiles // are not deleted. -func pruneNonGoFiles(baseDir string, logger *log.Logger) error { - files, err := collectNonGoFiles(baseDir, logger) - if err != nil { - return errors.Wrap(err, "could not collect non-Go files") - } - - if err := deleteFiles(files); err != nil { - return errors.Wrap(err, "could not prune Go test files") - } - - return nil -} - -// collectNonGoFiles returns a slice containing all non-Go files in baseDir. -// Files meeting the checks in isPreservedFile are not returned. -func collectNonGoFiles(baseDir string, logger *log.Logger) ([]string, error) { - files := make([]string, 0) - - err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Ignore directories. - if info.IsDir() { - return nil - } - - // Ignore all Go files. - if strings.HasSuffix(info.Name(), ".go") { - return nil +func pruneNonGoFiles(fs filesystemState, logger *log.Logger) error { + // TODO(ibrasho) detemine a sane capacity + toDelete := make([]string, 0, len(fs.files)/4) + + for _, path := range fs.files { + // Ignore Go files. + if strings.HasSuffix(path, ".go") { + continue } // Ignore perserved files. - if isPreservedFile(info.Name()) { - return nil + if isPreservedFile(filepath.Base(path)) { + continue } - files = append(files, path) + toDelete = append(toDelete, filepath.Join(fs.root, path)) + } - return nil - }) + if err := deleteFiles(toDelete); err != nil { + return errors.Wrap(err, "could not prune Go test files") + } - return files, err + return nil } // isPreservedFile checks if the file name indicates that the file should be @@ -275,49 +228,27 @@ func isPreservedFile(name string) bool { return false } -// pruneGoTestFiles deletes all Go test files (*_test.go) within baseDir. -func pruneGoTestFiles(baseDir string, logger *log.Logger) error { - files, err := collectGoTestFiles(baseDir) - if err != nil { - return errors.Wrap(err, "could not collect Go test files") +// pruneGoTestFiles deletes all Go test files (*_test.go) in fs. +func pruneGoTestFiles(fs filesystemState, logger *log.Logger) error { + // TODO(ibrasho) detemine a sane capacity + toDelete := make([]string, 0, len(fs.files)/2) + + for _, path := range fs.files { + if strings.HasSuffix(path, "_test.go") { + toDelete = append(toDelete, filepath.Join(fs.root, path)) + } } - if err := deleteFiles(files); err != nil { + if err := deleteFiles(toDelete); err != nil { return errors.Wrap(err, "could not prune Go test files") } return nil } -// collectGoTestFiles returns a slice contains all Go test files (any files -// prefixed with _test.go) in baseDir. -func collectGoTestFiles(baseDir string) ([]string, error) { - files := make([]string, 0) - - err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Ignore directories. - if info.IsDir() { - return nil - } - - // Ignore any files that is not a Go test file. - if strings.HasSuffix(info.Name(), "_test.go") { - files = append(files, path) - } - - return nil - }) - - return files, err -} - func deleteFiles(paths []string) error { for _, path := range paths { - if err := os.Remove(path); err != nil { + if err := os.Remove(path); err != nil && !os.IsNotExist(err) { return err } } diff --git a/internal/gps/prune_test.go b/internal/gps/prune_test.go index de7791cd77..8defe0114b 100644 --- a/internal/gps/prune_test.go +++ b/internal/gps/prune_test.go @@ -18,7 +18,7 @@ func TestPruneUnusedPackages(t *testing.T) { h.TempDir(".") - pr := "github.com/test/project" + pr := "github.com/sample/repository" pi := ProjectIdentifier{ProjectRoot: ProjectRoot(pr)} testcases := []struct { @@ -30,18 +30,20 @@ func TestPruneUnusedPackages(t *testing.T) { { "one-package", LockedProject{ - pi: pi, - pkgs: []string{"."}, + pi: pi, + pkgs: []string{ + ".", + }, }, fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"main.go"}, + files: []string{ + "main.go", }, }, after: filesystemState{ - files: []fsPath{ - {"main.go"}, + files: []string{ + "main.go", }, }, }, @@ -50,25 +52,27 @@ func TestPruneUnusedPackages(t *testing.T) { { "nested-package", LockedProject{ - pi: pi, - pkgs: []string{"pkg"}, + pi: pi, + pkgs: []string{ + "pkg", + }, }, fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"pkg"}, + dirs: []string{ + "pkg", }, - files: []fsPath{ - {"main.go"}, - {"pkg", "main.go"}, + files: []string{ + "main.go", + "pkg/main.go", }, }, after: filesystemState{ - dirs: []fsPath{ - {"pkg"}, + dirs: []string{ + "pkg", }, - files: []fsPath{ - {"pkg", "main.go"}, + files: []string{ + "pkg/main.go", }, }, }, @@ -77,36 +81,39 @@ func TestPruneUnusedPackages(t *testing.T) { { "complex-project", LockedProject{ - pi: pi, - pkgs: []string{"pkg", "pkg/nestedpkg/otherpkg"}, + pi: pi, + pkgs: []string{ + "pkg", + "pkg/nestedpkg/otherpkg", + }, }, fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"pkg"}, - {"pkg", "nestedpkg"}, - {"pkg", "nestedpkg", "otherpkg"}, + dirs: []string{ + "pkg", + "pkg/nestedpkg", + "pkg/nestedpkg/otherpkg", }, - files: []fsPath{ - {"main.go"}, - {"COPYING"}, - {"pkg", "main.go"}, - {"pkg", "nestedpkg", "main.go"}, - {"pkg", "nestedpkg", "PATENT.md"}, - {"pkg", "nestedpkg", "otherpkg", "main.go"}, + files: []string{ + "main.go", + "COPYING", + "pkg/main.go", + "pkg/nestedpkg/main.go", + "pkg/nestedpkg/PATENT.md", + "pkg/nestedpkg/otherpkg/main.go", }, }, after: filesystemState{ - dirs: []fsPath{ - {"pkg"}, - {"pkg", "nestedpkg"}, - {"pkg", "nestedpkg", "otherpkg"}, + dirs: []string{ + "pkg", + "pkg/nestedpkg", + "pkg/nestedpkg/otherpkg", }, - files: []fsPath{ - {"COPYING"}, - {"pkg", "main.go"}, - {"pkg", "nestedpkg", "PATENT.md"}, - {"pkg", "nestedpkg", "otherpkg", "main.go"}, + files: []string{ + "COPYING", + "pkg/main.go", + "pkg/nestedpkg/PATENT.md", + "pkg/nestedpkg/otherpkg/main.go", }, }, }, @@ -119,17 +126,22 @@ func TestPruneUnusedPackages(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { h.TempDir(pr) - projectDir := h.Path(pr) - tc.fs.before.root = projectDir - tc.fs.after.root = projectDir + baseDir := h.Path(pr) + tc.fs.before.root = baseDir + tc.fs.after.root = baseDir tc.fs.before.setup(t) - err := pruneUnusedPackages(tc.lp, projectDir, logger) + fs, err := calculateFilesystemState(baseDir) + if err != nil { + t.Fatal(err) + } + + err = pruneUnusedPackages(tc.lp, fs, logger) if tc.err && err == nil { - t.Errorf("expected an error, got nil") + t.Fatalf("expected an error, got nil") } else if !tc.err && err != nil { - t.Errorf("unexpected error: %s", err) + t.Fatalf("unexpected error: %s", err) } tc.fs.after.assert(t) @@ -152,8 +164,8 @@ func TestPruneNonGoFiles(t *testing.T) { "one-file", fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"README.md"}, + files: []string{ + "README.md", }, }, after: filesystemState{}, @@ -164,16 +176,16 @@ func TestPruneNonGoFiles(t *testing.T) { "multiple-files", fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"main.go"}, - {"main_test.go"}, - {"README"}, + files: []string{ + "main.go", + "main_test.go", + "README", }, }, after: filesystemState{ - files: []fsPath{ - {"main.go"}, - {"main_test.go"}, + files: []string{ + "main.go", + "main_test.go", }, }, }, @@ -183,22 +195,22 @@ func TestPruneNonGoFiles(t *testing.T) { "mixed-files", fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, - files: []fsPath{ - {"dir", "main.go"}, - {"dir", "main_test.go"}, - {"dir", "db.sqlite"}, + files: []string{ + "dir/main.go", + "dir/main_test.go", + "dir/db.sqlite", }, }, after: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, - files: []fsPath{ - {"dir", "main.go"}, - {"dir", "main_test.go"}, + files: []string{ + "dir/main.go", + "dir/main_test.go", }, }, }, @@ -217,7 +229,12 @@ func TestPruneNonGoFiles(t *testing.T) { tc.fs.before.setup(t) - err := pruneNonGoFiles(baseDir, logger) + fs, err := calculateFilesystemState(baseDir) + if err != nil { + t.Fatal(err) + } + + err = pruneNonGoFiles(fs, logger) if tc.err && err == nil { t.Errorf("expected an error, got nil") } else if !tc.err && err != nil { @@ -244,8 +261,8 @@ func TestPruneGoTestFiles(t *testing.T) { "one-test-file", fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"main_test.go"}, + files: []string{ + "main_test.go", }, }, after: filesystemState{}, @@ -256,17 +273,17 @@ func TestPruneGoTestFiles(t *testing.T) { "multiple-files", fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, - files: []fsPath{ - {"dir", "main_test.go"}, - {"dir", "main2_test.go"}, + files: []string{ + "dir/main_test.go", + "dir/main2_test.go", }, }, after: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, }, }, @@ -276,23 +293,23 @@ func TestPruneGoTestFiles(t *testing.T) { "mixed-files", fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, - files: []fsPath{ - {"dir", "main.go"}, - {"dir", "main2.go"}, - {"dir", "main_test.go"}, - {"dir", "main2_test.go"}, + files: []string{ + "dir/main.go", + "dir/main2.go", + "dir/main_test.go", + "dir/main2_test.go", }, }, after: filesystemState{ - dirs: []fsPath{ - {"dir"}, + dirs: []string{ + "dir", }, - files: []fsPath{ - {"dir", "main.go"}, - {"dir", "main2.go"}, + files: []string{ + "dir/main.go", + "dir/main2.go", }, }, }, @@ -311,11 +328,16 @@ func TestPruneGoTestFiles(t *testing.T) { tc.fs.before.setup(t) - err := pruneGoTestFiles(baseDir, logger) + fs, err := calculateFilesystemState(baseDir) + if err != nil { + t.Fatal(err) + } + + err = pruneGoTestFiles(fs, logger) if tc.err && err == nil { - t.Errorf("expected an error, got nil") + t.Fatalf("expected an error, got nil") } else if !tc.err && err != nil { - t.Errorf("unexpected error: %s", err) + t.Fatalf("unexpected error: %s", err) } tc.fs.after.assert(t) diff --git a/internal/gps/strip_vendor_nonwindows_test.go b/internal/gps/strip_vendor_nonwindows_test.go index a8eb9ae928..bb00d5c4ce 100644 --- a/internal/gps/strip_vendor_nonwindows_test.go +++ b/internal/gps/strip_vendor_nonwindows_test.go @@ -11,46 +11,46 @@ import "testing" func TestStripVendorSymlinks(t *testing.T) { t.Run("vendor symlink", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "vendor"}, + path: "package/vendor", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, }, })) t.Run("nonvendor symlink", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "link"}, + path: "package/link", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "link"}, + path: "package/link", to: "_vendor", }, }, @@ -59,23 +59,23 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("vendor symlink to file", stripVendorTestCase(fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"file"}, + files: []string{ + "file", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "file", }, }, }, after: filesystemState{ - files: []fsPath{ - {"file"}, + files: []string{ + "file", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "file", }, }, @@ -84,27 +84,27 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("chained symlinks", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"_vendor"}, + dirs: []string{ + "_vendor", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "vendor2", }, { - path: fsPath{"vendor2"}, + path: "vendor2", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"_vendor"}, + dirs: []string{ + "_vendor", }, links: []fsLink{ { - path: fsPath{"vendor2"}, + path: "vendor2", to: "_vendor", }, }, @@ -113,31 +113,31 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("circular symlinks", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, links: []fsLink{ { - path: fsPath{"package", "link1"}, + path: "package/link1", to: "link2", }, { - path: fsPath{"package", "link2"}, + path: "package/link2", to: "link1", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, links: []fsLink{ { - path: fsPath{"package", "link1"}, + path: "package/link1", to: "link2", }, { - path: fsPath{"package", "link2"}, + path: "package/link2", to: "link1", }, }, diff --git a/internal/gps/strip_vendor_test.go b/internal/gps/strip_vendor_test.go index 18a722cd9c..7495920727 100644 --- a/internal/gps/strip_vendor_test.go +++ b/internal/gps/strip_vendor_test.go @@ -38,33 +38,33 @@ func stripVendorTestCase(tc fsTestCase) func(*testing.T) { func TestStripVendorDirectory(t *testing.T) { t.Run("vendor directory", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "vendor"}, + dirs: []string{ + "package", + "package/vendor", }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, }, })) t.Run("vendor file", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, - files: []fsPath{ - {"package", "vendor"}, + files: []string{ + "package/vendor", }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, - files: []fsPath{ - {"package", "vendor"}, + files: []string{ + "package/vendor", }, }, })) diff --git a/internal/gps/strip_vendor_windows_test.go b/internal/gps/strip_vendor_windows_test.go index 7569a48741..c1948c1a0e 100644 --- a/internal/gps/strip_vendor_windows_test.go +++ b/internal/gps/strip_vendor_windows_test.go @@ -13,25 +13,25 @@ func TestStripVendorSymlinks(t *testing.T) { // they're too hard to distinguish from junctions. t.Run("vendor symlink", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "vendor"}, + path: "package/vendor", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "vendor"}, + path: "package/vendor", to: "_vendor", }, }, @@ -40,25 +40,25 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("nonvendor symlink", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "link"}, + path: "package/link", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, - {"package", "_vendor"}, + dirs: []string{ + "package", + "package/_vendor", }, links: []fsLink{ { - path: fsPath{"package", "link"}, + path: "package/link", to: "_vendor", }, }, @@ -67,23 +67,23 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("vendor symlink to file", stripVendorTestCase(fsTestCase{ before: filesystemState{ - files: []fsPath{ - {"file"}, + files: []string{ + "file", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "file", }, }, }, after: filesystemState{ - files: []fsPath{ - {"file"}, + files: []string{ + "file", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "file", }, }, @@ -96,27 +96,27 @@ func TestStripVendorSymlinks(t *testing.T) { // symlink, because the first symlink doesn't appear to Go to be a // directory. before: filesystemState{ - dirs: []fsPath{ - {"_vendor"}, + dirs: []string{ + "_vendor", }, links: []fsLink{ { - path: fsPath{"vendor"}, + path: "vendor", to: "vendor2", }, { - path: fsPath{"vendor2"}, + path: "vendor2", to: "_vendor", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"_vendor"}, + dirs: []string{ + "_vendor", }, links: []fsLink{ { - path: fsPath{"vendor2"}, + path: "vendor2", to: "_vendor", }, }, @@ -125,31 +125,31 @@ func TestStripVendorSymlinks(t *testing.T) { t.Run("circular symlinks", stripVendorTestCase(fsTestCase{ before: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, links: []fsLink{ { - path: fsPath{"package", "link1"}, + path: "package/link1", to: "link2", }, { - path: fsPath{"package", "link2"}, + path: "package/link2", to: "link1", }, }, }, after: filesystemState{ - dirs: []fsPath{ - {"package"}, + dirs: []string{ + "package", }, links: []fsLink{ { - path: fsPath{"package", "link1"}, + path: "package/link1", to: "link2", }, { - path: fsPath{"package", "link2"}, + path: "package/link2", to: "link1", }, },