From 42b655d8eedb9cba1b2afe166e58af83b465b242 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Mon, 23 Oct 2023 21:45:19 -0400 Subject: [PATCH] *.go: update to golangci-lint, and fix everything install tools in the workflow actions Also switch away from deprecated ioutil Signed-off-by: Vincent Batts --- .github/workflows/go.yml | 4 ++-- .github/workflows/validation.yml | 28 ++++++++++++++++++++++++ Makefile | 18 ++++++---------- check_test.go | 13 ++++++----- cmd/gomtree/cmd/validate.go | 10 ++++----- compare_test.go | 37 ++++++++++++++++---------------- fseval_test.go | 5 ++--- keywordfunc.go | 2 +- keywords_linux_test.go | 13 +++++++---- mtree_test.go | 4 ++-- tar.go | 3 +-- tar_test.go | 13 ++++++----- test/cli-test/main.go | 2 +- update.go | 8 ++++++- update_linux_test.go | 5 ++--- update_test.go | 5 ++--- walk_test.go | 3 +-- xattr/xattr_test.go | 3 +-- xattr/xattr_unsupported_test.go | 3 +-- 19 files changed, 101 insertions(+), 78 deletions(-) create mode 100644 .github/workflows/validation.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0ce20ad..e57fa18 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -22,9 +22,9 @@ jobs: go-version: ${{ matrix.go }} - name: Build - run: make + run: make build - - name: Test + - name: Validation run: make validation - name: Build.Arches diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml new file mode 100644 index 0000000..e005484 --- /dev/null +++ b/.github/workflows/validation.yml @@ -0,0 +1,28 @@ +name: lint + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + + build: + runs-on: ubuntu-latest + strategy: + matrix: + go: ['1.21'] + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go }} + + - name: Install tools + run: make install.tools + + - name: Test + run: make lint diff --git a/Makefile b/Makefile index 44e9fbe..ac31e47 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ GO_VER := go1.14 default: build validation .PHONY: validation -validation: .test .lint .vet .cli.test +validation: .test .vet .cli.test .PHONY: validation.tags validation.tags: .test.tags .vet.tags .cli.test .staticcheck @@ -50,11 +50,7 @@ lint: .lint CLEAN_FILES += .lint .lint: $(SOURCE_FILES) - @if [ "$(findstring $(GO_VER),$(shell go version))" != "" ] ; then \ - set -e ; for dir in $(NO_VENDOR_DIR) ; do golint -set_exit_status $$dir ; done && touch $@ \ - else \ - touch $@ ; \ - fi + set -e ; golangci-lint run && touch $@ .PHONY: vet vet: .vet .vet.tags @@ -85,12 +81,10 @@ $(BUILD): $(SOURCE_FILES) go build -ldflags="-X 'main.Version=$(shell git describe --always --dirty)'" -mod=vendor -o $(BUILD) $(BUILDPATH) install.tools: - @go install -u github.com/fatih/color@latest ; \ - go install -u github.com/fzipp/gocyclo/cmd/gocyclo@latest ; \ - go install -u honnef.co/go/tools/cmd/staticcheck@latest ; \ - if [ "$(findstring $(GO_VER),$(shell go version))" != "" ] ; then \ - go get -u golang.org/x/lint/golint ;\ - fi + @go install github.com/fatih/color@latest ; \ + go install github.com/fzipp/gocyclo/cmd/gocyclo@latest ; \ + go install honnef.co/go/tools/cmd/staticcheck@latest ; \ + go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest ./bin: mkdir -p $@ diff --git a/check_test.go b/check_test.go index 594fa63..bc19ed4 100644 --- a/check_test.go +++ b/check_test.go @@ -2,7 +2,6 @@ package mtree import ( "bytes" - "io/ioutil" "os" "path/filepath" "testing" @@ -31,14 +30,14 @@ func TestCheck(t *testing.T) { // only check again for size and sha1, and ignore time, and ensure it passes func TestCheckKeywords(t *testing.T) { content := []byte("I know half of you half as well as I ought to") - dir, err := ioutil.TempDir("", "test-check-keywords") + dir, err := os.MkdirTemp("", "test-check-keywords") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) // clean up tmpfn := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfn, content, 0666); err != nil { + if err := os.WriteFile(tmpfn, content, 0666); err != nil { t.Fatal(err) } @@ -120,7 +119,7 @@ func TestDefaultBrokenLink(t *testing.T) { // https://github.com/vbatts/go-mtree/issues/8 func TestTimeComparison(t *testing.T) { - dir, err := ioutil.TempDir("", "test-time.") + dir, err := os.MkdirTemp("", "test-time.") if err != nil { t.Fatal(err) } @@ -165,7 +164,7 @@ func TestTimeComparison(t *testing.T) { } func TestTarTime(t *testing.T) { - dir, err := ioutil.TempDir("", "test-tar-time.") + dir, err := os.MkdirTemp("", "test-tar-time.") if err != nil { t.Fatal(err) } @@ -219,7 +218,7 @@ func TestTarTime(t *testing.T) { } func TestIgnoreComments(t *testing.T) { - dir, err := ioutil.TempDir("", "test-comments.") + dir, err := os.MkdirTemp("", "test-comments.") if err != nil { t.Fatal(err) } @@ -288,7 +287,7 @@ func TestIgnoreComments(t *testing.T) { } func TestCheckNeedsEncoding(t *testing.T) { - dir, err := ioutil.TempDir("", "test-needs-encoding") + dir, err := os.MkdirTemp("", "test-needs-encoding") if err != nil { t.Fatal(err) } diff --git a/cmd/gomtree/cmd/validate.go b/cmd/gomtree/cmd/validate.go index 70d2d9b..13ca570 100644 --- a/cmd/gomtree/cmd/validate.go +++ b/cmd/gomtree/cmd/validate.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "strings" @@ -266,7 +265,7 @@ func validateAction(c *cli.Context) error { } ts := mtree.NewTarStreamer(input, excludes, currentKeywords) - if _, err := io.Copy(ioutil.Discard, ts); err != nil && err != io.EOF { + if _, err := io.Copy(io.Discard, ts); err != nil && err != io.EOF { return err } if err := ts.Close(); err != nil { @@ -344,8 +343,8 @@ func validateAction(c *cli.Context) error { } // output stateDh - stateDh.WriteTo(fh) - return nil + _, err = stateDh.WriteTo(fh) + return err } // no spec manifest has been provided yet, so look for it on stdin @@ -358,7 +357,8 @@ func validateAction(c *cli.Context) error { // We can't check against more fields than in the specKeywords list, so // currentKeywords can only have a subset of specKeywords. - specKeywords = specDh.UsedKeywords() + // TODO this specKeywords is not even used + _ = specDh.UsedKeywords() } // This is a validation. diff --git a/compare_test.go b/compare_test.go index 186e42f..8859dfa 100644 --- a/compare_test.go +++ b/compare_test.go @@ -5,7 +5,6 @@ import ( "bytes" "encoding/json" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -37,7 +36,7 @@ func TestCompare(t *testing.T) { //gocyclo:ignore func TestCompareModified(t *testing.T) { - dir, err := ioutil.TempDir("", "test-compare-modified") + dir, err := os.MkdirTemp("", "test-compare-modified") if err != nil { t.Fatal(err) } @@ -45,7 +44,7 @@ func TestCompareModified(t *testing.T) { // Create a bunch of objects. tmpfile := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { + if err := os.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { t.Fatal(err) } @@ -55,7 +54,7 @@ func TestCompareModified(t *testing.T) { } tmpsubfile := filepath.Join(tmpdir, "anotherfile") - if err := ioutil.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { t.Fatal(err) } @@ -66,7 +65,7 @@ func TestCompareModified(t *testing.T) { } // Overwrite the content in one of the files. - if err := ioutil.WriteFile(tmpsubfile, []byte("modified content"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("modified content"), 0666); err != nil { t.Fatal(err) } @@ -117,7 +116,7 @@ func TestCompareModified(t *testing.T) { //gocyclo:ignore func TestCompareMissing(t *testing.T) { - dir, err := ioutil.TempDir("", "test-compare-missing") + dir, err := os.MkdirTemp("", "test-compare-missing") if err != nil { t.Fatal(err) } @@ -125,7 +124,7 @@ func TestCompareMissing(t *testing.T) { // Create a bunch of objects. tmpfile := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { + if err := os.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { t.Fatal(err) } @@ -135,7 +134,7 @@ func TestCompareMissing(t *testing.T) { } tmpsubfile := filepath.Join(tmpdir, "anotherfile") - if err := ioutil.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { t.Fatal(err) } @@ -209,7 +208,7 @@ func TestCompareMissing(t *testing.T) { //gocyclo:ignore func TestCompareExtra(t *testing.T) { - dir, err := ioutil.TempDir("", "test-compare-extra") + dir, err := os.MkdirTemp("", "test-compare-extra") if err != nil { t.Fatal(err) } @@ -223,7 +222,7 @@ func TestCompareExtra(t *testing.T) { // Create a bunch of objects. tmpfile := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { + if err := os.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { t.Fatal(err) } @@ -233,7 +232,7 @@ func TestCompareExtra(t *testing.T) { } tmpsubfile := filepath.Join(tmpdir, "anotherfile") - if err := ioutil.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("some different content"), 0666); err != nil { t.Fatal(err) } @@ -287,7 +286,7 @@ func TestCompareExtra(t *testing.T) { } func TestCompareKeys(t *testing.T) { - dir, err := ioutil.TempDir("", "test-compare-keys") + dir, err := os.MkdirTemp("", "test-compare-keys") if err != nil { t.Fatal(err) } @@ -295,7 +294,7 @@ func TestCompareKeys(t *testing.T) { // Create a bunch of objects. tmpfile := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { + if err := os.WriteFile(tmpfile, []byte("some content here"), 0666); err != nil { t.Fatal(err) } @@ -305,7 +304,7 @@ func TestCompareKeys(t *testing.T) { } tmpsubfile := filepath.Join(tmpdir, "anotherfile") - if err := ioutil.WriteFile(tmpsubfile, []byte("aaa"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("aaa"), 0666); err != nil { t.Fatal(err) } @@ -316,7 +315,7 @@ func TestCompareKeys(t *testing.T) { } // Overwrite the content in one of the files, but without changing the size. - if err := ioutil.WriteFile(tmpsubfile, []byte("bbb"), 0666); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("bbb"), 0666); err != nil { t.Fatal(err) } @@ -343,7 +342,7 @@ func TestCompareKeys(t *testing.T) { //gocyclo:ignore func TestTarCompare(t *testing.T) { - dir, err := ioutil.TempDir("", "test-compare-tar") + dir, err := os.MkdirTemp("", "test-compare-tar") if err != nil { t.Fatal(err) } @@ -351,7 +350,7 @@ func TestTarCompare(t *testing.T) { // Create a bunch of objects. tmpfile := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfile, []byte("some content"), 0644); err != nil { + if err := os.WriteFile(tmpfile, []byte("some content"), 0644); err != nil { t.Fatal(err) } @@ -361,7 +360,7 @@ func TestTarCompare(t *testing.T) { } tmpsubfile := filepath.Join(tmpdir, "anotherfile") - if err := ioutil.WriteFile(tmpsubfile, []byte("aaa"), 0644); err != nil { + if err := os.WriteFile(tmpsubfile, []byte("aaa"), 0644); err != nil { t.Fatal(err) } @@ -395,7 +394,7 @@ func TestTarCompare(t *testing.T) { } str := NewTarStreamer(bytes.NewBuffer(ts), nil, append(DefaultTarKeywords, "sha1")) - if _, err = io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err = io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err = str.Close(); err != nil { diff --git a/fseval_test.go b/fseval_test.go index 9535cb6..a52ea52 100644 --- a/fseval_test.go +++ b/fseval_test.go @@ -2,7 +2,6 @@ package mtree import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "testing" @@ -73,7 +72,7 @@ func (fs *MockFsEval) KeywordFunc(fn KeywordFunc) KeywordFunc { //gocyclo:ignore func TestCheckFsEval(t *testing.T) { - dir, err := ioutil.TempDir("", "test-check-fs-eval") + dir, err := os.MkdirTemp("", "test-check-fs-eval") if err != nil { t.Fatal(err) } @@ -81,7 +80,7 @@ func TestCheckFsEval(t *testing.T) { content := []byte("If you hide your ignorance, no one will hit you and you'll never learn.") tmpfn := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfn, content, 0451); err != nil { + if err := os.WriteFile(tmpfn, content, 0451); err != nil { t.Fatal(err) } diff --git a/keywordfunc.go b/keywordfunc.go index 8876ca5..2299325 100644 --- a/keywordfunc.go +++ b/keywordfunc.go @@ -13,7 +13,7 @@ import ( "github.com/vbatts/go-mtree/pkg/govis" - //lint:ignore SA1019 yes ripemd160 is deprecated, but this is for mtree compatibility + //nolint:staticcheck // SA1019 yes ripemd160 is deprecated, but this is for mtree compatibility "golang.org/x/crypto/ripemd160" ) diff --git a/keywords_linux_test.go b/keywords_linux_test.go index 6e29012..e293909 100644 --- a/keywords_linux_test.go +++ b/keywords_linux_test.go @@ -4,7 +4,6 @@ package mtree import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -21,7 +20,7 @@ func TestXattr(t *testing.T) { // xattrs testDir = "." } - dir, err := ioutil.TempDir(testDir, "test.xattrs.") + dir, err := os.MkdirTemp(testDir, "test.xattrs.") if err != nil { t.Fatal(err) } @@ -30,8 +29,14 @@ func TestXattr(t *testing.T) { if err != nil { t.Fatal(err) } - fh.WriteString("howdy") - fh.Sync() + _, err = fh.WriteString("howdy") + if err != nil { + t.Errorf("failed to write string: %s", err) + } + err = fh.Sync() + if err != nil { + t.Errorf("failed to sync file: %s", err) + } if _, err := fh.Seek(0, 0); err != nil { t.Fatal(err) } diff --git a/mtree_test.go b/mtree_test.go index 882d1a9..35b2717 100644 --- a/mtree_test.go +++ b/mtree_test.go @@ -1,7 +1,7 @@ package mtree import ( - "io/ioutil" + "io" "os" "testing" @@ -74,7 +74,7 @@ func TestParser(t *testing.T) { } } - i, err := dh.WriteTo(ioutil.Discard) + i, err := dh.WriteTo(io.Discard) if err != nil { t.Error(err) } diff --git a/tar.go b/tar.go index ce18344..dcef122 100644 --- a/tar.go +++ b/tar.go @@ -4,7 +4,6 @@ import ( "archive/tar" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -111,7 +110,7 @@ hdrloop: // Because the content of the file may need to be read by several // KeywordFuncs, it needs to be an io.Seeker as well. So, just reading from // ts.tarReader is not enough. - tmpFile, err := ioutil.TempFile("", "ts.payload.") + tmpFile, err := os.CreateTemp("", "ts.payload.") if err != nil { ts.pipeReader.CloseWithError(err) return diff --git a/tar_test.go b/tar_test.go index 1f9408c..3725821 100644 --- a/tar_test.go +++ b/tar_test.go @@ -4,7 +4,6 @@ import ( "archive/tar" "bytes" "io" - "io/ioutil" "os" "path/filepath" "syscall" @@ -62,7 +61,7 @@ func TestTar(t *testing.T) { } str := NewTarStreamer(fh, nil, append(DefaultKeywords, "sha1")) - if _, err := io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err := io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err := str.Close(); err != nil { @@ -137,7 +136,7 @@ func TestArchiveCreation(t *testing.T) { } str := NewTarStreamer(fh, nil, []Keyword{"sha1"}) - if _, err := io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err := io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err := str.Close(); err != nil { @@ -206,7 +205,7 @@ func TestTreeTraversal(t *testing.T) { } str := NewTarStreamer(fh, nil, DefaultTarKeywords) - if _, err = io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err = io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err = str.Close(); err != nil { @@ -258,7 +257,7 @@ func TestTreeTraversal(t *testing.T) { t.Fatal(err) } str = NewTarStreamer(fh, nil, DefaultTarKeywords) - if _, err = io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err = io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err = str.Close(); err != nil { @@ -297,7 +296,7 @@ func TestHardlinks(t *testing.T) { } str := NewTarStreamer(fh, nil, append(DefaultTarKeywords, "nlink")) - if _, err = io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err = io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err = str.Close(); err != nil { @@ -379,7 +378,7 @@ func TestArchiveExcludeNonDirectory(t *testing.T) { } str := NewTarStreamer(fh, []ExcludeFunc{ExcludeNonDirectories}, []Keyword{"type"}) - if _, err := io.Copy(ioutil.Discard, str); err != nil && err != io.EOF { + if _, err := io.Copy(io.Discard, str); err != nil && err != io.EOF { t.Fatal(err) } if err := str.Close(); err != nil { diff --git a/test/cli-test/main.go b/test/cli-test/main.go index 639ef2f..0606362 100644 --- a/test/cli-test/main.go +++ b/test/cli-test/main.go @@ -32,5 +32,5 @@ func main() { fmt.Fprintf(os.Stderr, red("%d FAILED tests\n"), failed) os.Exit(1) } - fmt.Fprintf(os.Stdout, green("SUCCESS: no cli tests failed\n")) + fmt.Fprint(os.Stdout, green("SUCCESS: no cli tests failed\n")) } diff --git a/update.go b/update.go index 5c37a15..2f2e073 100644 --- a/update.go +++ b/update.go @@ -2,6 +2,7 @@ package mtree import ( "container/heap" + "fmt" "os" "sort" @@ -23,7 +24,12 @@ func Update(root string, dh *DirectoryHierarchy, keywords []Keyword, fs FsEval) creator := dhCreator{DH: dh} curDir, err := os.Getwd() if err == nil { - defer os.Chdir(curDir) + defer func() { + err := os.Chdir(curDir) + if err != nil { + logrus.Warn(fmt.Errorf("failed to change directory to %q: %w", curDir, err)) + } + }() } if err := os.Chdir(root); err != nil { diff --git a/update_linux_test.go b/update_linux_test.go index 729a484..1fb57e5 100644 --- a/update_linux_test.go +++ b/update_linux_test.go @@ -2,7 +2,6 @@ package mtree import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "testing" @@ -19,14 +18,14 @@ func TestXattrUpdate(t *testing.T) { content := []byte("I know half of you half as well as I ought to") // a bit dirty to create/destroy a directory in cwd, but often /tmp is // mounted tmpfs and doesn't support xattrs - dir, err := ioutil.TempDir(".", "test.xattr.restore.") + dir, err := os.MkdirTemp(".", "test.xattr.restore.") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) // clean up tmpfn := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfn, content, 0666); err != nil { + if err := os.WriteFile(tmpfn, content, 0666); err != nil { t.Fatal(err) } diff --git a/update_test.go b/update_test.go index ddce65c..b346c44 100644 --- a/update_test.go +++ b/update_test.go @@ -6,7 +6,6 @@ package mtree import ( "container/heap" "encoding/json" - "io/ioutil" "os" "os/user" "path/filepath" @@ -24,14 +23,14 @@ func init() { //gocyclo:ignore func TestUpdate(t *testing.T) { content := []byte("I know half of you half as well as I ought to") - dir, err := ioutil.TempDir("", "test-check-keywords") + dir, err := os.MkdirTemp("", "test-check-keywords") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) // clean up tmpfn := filepath.Join(dir, "tmpfile") - if err := ioutil.WriteFile(tmpfn, content, 0666); err != nil { + if err := os.WriteFile(tmpfn, content, 0666); err != nil { t.Fatal(err) } diff --git a/walk_test.go b/walk_test.go index 181e517..2277e4d 100644 --- a/walk_test.go +++ b/walk_test.go @@ -1,7 +1,6 @@ package mtree import ( - "io/ioutil" "os" "testing" ) @@ -13,7 +12,7 @@ func TestWalk(t *testing.T) { } numEntries := countTypes(dh) - fh, err := ioutil.TempFile("", "walk.") + fh, err := os.CreateTemp("", "walk.") if err != nil { t.Fatal(err) } diff --git a/xattr/xattr_test.go b/xattr/xattr_test.go index 668fac3..13afe1e 100644 --- a/xattr/xattr_test.go +++ b/xattr/xattr_test.go @@ -5,7 +5,6 @@ package xattr import ( "bytes" - "io/ioutil" "os" "testing" ) @@ -15,7 +14,7 @@ func TestXattr(t *testing.T) { if present == false { testDir = "." } - fh, err := ioutil.TempFile(testDir, "xattr.") + fh, err := os.CreateTemp(testDir, "xattr.") if err != nil { t.Fatal(err) } diff --git a/xattr/xattr_unsupported_test.go b/xattr/xattr_unsupported_test.go index 7df2971..44d3c41 100644 --- a/xattr/xattr_unsupported_test.go +++ b/xattr/xattr_unsupported_test.go @@ -5,13 +5,12 @@ package xattr import ( "bytes" - "io/ioutil" "os" "testing" ) func TestXattrUnsupported(t *testing.T) { - fh, err := ioutil.TempFile(".", "xattr.") + fh, err := os.CreateTemp(".", "xattr.") if err != nil { t.Fatal(err) }