diff --git a/.travis.yml b/.travis.yml index 5a91f4d5..aef09531 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,17 @@ language: go go: - - 1.17.x + - 1.19.x os: - linux - osx before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover - - go get github.com/axw/gocov/gocov - - go get github.com/modocache/gover - - go get github.com/keybase/go-updater/test + - go install github.com/mattn/goveralls@latest + - go install golang.org/x/tools/cmd/cover@latest + - go install github.com/axw/gocov/gocov@latest + - go install github.com/modocache/gover@latest + - go install github.com/keybase/go-updater/test script: - - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.43.0 + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.50.0 - golangci-lint run - go vet ./... - go test -v -coverprofile=command.coverprofile ./command diff --git a/README.md b/README.md index adbafde9..2ff04ac1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Updater -[![Build Status](https://travis-ci.org/keybase/go-updater.svg?branch=master)](https://travis-ci.org/keybase/go-updater) +[![Build Status](https://app.travis-ci.com/keybase/go-updater.svg?branch=master)](https://app.travis-ci.com/github/keybase/go-updater) [![Build Status](https://ci.appveyor.com/api/projects/status/github/keybase/go-updater?branch=master&svg=true)](https://ci.appveyor.com/project/keybase/go-updater) [![Coverage Status](https://coveralls.io/repos/github/keybase/go-updater/badge.svg?branch=master)](https://coveralls.io/github/keybase/go-updater?branch=master) [![GoDoc](https://godoc.org/github.com/keybase/go-updater?status.svg)](https://godoc.org/github.com/keybase/go-updater) @@ -24,7 +24,6 @@ The goals of this library are to provide an updater that: This updater library is used to support updating (in background and on-demand) for Keybase apps and services. - ### Packages The main package is the updater core, there are other support packages: @@ -41,7 +40,6 @@ The main package is the updater core, there are other support packages: - watchdog: Utility to monitor processes and restart them (like launchd), for use with updater service - windows: Windows specific UI - ### Development This library should pass the [gometalinter](https://github.com/alecthomas/gometalinter). @@ -55,4 +53,3 @@ gometalinter --install --update pre-commit install pre-commit run -a ``` - diff --git a/appveyor.yml b/appveyor.yml index 0d3de4d0..fb6e6af9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,7 +4,7 @@ clone_folder: c:\gopath\src\github.com\keybase\go-updater environment: GOPATH: c:\gopath - GOVERSION: 1.17.x + GOVERSION: 1.19.x install: - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% @@ -14,9 +14,9 @@ install: - 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL - go version - go env - - go get -u github.com/stretchr/testify/assert - - go get -u github.com/stretchr/testify/require - - go get github.com/keybase/go-updater/test + - go install github.com/stretchr/testify/assert@latest + - go install github.com/stretchr/testify/require@latest + - go install github.com/keybase/go-updater/test - dir %GOPATH%\bin\test.exe /s build_script: diff --git a/keybase/config_test.go b/keybase/config_test.go index eb77bece..c834f218 100644 --- a/keybase/config_test.go +++ b/keybase/config_test.go @@ -4,7 +4,6 @@ package keybase import ( - "io/ioutil" "os" "path/filepath" "runtime" @@ -135,7 +134,7 @@ func TestConfigExtra(t *testing.T) { }` path := filepath.Join(os.TempDir(), "TestConfigExtra") defer util.RemoveFileAtPath(path) - err := ioutil.WriteFile(path, []byte(data), 0644) + err := os.WriteFile(path, []byte(data), 0644) assert.NoError(t, err) cfg := newDefaultConfig("", "", testLog, false) @@ -159,7 +158,7 @@ func TestConfigBadType(t *testing.T) { }` path := filepath.Join(os.TempDir(), "TestConfigBadType") defer util.RemoveFileAtPath(path) - err := ioutil.WriteFile(path, []byte(data), 0644) + err := os.WriteFile(path, []byte(data), 0644) assert.NoError(t, err) cfg := newDefaultConfig("", "", testLog, false) diff --git a/saltpack/saltpack_test.go b/saltpack/saltpack_test.go index d23f7267..e080cd76 100644 --- a/saltpack/saltpack_test.go +++ b/saltpack/saltpack_test.go @@ -25,7 +25,8 @@ var validCodeSigningKIDs = map[string]bool{ const message1 = "This is a test message\n" // This is the output of running: -// echo "This is a test message" | keybase sign -d +// +// echo "This is a test message" | keybase sign -d const signature1 = `BEGIN KEYBASE SALTPACK DETACHED SIGNATURE. kXR7VktZdyH7rvq v5weRa8moXPeKBe e2YLT0PnyHzCrVi RbC1J5uJtYgYyLW eGg4qzsWqkXuVtJ yTsutKVn8DT97Oe mnvASPWsbU2VjnR t4EChFoYF1RSi75 MvyyWify9iZldeI 0OTYM5yKLpbCrX5 yD0Tmjf2txwg7Jx diff --git a/test/test.go b/test/test.go index 23ee252e..69ffa03d 100644 --- a/test/test.go +++ b/test/test.go @@ -6,7 +6,6 @@ package main import ( "flag" "fmt" - "io/ioutil" "log" "os" "os/signal" @@ -75,7 +74,7 @@ func echo(s string) { } func writeToFile(s string, path string) { - err := ioutil.WriteFile(path, []byte(s), 0700) + err := os.WriteFile(path, []byte(s), 0700) if err != nil { log.Fatalf("Error writing to file: %s", err) } @@ -83,12 +82,12 @@ func writeToFile(s string, path string) { func copyFakeLayout(dst string) { // Read all content of src to data - data, err := ioutil.ReadFile("winlayout.log") + data, err := os.ReadFile("winlayout.log") if err != nil { log.Fatalf("Error reading winlayout.log: %s", err) } // Write data to dst - err = ioutil.WriteFile(dst, data, 0644) + err = os.WriteFile(dst, data, 0644) if err != nil { log.Fatalf("Error writing to %s: %s", dst, err) } diff --git a/updater.go b/updater.go index 251fc449..02164c0a 100644 --- a/updater.go +++ b/updater.go @@ -6,7 +6,6 @@ package updater import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "regexp" @@ -490,7 +489,7 @@ func (u *Updater) CleanupPreviousUpdates() (err error) { if parent == "" || parent == "." { return fmt.Errorf("temp directory is '%v'", parent) } - files, err := ioutil.ReadDir(parent) + files, err := os.ReadDir(parent) if err != nil { return fmt.Errorf("listing parent directory: %v", err) } @@ -530,7 +529,7 @@ func (u *Updater) FindDownloadedAsset(assetName string) (matchingAssetPath strin return matchingAssetPath, fmt.Errorf("temp directory is %v", parent) } - files, err := ioutil.ReadDir(parent) + files, err := os.ReadDir(parent) if err != nil { return matchingAssetPath, fmt.Errorf("listing parent directory: %v", err) } diff --git a/updater_test.go b/updater_test.go index adaa6be5..6a935428 100644 --- a/updater_test.go +++ b/updater_test.go @@ -6,7 +6,6 @@ package updater import ( "fmt" "io" - "io/ioutil" "net/http" "time" @@ -736,7 +735,7 @@ func TestFindDownloadedAsset(t *testing.T) { tmpDir, err = util.MakeTempDir("KeybaseUpdater.", 0700) assert.NoError(t, err) tmpFile := filepath.Join(tmpDir, "nottemp") - err = ioutil.WriteFile(tmpFile, []byte("Contents of temp file"), 0700) + err = os.WriteFile(tmpFile, []byte("Contents of temp file"), 0700) require.NoError(t, err) matchingAssetPath, err = upr.FindDownloadedAsset("temp") @@ -748,7 +747,7 @@ func TestFindDownloadedAsset(t *testing.T) { // 5. asset given -> created KeybaseUpdate. -> file exixst and matches tmpDir, err = util.MakeTempDir("KeybaseUpdater.", 0700) tmpFile = filepath.Join(tmpDir, "temp") - err = ioutil.WriteFile(tmpFile, []byte("Contents of temp file"), 0700) + err = os.WriteFile(tmpFile, []byte("Contents of temp file"), 0700) require.NoError(t, err) matchingAssetPath, err = upr.FindDownloadedAsset("temp") @@ -772,14 +771,14 @@ func TestUpdaterGuiBusy(t *testing.T) { // Now put the config file there and make sure the right error is returned now := time.Now().Unix() * 1000 - err = ioutil.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":true, "changedAtMs":%d}`, now)), 0644) + err = os.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":true, "changedAtMs":%d}`, now)), 0644) assert.NoError(t, err) defer util.RemoveFileAtPath(testAppStatePath) _, err = upr.Update(ctx) assert.EqualError(t, err, "Update Error (guiBusy): User active, retrying later") // If the user was recently active, they are still considered busy. - err = ioutil.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":false, "changedAtMs":%d}`, now)), 0644) + err = os.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":false, "changedAtMs":%d}`, now)), 0644) assert.NoError(t, err) _, err = upr.Update(ctx) assert.EqualError(t, err, "Update Error (guiBusy): User active, retrying later") @@ -792,7 +791,7 @@ func TestUpdaterGuiBusy(t *testing.T) { // If the user wasn't recently active, they are not considered busy ctx.isCheckCommand = false later := time.Now().Add(-5*time.Minute).Unix() * 1000 - err = ioutil.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":false, "changedAtMs":%d}`, later)), 0644) + err = os.WriteFile(testAppStatePath, []byte(fmt.Sprintf(`{"isUserActive":false, "changedAtMs":%d}`, later)), 0644) assert.NoError(t, err) _, err = upr.Update(ctx) assert.NoError(t, err) diff --git a/util/file.go b/util/file.go index 31bc6d96..ec11600a 100644 --- a/util/file.go +++ b/util/file.go @@ -6,7 +6,6 @@ package util import ( "fmt" "io" - "io/ioutil" "net/url" "os" "path/filepath" @@ -87,8 +86,9 @@ func safeWriteToFile(t SafeWriter, mode os.FileMode, log Log) error { // Close closes a file and ignores the error. // This satisfies lint checks when using with defer and you don't care if there // is an error, so instead of: -// defer func() { _ = f.Close() }() -// defer Close(f) +// +// defer func() { _ = f.Close() }() +// defer Close(f) func Close(f io.Closer) { if f == nil { return @@ -100,8 +100,9 @@ func Close(f io.Closer) { // We do nothing if path == "". // This satisfies lint checks when using with defer and you don't care if there // is an error, so instead of: -// defer func() { _ = os.Remove(path) }() -// defer RemoveFileAtPath(path) +// +// defer func() { _ = os.Remove(path) }() +// defer RemoveFileAtPath(path) func RemoveFileAtPath(path string) { if path == "" { return @@ -111,9 +112,8 @@ func RemoveFileAtPath(path string) { // openTempFile creates an opened temporary file. // -// openTempFile("foo", ".zip", 0755) => "foo.RCG2KUSCGYOO3PCKNWQHBOXBKACOPIKL.zip" -// openTempFile(path.Join(os.TempDir(), "foo"), "", 0600) => "/tmp/foo.RCG2KUSCGYOO3PCKNWQHBOXBKACOPIKL" -// +// openTempFile("foo", ".zip", 0755) => "foo.RCG2KUSCGYOO3PCKNWQHBOXBKACOPIKL.zip" +// openTempFile(path.Join(os.TempDir(), "foo"), "", 0600) => "/tmp/foo.RCG2KUSCGYOO3PCKNWQHBOXBKACOPIKL" func openTempFile(prefix string, suffix string, mode os.FileMode) (string, *os.File, error) { filename, err := RandomID(prefix) if err != nil { @@ -189,10 +189,11 @@ func TempPath(tempDir string, prefix string) string { // WriteTempFile creates a unique temp file with data. // // For example: -// WriteTempFile("Test.", byte[]("test data"), 0600) +// +// WriteTempFile("Test.", byte[]("test data"), 0600) func WriteTempFile(prefix string, data []byte, mode os.FileMode) (string, error) { path := TempPath("", prefix) - if err := ioutil.WriteFile(path, data, mode); err != nil { + if err := os.WriteFile(path, data, mode); err != nil { return "", err } return path, nil @@ -201,7 +202,8 @@ func WriteTempFile(prefix string, data []byte, mode os.FileMode) (string, error) // MakeTempDir creates a unique temp directory. // // For example: -// MakeTempDir("Test.", 0700) +// +// MakeTempDir("Test.", 0700) func MakeTempDir(prefix string, mode os.FileMode) (string, error) { path := TempPath("", prefix) if err := os.MkdirAll(path, mode); err != nil { @@ -298,7 +300,7 @@ func ReadFile(path string) ([]byte, error) { return nil, err } defer Close(file) - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { return nil, err } @@ -311,8 +313,9 @@ func convertPathForWindows(path string) string { // URLStringForPath returns an URL as string with file scheme for path. // For example, -// /usr/local/go/bin => file:///usr/local/go/bin -// C:\Go\bin => file:///C:/Go/bin +// +// /usr/local/go/bin => file:///usr/local/go/bin +// C:\Go\bin => file:///C:/Go/bin func URLStringForPath(path string) string { if runtime.GOOS == "windows" { path = convertPathForWindows(path) @@ -324,8 +327,9 @@ func URLStringForPath(path string) string { // PathFromURL returns path for file URL scheme // For example, -// file:///usr/local/go/bin => /usr/local/go/bin -// file:///C:/Go/bin => C:\Go\bin +// +// file:///usr/local/go/bin => /usr/local/go/bin +// file:///C:/Go/bin => C:\Go\bin func PathFromURL(u *url.URL) string { path := u.Path if runtime.GOOS == "windows" && u.Scheme == fileScheme { diff --git a/util/file_test.go b/util/file_test.go index 53e2b564..e8b72674 100644 --- a/util/file_test.go +++ b/util/file_test.go @@ -5,7 +5,6 @@ package util import ( "fmt" - "io/ioutil" "net/url" "os" "os/exec" @@ -139,7 +138,7 @@ func TestMoveFileValid(t *testing.T) { exists, err := FileExists(destinationPath) assert.NoError(t, err) assert.True(t, exists) - data, err := ioutil.ReadFile(destinationPath) + data, err := os.ReadFile(destinationPath) assert.NoError(t, err) assert.Equal(t, []byte("test"), data) srcExists, err := FileExists(sourcePath) @@ -154,7 +153,7 @@ func TestMoveFileValid(t *testing.T) { exists, err = FileExists(destinationPath) assert.NoError(t, err) assert.True(t, exists) - data2, err := ioutil.ReadFile(destinationPath) + data2, err := os.ReadFile(destinationPath) assert.NoError(t, err) assert.Equal(t, []byte("test2"), data2) srcExists2, err := FileExists(sourcePath2) @@ -222,7 +221,7 @@ func TestCopyFileValid(t *testing.T) { exists, err := FileExists(destinationPath) assert.NoError(t, err) assert.True(t, exists) - data, err := ioutil.ReadFile(destinationPath) + data, err := os.ReadFile(destinationPath) assert.NoError(t, err) assert.Equal(t, []byte("test"), data) @@ -234,7 +233,7 @@ func TestCopyFileValid(t *testing.T) { exists, err = FileExists(destinationPath) assert.NoError(t, err) assert.True(t, exists) - data2, err := ioutil.ReadFile(destinationPath) + data2, err := os.ReadFile(destinationPath) assert.NoError(t, err) assert.Equal(t, []byte("test2"), data2) } diff --git a/util/http.go b/util/http.go index 406a5a4e..8fc5806a 100644 --- a/util/http.go +++ b/util/http.go @@ -6,7 +6,6 @@ package util import ( "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -16,7 +15,7 @@ import ( const fileScheme = "file" func discardAndClose(rc io.ReadCloser) error { - _, _ = io.Copy(ioutil.Discard, rc) + _, _ = io.Copy(io.Discard, rc) return rc.Close() } @@ -29,13 +28,13 @@ func discardAndClose(rc io.ReadCloser) error { // // Instead of doing: // -// res, _ := ... -// defer res.Body.Close() +// res, _ := ... +// defer res.Body.Close() // // do // -// res, _ := ... -// defer DiscardAndCloseBody(res) +// res, _ := ... +// defer DiscardAndCloseBody(res) // // instead. func DiscardAndCloseBody(resp *http.Response) error { @@ -67,8 +66,9 @@ func SaveHTTPResponse(resp *http.Response, savePath string, mode os.FileMode, lo // DiscardAndCloseBodyIgnoreError calls DiscardAndCloseBody. // This satisfies lint checks when using with defer and you don't care if there // is an error, so instead of: -// defer func() { _ = DiscardAndCloseBody(resp) }() -// defer DiscardAndCloseBodyIgnoreError(resp) +// +// defer func() { _ = DiscardAndCloseBody(resp) }() +// defer DiscardAndCloseBodyIgnoreError(resp) func DiscardAndCloseBodyIgnoreError(resp *http.Response) { _ = DiscardAndCloseBody(resp) } diff --git a/util/http_test.go b/util/http_test.go index 22e73229..c3e15181 100644 --- a/util/http_test.go +++ b/util/http_test.go @@ -6,9 +6,9 @@ package util import ( "bytes" "fmt" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path/filepath" "runtime" "testing" @@ -68,7 +68,7 @@ func TestSaveHTTPResponse(t *testing.T) { err = SaveHTTPResponse(resp, savePath, 0600, testLog) assert.NoError(t, err) - saved, err := ioutil.ReadFile(savePath) + saved, err := os.ReadFile(savePath) assert.NoError(t, err) assert.Equal(t, string(saved), data+"\n") @@ -150,7 +150,7 @@ func TestDownloadURLValid(t *testing.T) { fileExists, fileErr := FileExists(destinationPath) assert.NoError(t, fileErr) assert.True(t, fileExists) - data, readErr := ioutil.ReadFile(destinationPath) + data, readErr := os.ReadFile(destinationPath) assert.NoError(t, readErr) assert.Equal(t, []byte("ok\n"), data) } @@ -165,7 +165,7 @@ func TestDownloadURLValid(t *testing.T) { fileExists2, err := FileExists(destinationPath) assert.NoError(t, err) assert.True(t, fileExists2) - data2, err := ioutil.ReadFile(destinationPath) + data2, err := os.ReadFile(destinationPath) assert.NoError(t, err) assert.Equal(t, []byte("ok2\n"), data2) } @@ -225,7 +225,7 @@ func TestDownloadURLETag(t *testing.T) { server := testServerWithETag(t, "ok", 0, etag) defer server.Close() destinationPath := TempPath("", "TestDownloadURLETag.") - err := ioutil.WriteFile(destinationPath, data, 0600) + err := os.WriteFile(destinationPath, data, 0600) require.NoError(t, err) digest, err := Digest(bytes.NewReader(data)) assert.NoError(t, err) diff --git a/util/unzip.go b/util/unzip.go index 3b7e6ab1..f1aaadf8 100644 --- a/util/unzip.go +++ b/util/unzip.go @@ -7,7 +7,6 @@ import ( "archive/zip" "fmt" "io" - "io/ioutil" "os" "path/filepath" ) @@ -22,8 +21,7 @@ import ( // // To unzip Keybase-1.2.3.zip and move the contents Keybase.app to /Applications/Keybase.app // -// UnzipOver("/tmp/Keybase-1.2.3.zip", "Keybase.app", "/Applications/Keybase.app", check, "", log) -// +// UnzipOver("/tmp/Keybase-1.2.3.zip", "Keybase.app", "/Applications/Keybase.app", check, "", log) func UnzipOver(sourcePath string, path string, destinationPath string, check func(sourcePath, destinationPath string) error, tmpDir string, log Log) error { unzipPath := fmt.Sprintf("%s.unzipped", sourcePath) defer RemoveFileAtPath(unzipPath) @@ -115,7 +113,7 @@ func Unzip(sourcePath, destinationPath string, log Log) error { } if fileInfo.Mode()&os.ModeSymlink != 0 { - linkName, readErr := ioutil.ReadAll(rc) + linkName, readErr := io.ReadAll(rc) if readErr != nil { return readErr } diff --git a/watchdog/watchdog_test.go b/watchdog/watchdog_test.go index 4a152922..75317824 100644 --- a/watchdog/watchdog_test.go +++ b/watchdog/watchdog_test.go @@ -87,19 +87,22 @@ func TestTerminateBeforeWatch(t *testing.T) { } // TestTerminateBeforeWatchRace verifies protection from the following scenario: -// watchdog1 starts up -// watchdog1 looks up existing processes to terminate and sees none -// watchdog2 starts up -// watchdog2 looks up existing processes to terminate and sees watchdog1 -// watchdog1 starts PROGRAM -// watchdog1 receives kill signal from watchdog2 and dies -// watchdog2 starts a second PROGRAM -// PROGRAM has a bad time +// +// watchdog1 starts up +// watchdog1 looks up existing processes to terminate and sees none +// watchdog2 starts up +// watchdog2 looks up existing processes to terminate and sees watchdog1 +// watchdog1 starts PROGRAM +// watchdog1 receives kill signal from watchdog2 and dies +// watchdog2 starts a second PROGRAM +// PROGRAM has a bad time +// // The test doesn't protect us from the race condition generically, rather only when: -// (1) PROGRAM is only started by a watchdog, and -// (2) PROGRAM and watchdog share a path to the same executable. When a -// watchdog looks up existing processes to terminate, it needs to be able -// to find another watchdog. +// +// (1) PROGRAM is only started by a watchdog, and +// (2) PROGRAM and watchdog share a path to the same executable. When a +// watchdog looks up existing processes to terminate, it needs to be able +// to find another watchdog. func TestTerminateBeforeWatchRace(t *testing.T) { var err error // set up a bunch of iterations of the same program diff --git a/windows/WpfPrompter/run.go b/windows/WpfPrompter/run.go index 31132d3b..8d293be2 100644 --- a/windows/WpfPrompter/run.go +++ b/windows/WpfPrompter/run.go @@ -8,7 +8,7 @@ package main import ( "encoding/json" - "io/ioutil" + "os" "path/filepath" "time" @@ -55,7 +55,7 @@ func main() { return } - result, err := ioutil.ReadFile(outPathName) + result, err := os.ReadFile(outPathName) if err != nil { testLog.Errorf("Error opening result file: %v", err) return