зеркало из https://github.com/golang/dep.git
gps: refactor the filesystemState struct
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
This commit is contained in:
Родитель
4e4925d382
Коммит
869f2d711a
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
// deriveFilesystemState returns a filesystemState based on the state of
|
||||||
|
// the filesystem on root.
|
||||||
|
func deriveFilesystemState(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
|
||||||
|
}
|
|
@ -12,54 +12,34 @@ import (
|
||||||
|
|
||||||
// This file contains utilities for running tests around file system state.
|
// 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 {
|
type fsTestCase struct {
|
||||||
before, after filesystemState
|
before, after filesystemState
|
||||||
}
|
}
|
||||||
|
|
||||||
// filesystemState represents the state of a file system. It has a setup method
|
// assert makes sure that the tc.after state matches the state of the actual host
|
||||||
// which inflates its state to the actual host file system, and an assert
|
// file system at tc.after.root.
|
||||||
// method which checks that the actual file system matches the described state.
|
func (tc fsTestCase) assert(t *testing.T) {
|
||||||
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) {
|
|
||||||
dirMap := make(map[string]bool)
|
dirMap := make(map[string]bool)
|
||||||
fileMap := make(map[string]bool)
|
fileMap := make(map[string]bool)
|
||||||
linkMap := make(map[string]bool)
|
linkMap := make(map[string]bool)
|
||||||
|
|
||||||
for _, d := range fs.dirs {
|
for _, d := range tc.after.dirs {
|
||||||
dirMap[d.prepend(fs.root).String()] = true
|
dirMap[filepath.Join(tc.after.root, d)] = true
|
||||||
}
|
}
|
||||||
for _, f := range fs.files {
|
for _, f := range tc.after.files {
|
||||||
fileMap[f.prepend(fs.root).String()] = true
|
fileMap[filepath.Join(tc.after.root, f)] = true
|
||||||
}
|
}
|
||||||
for _, l := range fs.links {
|
for _, l := range tc.after.links {
|
||||||
linkMap[l.path.prepend(fs.root).String()] = true
|
linkMap[filepath.Join(tc.after.root, l.path)] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
err := filepath.Walk(fs.root, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(tc.after.root, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("filepath.Walk path=%q err=%q", path, err)
|
t.Errorf("filepath.Walk path=%q err=%q", path, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if path == fs.root {
|
if path == tc.after.root {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,32 +86,27 @@ func (fs filesystemState) assert(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fsLink represents a symbolic link.
|
// setup inflates fs onto the actual host file system at tc.before.root.
|
||||||
type fsLink struct {
|
// It doesn't delete existing files and should be used on empty roots only.
|
||||||
path fsPath
|
func (tc fsTestCase) setup(t *testing.T) {
|
||||||
to string
|
tc.setupDirs(t)
|
||||||
|
tc.setupFiles(t)
|
||||||
|
tc.setupLinks(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup inflates fs onto the actual host file system
|
func (tc fsTestCase) setupDirs(t *testing.T) {
|
||||||
func (fs filesystemState) setup(t *testing.T) {
|
for _, dir := range tc.before.dirs {
|
||||||
fs.setupDirs(t)
|
p := filepath.Join(tc.before.root, dir)
|
||||||
fs.setupFiles(t)
|
if err := os.MkdirAll(p, 0777); err != nil {
|
||||||
fs.setupLinks(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 {
|
|
||||||
t.Fatalf("os.MkdirAll(%q, 0777) err=%q", p, err)
|
t.Fatalf("os.MkdirAll(%q, 0777) err=%q", p, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs filesystemState) setupFiles(t *testing.T) {
|
func (tc fsTestCase) setupFiles(t *testing.T) {
|
||||||
for _, file := range fs.files {
|
for _, file := range tc.before.files {
|
||||||
p := file.prepend(fs.root)
|
p := filepath.Join(tc.before.root, file)
|
||||||
f, err := os.Create(p.String())
|
f, err := os.Create(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("os.Create(%q) err=%q", p, err)
|
t.Fatalf("os.Create(%q) err=%q", p, err)
|
||||||
}
|
}
|
||||||
|
@ -141,17 +116,17 @@ func (fs filesystemState) setupFiles(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs filesystemState) setupLinks(t *testing.T) {
|
func (tc fsTestCase) setupLinks(t *testing.T) {
|
||||||
for _, link := range fs.links {
|
for _, link := range tc.before.links {
|
||||||
p := link.path.prepend(fs.root)
|
p := filepath.Join(tc.before.root, link.path)
|
||||||
|
|
||||||
// On Windows, relative symlinks confuse filepath.Walk. This is golang/go
|
// 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
|
// issue 17540. So, we'll just sigh and do absolute links, assuming they are
|
||||||
// relative to the directory of link.path.
|
// relative to the directory of link.path.
|
||||||
dir := filepath.Dir(p.String())
|
dir := filepath.Dir(p)
|
||||||
to := filepath.Join(dir, link.to)
|
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)
|
t.Fatalf("os.Symlink(%q, %q) err=%q", to, p, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче