mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-18 02:01:29 +00:00
merge upstream master
This commit is contained in:
@@ -4,7 +4,10 @@
|
||||
package filesys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -16,40 +19,70 @@ const (
|
||||
// FileSystem groups basic os filesystem methods.
|
||||
// It's supposed be functional subset of https://golang.org/pkg/os
|
||||
type FileSystem interface {
|
||||
|
||||
// Create a file.
|
||||
Create(path string) (File, error)
|
||||
|
||||
// MkDir makes a directory.
|
||||
Mkdir(path string) error
|
||||
|
||||
// MkDirAll makes a directory path, creating intervening directories.
|
||||
MkdirAll(path string) error
|
||||
|
||||
// RemoveAll removes path and any children it contains.
|
||||
RemoveAll(path string) error
|
||||
|
||||
// Open opens the named file for reading.
|
||||
Open(path string) (File, error)
|
||||
|
||||
// IsDir returns true if the path is a directory.
|
||||
IsDir(path string) bool
|
||||
|
||||
// ReadDir returns a list of files and directories within a directory.
|
||||
ReadDir(path string) ([]string, error)
|
||||
|
||||
// CleanedAbs converts the given path into a
|
||||
// directory and a file name, where the directory
|
||||
// is represented as a ConfirmedDir and all that implies.
|
||||
// If the entire path is a directory, the file component
|
||||
// is an empty string.
|
||||
CleanedAbs(path string) (ConfirmedDir, string, error)
|
||||
|
||||
// Exists is true if the path exists in the file system.
|
||||
Exists(path string) bool
|
||||
|
||||
// Glob returns the list of matching files,
|
||||
// emulating https://golang.org/pkg/path/filepath/#Glob
|
||||
Glob(pattern string) ([]string, error)
|
||||
|
||||
// ReadFile returns the contents of the file at the given path.
|
||||
ReadFile(path string) ([]byte, error)
|
||||
|
||||
// WriteFile writes the data to a file at the given path,
|
||||
// overwriting anything that's already there.
|
||||
WriteFile(path string, data []byte) error
|
||||
|
||||
// Walk walks the file system with the given WalkFunc.
|
||||
Walk(path string, walkFn filepath.WalkFunc) error
|
||||
}
|
||||
|
||||
// ConfirmDir returns an error if the user-specified path is not an existing directory on fSys.
|
||||
// Otherwise, ConfirmDir returns path, which can be relative, as a ConfirmedDir and all that implies.
|
||||
func ConfirmDir(fSys FileSystem, path string) (ConfirmedDir, error) {
|
||||
if path == "" {
|
||||
return "", errors.Errorf("directory path cannot be empty")
|
||||
}
|
||||
|
||||
d, f, err := fSys.CleanedAbs(path)
|
||||
if err != nil {
|
||||
return "", errors.WrapPrefixf(err, "not a valid directory")
|
||||
}
|
||||
if f != "" {
|
||||
return "", errors.WrapPrefixf(errors.Errorf("file is not directory"), fmt.Sprintf("'%s'", path))
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// FileSystemOrOnDisk satisfies the FileSystem interface by forwarding
|
||||
// all of its method calls to the given FileSystem whenever it's not nil.
|
||||
// If it's nil, the call is forwarded to the OS's underlying file system.
|
||||
|
||||
@@ -5,16 +5,26 @@ package filesys
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
disk = "MakeFsOnDisk"
|
||||
memoryAbs = "MakeFsInMemory"
|
||||
memoryEmpty = "MakeEmptyDirInMemory"
|
||||
|
||||
existMsg = "expected '%s' to exist"
|
||||
)
|
||||
|
||||
var filesysBuilders = map[string]func() FileSystem{
|
||||
"MakeFsInMemory": MakeFsInMemory,
|
||||
"MakeFsOnDisk": MakeFsOnDisk,
|
||||
"MakeEmptyDirInMemory": func() FileSystem { return MakeEmptyDirInMemory() },
|
||||
memoryAbs: MakeFsInMemory,
|
||||
disk: MakeFsOnDisk,
|
||||
memoryEmpty: func() FileSystem { return MakeEmptyDirInMemory() },
|
||||
}
|
||||
|
||||
func TestNotExistErr(t *testing.T) {
|
||||
@@ -42,3 +52,89 @@ func testNotExistErr(t *testing.T, fs FileSystem) {
|
||||
err = fs.Walk(path, func(_ string, _ os.FileInfo, err error) error { return err })
|
||||
assert.Truef(t, errors.Is(err, os.ErrNotExist), "Walk should return ErrNotExist, got %v", err)
|
||||
}
|
||||
|
||||
// setupFileSys returns file system, default directory to test in, and working directory
|
||||
func setupFileSys(t *testing.T, name string) (FileSystem, string, string) {
|
||||
t.Helper()
|
||||
|
||||
switch name {
|
||||
case disk:
|
||||
fSys, testDir := makeTestDir(t)
|
||||
return fSys, testDir, cleanWd(t)
|
||||
case memoryAbs:
|
||||
return filesysBuilders[name](), Separator, Separator
|
||||
case memoryEmpty:
|
||||
return filesysBuilders[name](), "", ""
|
||||
default:
|
||||
t.Fatalf("unexpected FileSystem implementation '%s'", name)
|
||||
panic("unreachable point of execution")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfirmDir(t *testing.T) {
|
||||
for name := range filesysBuilders {
|
||||
name := name
|
||||
t.Run(name, func(t *testing.T) {
|
||||
fSys, prefixPath, wd := setupFileSys(t, name)
|
||||
|
||||
d1Path := filepath.Join(prefixPath, "d1")
|
||||
d2Path := filepath.Join(d1Path, ".d2")
|
||||
err := fSys.MkdirAll(d2Path)
|
||||
require.NoError(t, err)
|
||||
require.Truef(t, fSys.Exists(d2Path), existMsg, d2Path)
|
||||
|
||||
tests := map[string]*struct {
|
||||
dir string
|
||||
expected string
|
||||
}{
|
||||
"Simple": {
|
||||
d1Path,
|
||||
d1Path,
|
||||
},
|
||||
"Hidden": {
|
||||
d2Path,
|
||||
d2Path,
|
||||
},
|
||||
"Relative": {
|
||||
SelfDir,
|
||||
wd,
|
||||
},
|
||||
}
|
||||
for subName, test := range tests {
|
||||
test := test
|
||||
t.Run(subName, func(t *testing.T) {
|
||||
cleanDir, err := ConfirmDir(fSys, test.dir)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, cleanDir.String())
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfirmDirErr(t *testing.T) {
|
||||
for name := range filesysBuilders {
|
||||
thisName := name
|
||||
t.Run(thisName, func(t *testing.T) {
|
||||
fSys, prefixPath, _ := setupFileSys(t, thisName)
|
||||
|
||||
fPath := filepath.Join(prefixPath, "foo")
|
||||
err := fSys.WriteFile(fPath, []byte(`foo`))
|
||||
require.NoError(t, err)
|
||||
require.Truef(t, fSys.Exists(fPath), existMsg, fPath)
|
||||
|
||||
tests := map[string]string{
|
||||
"Empty": "",
|
||||
"File": fPath,
|
||||
"Non-existent": filepath.Join(prefixPath, "bar"),
|
||||
}
|
||||
for subName, invalidPath := range tests {
|
||||
invalidPath := invalidPath
|
||||
t.Run(subName, func(t *testing.T) {
|
||||
_, err := ConfirmDir(fSys, invalidPath)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
)
|
||||
|
||||
var _ File = &fsNode{}
|
||||
@@ -232,7 +232,7 @@ func (n *fsNode) AddDir(path string) (result *fsNode, err error) {
|
||||
func (n *fsNode) CleanedAbs(path string) (ConfirmedDir, string, error) {
|
||||
node, err := n.Find(path)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "unable to clean")
|
||||
return "", "", errors.WrapPrefixf(err, "unable to clean")
|
||||
}
|
||||
if node == nil {
|
||||
return "", "", notExistError(path)
|
||||
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const content = `
|
||||
@@ -840,6 +842,32 @@ func TestCleanedAbs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfirmDirMemRoot(t *testing.T) {
|
||||
fSys := MakeFsInMemory()
|
||||
actual, err := ConfirmDir(fSys, Separator)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, Separator, actual.String())
|
||||
}
|
||||
|
||||
func TestConfirmDirRelativeNode(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSysEmpty := MakeEmptyDirInMemory()
|
||||
|
||||
fSysRoot, err := fSysEmpty.AddDir("a")
|
||||
req.NoError(err)
|
||||
fSysSub, err := fSysRoot.AddDir("b")
|
||||
req.NoError(err)
|
||||
err = fSysSub.Mkdir("c")
|
||||
req.NoError(err)
|
||||
|
||||
expected := filepath.Join("a", "b", "c")
|
||||
req.Truef(fSysEmpty.Exists(expected), existMsg, expected)
|
||||
|
||||
actual, err := ConfirmDir(fSysSub, "c")
|
||||
req.NoError(err)
|
||||
req.Equal(expected, actual.String())
|
||||
}
|
||||
|
||||
func TestFileOps(t *testing.T) {
|
||||
const path = "foo.txt"
|
||||
content := strings.Repeat("longest content", 100)
|
||||
|
||||
@@ -1,137 +1,164 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package filesys
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const dirMsg = "expected '%s' to be a dir"
|
||||
|
||||
func makeTestDir(t *testing.T) (FileSystem, string) {
|
||||
t.Helper()
|
||||
req := require.New(t)
|
||||
|
||||
fSys := MakeFsOnDisk()
|
||||
td := t.TempDir()
|
||||
|
||||
testDir, err := filepath.EvalSymlinks(td)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %s", err)
|
||||
}
|
||||
if !fSys.Exists(testDir) {
|
||||
t.Fatalf("expected existence")
|
||||
}
|
||||
if !fSys.IsDir(testDir) {
|
||||
t.Fatalf("expected directory")
|
||||
}
|
||||
req.NoError(err)
|
||||
req.Truef(fSys.Exists(testDir), existMsg, testDir)
|
||||
req.Truef(fSys.IsDir(testDir), dirMsg, testDir)
|
||||
|
||||
return fSys, testDir
|
||||
}
|
||||
|
||||
func cleanWd(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
wd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanedWd, err := filepath.EvalSymlinks(wd)
|
||||
require.NoError(t, err)
|
||||
|
||||
return cleanedWd
|
||||
}
|
||||
|
||||
func TestCleanedAbs_1(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSys, _ := makeTestDir(t)
|
||||
|
||||
d, f, err := fSys.CleanedAbs("")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
if d.String() != wd {
|
||||
t.Fatalf("unexpected d=%s", d)
|
||||
}
|
||||
if f != "" {
|
||||
t.Fatalf("unexpected f=%s", f)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
wd := cleanWd(t)
|
||||
req.Equal(wd, d.String())
|
||||
req.Empty(f)
|
||||
}
|
||||
|
||||
func TestCleanedAbs_2(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSys, _ := makeTestDir(t)
|
||||
|
||||
d, f, err := fSys.CleanedAbs("/")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
if d != "/" {
|
||||
t.Fatalf("unexpected d=%s", d)
|
||||
}
|
||||
if f != "" {
|
||||
t.Fatalf("unexpected f=%s", f)
|
||||
}
|
||||
root := getOSRoot(t)
|
||||
d, f, err := fSys.CleanedAbs(root)
|
||||
req.NoError(err)
|
||||
req.Equal(root, d.String())
|
||||
req.Empty(f)
|
||||
}
|
||||
|
||||
func TestCleanedAbs_3(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSys, testDir := makeTestDir(t)
|
||||
|
||||
err := fSys.WriteFile(
|
||||
filepath.Join(testDir, "foo"), []byte(`foo`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
d, f, err := fSys.CleanedAbs(filepath.Join(testDir, "foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
if d.String() != testDir {
|
||||
t.Fatalf("unexpected d=%s", d)
|
||||
}
|
||||
if f != "foo" {
|
||||
t.Fatalf("unexpected f=%s", f)
|
||||
}
|
||||
req.NoError(err)
|
||||
req.Equal(testDir, d.String())
|
||||
req.Equal("foo", f)
|
||||
}
|
||||
|
||||
func TestCleanedAbs_4(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSys, testDir := makeTestDir(t)
|
||||
|
||||
err := fSys.MkdirAll(filepath.Join(testDir, "d1", "d2"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
err = fSys.WriteFile(
|
||||
filepath.Join(testDir, "d1", "d2", "bar"),
|
||||
[]byte(`bar`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
d, f, err := fSys.CleanedAbs(
|
||||
filepath.Join(testDir, "d1", "d2"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
}
|
||||
if d.String() != filepath.Join(testDir, "d1", "d2") {
|
||||
t.Fatalf("unexpected d=%s", d)
|
||||
}
|
||||
if f != "" {
|
||||
t.Fatalf("unexpected f=%s", f)
|
||||
}
|
||||
req.NoError(err)
|
||||
req.Equal(filepath.Join(testDir, "d1", "d2"), d.String())
|
||||
req.Empty(f)
|
||||
|
||||
d, f, err = fSys.CleanedAbs(
|
||||
filepath.Join(testDir, "d1", "d2", "bar"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err=%v", err)
|
||||
req.NoError(err)
|
||||
req.Equal(filepath.Join(testDir, "d1", "d2"), d.String())
|
||||
req.Equal("bar", f)
|
||||
}
|
||||
|
||||
func TestConfirmDirDisk(t *testing.T) {
|
||||
req := require.New(t)
|
||||
fSys, testDir := makeTestDir(t)
|
||||
wd := cleanWd(t)
|
||||
|
||||
relDir := "actual_foo_431432"
|
||||
err := fSys.Mkdir(relDir)
|
||||
t.Cleanup(func() {
|
||||
err := fSys.RemoveAll(relDir)
|
||||
req.NoError(err)
|
||||
})
|
||||
req.NoError(err)
|
||||
req.Truef(fSys.Exists(relDir), existMsg, relDir)
|
||||
|
||||
linkDir := filepath.Join(testDir, "pointer")
|
||||
err = os.Symlink(filepath.Join(wd, relDir), linkDir)
|
||||
req.NoError(err)
|
||||
|
||||
root := getOSRoot(t)
|
||||
tests := map[string]*struct {
|
||||
path string
|
||||
expected string
|
||||
}{
|
||||
"root": {
|
||||
root,
|
||||
root,
|
||||
},
|
||||
"non-selfdir relative path": {
|
||||
relDir,
|
||||
filepath.Join(wd, relDir),
|
||||
},
|
||||
"symlink": {
|
||||
linkDir,
|
||||
filepath.Join(wd, relDir),
|
||||
},
|
||||
}
|
||||
if d.String() != filepath.Join(testDir, "d1", "d2") {
|
||||
t.Fatalf("unexpected d=%s", d)
|
||||
}
|
||||
if f != "bar" {
|
||||
t.Fatalf("unexpected f=%s", f)
|
||||
|
||||
for name, test := range tests {
|
||||
test := test
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actualPath, err := ConfirmDir(fSys, test.path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, actualPath.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFilesRealFS(t *testing.T) {
|
||||
req := require.New(t)
|
||||
|
||||
fSys, testDir := makeTestDir(t)
|
||||
|
||||
dir := path.Join(testDir, "dir")
|
||||
nestedDir := path.Join(dir, "nestedDir")
|
||||
hiddenDir := path.Join(testDir, ".hiddenDir")
|
||||
dir := filepath.Join(testDir, "dir")
|
||||
nestedDir := filepath.Join(dir, "nestedDir")
|
||||
hiddenDir := filepath.Join(testDir, ".hiddenDir")
|
||||
dirs := []string{
|
||||
testDir,
|
||||
dir,
|
||||
@@ -149,27 +176,19 @@ func TestReadFilesRealFS(t *testing.T) {
|
||||
}
|
||||
|
||||
err := fSys.MkdirAll(nestedDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected Error %v\n", err)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
err = fSys.MkdirAll(hiddenDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected Error %v\n", err)
|
||||
}
|
||||
req.NoError(err)
|
||||
|
||||
// adding all files in every directory that we had defined
|
||||
for _, d := range dirs {
|
||||
if !fSys.IsDir(d) {
|
||||
t.Fatalf("Expected %s to be a dir\n", d)
|
||||
}
|
||||
req.Truef(fSys.IsDir(d), dirMsg, d)
|
||||
for _, f := range files {
|
||||
err = fSys.WriteFile(path.Join(d, f), []byte(f))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %s", err)
|
||||
}
|
||||
if !fSys.Exists(path.Join(d, f)) {
|
||||
t.Fatalf("expected %s", f)
|
||||
}
|
||||
fPath := filepath.Join(d, f)
|
||||
err = fSys.WriteFile(fPath, []byte(f))
|
||||
req.NoError(err)
|
||||
req.Truef(fSys.Exists(fPath), existMsg, fPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,15 +240,14 @@ func TestReadFilesRealFS(t *testing.T) {
|
||||
for _, d := range dirs {
|
||||
var expectedPaths []string
|
||||
for _, f := range c.expectedFiles {
|
||||
expectedPaths = append(expectedPaths, path.Join(d, f))
|
||||
expectedPaths = append(expectedPaths, filepath.Join(d, f))
|
||||
}
|
||||
if c.expectedDirs != nil {
|
||||
expectedPaths = append(expectedPaths, c.expectedDirs[d]...)
|
||||
}
|
||||
actualPaths, globErr := fSys.Glob(path.Join(d, c.globPattern))
|
||||
if globErr != nil {
|
||||
t.Fatalf("Unexpected Error : %v\n", globErr)
|
||||
}
|
||||
actualPaths, globErr := fSys.Glob(filepath.Join(d, c.globPattern))
|
||||
require.NoError(t, globErr)
|
||||
|
||||
sort.Strings(actualPaths)
|
||||
sort.Strings(expectedPaths)
|
||||
if !reflect.DeepEqual(actualPaths, expectedPaths) {
|
||||
|
||||
17
kyaml/filesys/fsondisk_test_unix.go
Normal file
17
kyaml/filesys/fsondisk_test_unix.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2022 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package filesys
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func getOSRoot(t *testing.T) string {
|
||||
t.Helper()
|
||||
return string(filepath.Separator)
|
||||
}
|
||||
20
kyaml/filesys/fsondisk_test_windows.go
Normal file
20
kyaml/filesys/fsondisk_test_windows.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2022 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package filesys
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func getOSRoot(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
sysDir, err := windows.GetSystemDirectory()
|
||||
require.NoError(t, err)
|
||||
return filepath.VolumeName(sysDir) + `\`
|
||||
}
|
||||
@@ -14,6 +14,8 @@ require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/xlab/treeprint v1.1.0
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
||||
@@ -144,6 +144,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
Reference in New Issue
Block a user