From 0e2d9354623cd22b93b17e71c6765e108292d026 Mon Sep 17 00:00:00 2001 From: web3-bot Date: Wed, 11 Jan 2023 10:37:57 +0000 Subject: [PATCH 1/6] bump go.mod to Go 1.18 and run go fix --- cli/error_posix.go | 1 - cli/error_windows.go | 1 - go.mod | 13 ++++++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cli/error_posix.go b/cli/error_posix.go index 03773212..c5ced61e 100644 --- a/cli/error_posix.go +++ b/cli/error_posix.go @@ -1,5 +1,4 @@ //go:build !windows && !plan9 -// +build !windows,!plan9 package cli diff --git a/cli/error_windows.go b/cli/error_windows.go index e86f3b84..d69871f8 100644 --- a/cli/error_windows.go +++ b/cli/error_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package cli diff --git a/go.mod b/go.mod index 075bc419..c795715d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ipfs/go-ipfs-cmds -go 1.16 +go 1.18 require ( github.com/Kubuxu/go-os-helper v0.0.1 @@ -10,3 +10,14 @@ require ( github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d ) + +require ( + github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/gogo/protobuf v1.3.1 // indirect + github.com/ipfs/go-log/v2 v2.0.5 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect + go.uber.org/atomic v1.6.0 // indirect + go.uber.org/multierr v1.5.0 // indirect + go.uber.org/zap v1.14.1 // indirect + golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect +) From 571e0dac5035172686dcf8841294ad90c6acde82 Mon Sep 17 00:00:00 2001 From: web3-bot Date: Wed, 11 Jan 2023 10:38:01 +0000 Subject: [PATCH 2/6] stop using the deprecated io/ioutil package --- arguments_test.go | 4 +- cli/helptext.go | 1 + cli/parse_test.go | 9 +- cli/responseemitter.go | 2 +- cli/run.go | 2 +- cli/run_test.go | 2 +- doc.go | 176 +++++++++++++++++------------------ examples/adder/cmd.go | 2 +- examples/adder/local/main.go | 2 +- http/client.go | 4 +- http/errors_test.go | 4 +- http/flushfwd.go | 3 +- http/handler_test.go | 3 +- http/parse.go | 4 +- http/response.go | 2 +- http/response_test.go | 2 +- 16 files changed, 109 insertions(+), 113 deletions(-) diff --git a/arguments_test.go b/arguments_test.go index e9ed47ca..d5d7e68c 100644 --- a/arguments_test.go +++ b/arguments_test.go @@ -2,7 +2,7 @@ package cmds import ( "bytes" - "io/ioutil" + "io" "testing" ) @@ -75,7 +75,7 @@ func TestArguments(t *testing.T) { for i, tc := range testCases { for cut := 0; cut <= len(tc.arguments); cut++ { - args := newArguments(ioutil.NopCloser(bytes.NewBufferString(tc.input))) + args := newArguments(io.NopCloser(bytes.NewBufferString(tc.input))) for j, arg := range tc.arguments[:cut] { if !args.Scan() { t.Errorf("in test case %d, missing argument %d", i, j) diff --git a/cli/helptext.go b/cli/helptext.go index dad30939..c363c7de 100644 --- a/cli/helptext.go +++ b/cli/helptext.go @@ -46,6 +46,7 @@ type helpFields struct { // TrimNewlines removes extra newlines from fields. This makes aligning // commands easier. Below, the leading + tralining newlines are removed: +// // Synopsis: ` // ipfs config - Get value of // ipfs config - Set value of to diff --git a/cli/parse_test.go b/cli/parse_test.go index 45bd8c48..4f8dcc2e 100644 --- a/cli/parse_test.go +++ b/cli/parse_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net/url" "os" "path/filepath" @@ -475,7 +474,7 @@ func TestBodyArgs(t *testing.T) { // Use a temp file to simulate stdin fileToSimulateStdin := func(t *testing.T, content string) *os.File { - fstdin, err := ioutil.TempFile("", "") + fstdin, err := os.CreateTemp("", "") if err != nil { t.Fatal(err) } @@ -742,7 +741,7 @@ func TestFileArgs(t *testing.T) { if pattern != "" { pat = pattern } - tmpFile, err := ioutil.TempFile(dir, pat) + tmpFile, err := os.CreateTemp(dir, pat) if err != nil { t.Fatal(err) } @@ -752,11 +751,11 @@ func TestFileArgs(t *testing.T) { } return tmpFile } - tmpDir1, err := ioutil.TempDir("", "parsetest_fileargs_tmpdir_") + tmpDir1, err := os.MkdirTemp("", "parsetest_fileargs_tmpdir_") if err != nil { t.Fatal(err) } - tmpDir2, err := ioutil.TempDir("", "parsetest_utildir_") + tmpDir2, err := os.MkdirTemp("", "parsetest_utildir_") if err != nil { t.Fatal(err) } diff --git a/cli/responseemitter.go b/cli/responseemitter.go index db46a907..0e69e7fc 100644 --- a/cli/responseemitter.go +++ b/cli/responseemitter.go @@ -7,7 +7,7 @@ import ( "os" "sync" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) var _ ResponseEmitter = &responseEmitter{} diff --git a/cli/run.go b/cli/run.go index 46b68280..7465827d 100644 --- a/cli/run.go +++ b/cli/run.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) // ExitError is the error used when a specific exit code needs to be returned. diff --git a/cli/run_test.go b/cli/run_test.go index d318bc11..ee5f1c04 100644 --- a/cli/run_test.go +++ b/cli/run_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) var root = &cmds.Command{ diff --git a/doc.go b/doc.go index 34cf4c45..fde82c1c 100644 --- a/doc.go +++ b/doc.go @@ -1,93 +1,89 @@ /* - Package cmds helps building both standalone and client-server - applications. - - Semantics - - The basic building blocks are requests, commands, emitters and - responses. A command consists of a description of the - parameters and a function. The function is passed the request - as well as an emitter as arguments. It does operations on the - inputs and sends the results to the user by emitting them. - - There are a number of emitters in this package and - subpackages, but the user is free to create their own. - - Commands - - A command is a struct containing the commands help text, a - description of the arguments and options, the command's - processing function and a type to let the caller know what - type will be emitted. Optionally one of the functions PostRun - and Encoder may be defined that consumes the function's - emitted values and generates a visual representation for e.g. - the terminal. Encoders work on a value-by-value basis, while - PostRun operates on the value stream. - - Emitters - - - - An emitter has the Emit method, that takes the command's - function's output as an argument and passes it to the user. - - type ResponseEmitter interface { - Close() error - CloseWithError(error) error - SetLength(length uint64) - Emit(value interface{}) error - } - - The command's function does not know what kind of emitter it - works with, so the same function may run locally or on a - server, using an rpc interface. Emitters can also send errors - using the SetError method. - - The user-facing emitter usually is the cli emitter. Values - emitter here will be printed to the terminal using either the - Encoders or the PostRun function. - - Responses - - - A response is a value that the user can read emitted values - from. - - type Response interface { - Request() Request - Error() *Error - Length() uint64 - Next() (interface{}, error) - } - - Responses have a method Next() that returns the next - emitted value and an error value. If the last element has been - received, the returned error value is io.EOF. If the - application code has sent an error using SetError, the error - ErrRcvdError is returned on next, indicating that the caller - should call Error(). Depending on the reponse type, other - errors may also occur. - - Pipes - - Pipes are pairs (emitter, response), such that a value emitted - on the emitter can be received in the response value. Most - builtin emitters are "pipe" emitters. The most prominent - examples are the channel pipe and the http pipe. - - The channel pipe is backed by a channel. The only error value - returned by the response is io.EOF, which happens when the - channel is closed. - - The http pipe is backed by an http connection. The response - can also return other errors, e.g. if there are errors on the - network. - - Examples - - To get a better idea of what's going on, take a look at the - examples at - https://github.com/ipfs/go-ipfs-cmds/tree/master/examples. - +Package cmds helps building both standalone and client-server +applications. + +# Semantics + +The basic building blocks are requests, commands, emitters and +responses. A command consists of a description of the +parameters and a function. The function is passed the request +as well as an emitter as arguments. It does operations on the +inputs and sends the results to the user by emitting them. + +There are a number of emitters in this package and +subpackages, but the user is free to create their own. + +# Commands + +A command is a struct containing the commands help text, a +description of the arguments and options, the command's +processing function and a type to let the caller know what +type will be emitted. Optionally one of the functions PostRun +and Encoder may be defined that consumes the function's +emitted values and generates a visual representation for e.g. +the terminal. Encoders work on a value-by-value basis, while +PostRun operates on the value stream. + +# Emitters + +An emitter has the Emit method, that takes the command's +function's output as an argument and passes it to the user. + + type ResponseEmitter interface { + Close() error + CloseWithError(error) error + SetLength(length uint64) + Emit(value interface{}) error + } + +The command's function does not know what kind of emitter it +works with, so the same function may run locally or on a +server, using an rpc interface. Emitters can also send errors +using the SetError method. + +The user-facing emitter usually is the cli emitter. Values +emitter here will be printed to the terminal using either the +Encoders or the PostRun function. + +# Responses + +A response is a value that the user can read emitted values +from. + + type Response interface { + Request() Request + Error() *Error + Length() uint64 + Next() (interface{}, error) + } + +Responses have a method Next() that returns the next +emitted value and an error value. If the last element has been +received, the returned error value is io.EOF. If the +application code has sent an error using SetError, the error +ErrRcvdError is returned on next, indicating that the caller +should call Error(). Depending on the reponse type, other +errors may also occur. + +# Pipes + +Pipes are pairs (emitter, response), such that a value emitted +on the emitter can be received in the response value. Most +builtin emitters are "pipe" emitters. The most prominent +examples are the channel pipe and the http pipe. + +The channel pipe is backed by a channel. The only error value +returned by the response is io.EOF, which happens when the +channel is closed. + +The http pipe is backed by an http connection. The response +can also return other errors, e.g. if there are errors on the +network. + +# Examples + +To get a better idea of what's going on, take a look at the +examples at +https://github.com/ipfs/go-ipfs-cmds/tree/master/examples. */ package cmds diff --git a/examples/adder/cmd.go b/examples/adder/cmd.go index 58af9577..2194f23a 100644 --- a/examples/adder/cmd.go +++ b/examples/adder/cmd.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" ) diff --git a/examples/adder/local/main.go b/examples/adder/local/main.go index 8e7eeafe..dadae1ca 100644 --- a/examples/adder/local/main.go +++ b/examples/adder/local/main.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/go-ipfs-cmds/examples/adder" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" ) diff --git a/http/client.go b/http/client.go index 27c2bf03..a3242316 100644 --- a/http/client.go +++ b/http/client.go @@ -9,9 +9,9 @@ import ( "net/url" "strings" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/ipfs/go-ipfs-files" + files "github.com/ipfs/go-ipfs-files" ) const ( diff --git a/http/errors_test.go b/http/errors_test.go index 2cef1b04..c08380a9 100644 --- a/http/errors_test.go +++ b/http/errors_test.go @@ -3,7 +3,7 @@ package http import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "runtime" "strings" @@ -139,7 +139,7 @@ func TestErrors(t *testing.T) { t.Errorf("expected status %v, got %v", tc.status, res.Status) } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { t.Fatal("err reading response body", err) } diff --git a/http/flushfwd.go b/http/flushfwd.go index 4f67c54c..a43650db 100644 --- a/http/flushfwd.go +++ b/http/flushfwd.go @@ -1,8 +1,9 @@ package http import ( - "github.com/ipfs/go-ipfs-cmds" "net/http" + + cmds "github.com/ipfs/go-ipfs-cmds" ) type flushfwder struct { diff --git a/http/handler_test.go b/http/handler_test.go index 3c5cfc71..1a26e29f 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http/httptest" "runtime" @@ -211,7 +210,7 @@ var ( return it.Err() } - data, err := ioutil.ReadAll(files.FileFromEntry(it)) + data, err := io.ReadAll(files.FileFromEntry(it)) if err != nil { return err } diff --git a/http/parse.go b/http/parse.go index 2bd3ac21..bc004a67 100644 --- a/http/parse.go +++ b/http/parse.go @@ -3,7 +3,7 @@ package http import ( "encoding/base32" "fmt" - "io/ioutil" + "io" "math/rand" "mime" "net/http" @@ -223,7 +223,7 @@ func parseResponse(httpRes *http.Response, req *cmds.Request) (cmds.Response, er e.Code = cmds.ErrClient case contentType == plainText: // handle non-marshalled errors - mes, err := ioutil.ReadAll(res.rr) + mes, err := io.ReadAll(res.rr) if err != nil { return nil, err } diff --git a/http/response.go b/http/response.go index 3ba2d938..1964dfc4 100644 --- a/http/response.go +++ b/http/response.go @@ -7,7 +7,7 @@ import ( "reflect" "strings" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) var ( diff --git a/http/response_test.go b/http/response_test.go index 263ea5b4..15781a2f 100644 --- a/http/response_test.go +++ b/http/response_test.go @@ -3,7 +3,7 @@ package http import ( "testing" - "github.com/ipfs/go-ipfs-cmds" + cmds "github.com/ipfs/go-ipfs-cmds" ) type testResponseType struct { From 79f7d5205f65cc6aae1a7969607c9113830b9a73 Mon Sep 17 00:00:00 2001 From: web3-bot Date: Wed, 11 Jan 2023 10:38:02 +0000 Subject: [PATCH 3/6] update .github/workflows/automerge.yml --- .github/workflows/automerge.yml | 50 +++------------------------------ 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 44fad65f..3833fc22 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -1,53 +1,11 @@ # File managed by web3-bot. DO NOT EDIT. # See https://github.com/protocol/.github/ for details. -# Automatically merge pull requests opened by web3-bot, as soon as (and only if) all tests pass. -# This reduces the friction associated with updating with our workflows. - -on: [ pull_request ] name: Automerge +on: [ pull_request ] jobs: - automerge-check: - if: github.event.pull_request.user.login == 'web3-bot' - runs-on: ubuntu-latest - outputs: - status: ${{ steps.should-automerge.outputs.status }} - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Check if we should automerge - id: should-automerge - run: | - for commit in $(git rev-list --first-parent origin/${{ github.event.pull_request.base.ref }}..${{ github.event.pull_request.head.sha }}); do - committer=$(git show --format=$'%ce' -s $commit) - echo "Committer: $committer" - if [[ "$committer" != "web3-bot@users.noreply.github.com" ]]; then - echo "Commit $commit wasn't committed by web3-bot, but by $committer." - echo "::set-output name=status::false" - exit - fi - done - echo "::set-output name=status::true" automerge: - needs: automerge-check - runs-on: ubuntu-latest - # The check for the user is redundant here, as this job depends on the automerge-check job, - # but it prevents this job from spinning up, just to be skipped shortly after. - if: github.event.pull_request.user.login == 'web3-bot' && needs.automerge-check.outputs.status == 'true' - steps: - - name: Wait on tests - uses: lewagon/wait-on-check-action@bafe56a6863672c681c3cf671f5e10b20abf2eaa # v0.2 - with: - ref: ${{ github.event.pull_request.head.sha }} - repo-token: ${{ secrets.GITHUB_TOKEN }} - wait-interval: 10 - running-workflow-name: 'automerge' # the name of this job - - name: Merge PR - uses: pascalgn/automerge-action@741c311a47881be9625932b0a0de1b0937aab1ae # v0.13.1 - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - MERGE_LABELS: "" - MERGE_METHOD: "squash" - MERGE_DELETE_BRANCH: true + uses: protocol/.github/.github/workflows/automerge.yml@master + with: + job: 'automerge' From 8b48eb6d6411c7ad99d4cc511dd70a14d68b943d Mon Sep 17 00:00:00 2001 From: web3-bot Date: Wed, 11 Jan 2023 10:38:02 +0000 Subject: [PATCH 4/6] update .github/workflows/go-test.yml --- .github/workflows/go-test.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 606e0c7f..8a1697b2 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -10,16 +10,16 @@ jobs: fail-fast: false matrix: os: [ "ubuntu", "windows", "macos" ] - go: [ "1.16.x", "1.17.x" ] + go: [ "1.18.x", "1.19.x" ] env: COVERAGES: "" - runs-on: ${{ matrix.os }}-latest - name: ${{ matrix.os}} (go ${{ matrix.go }}) + runs-on: ${{ format('{0}-latest', matrix.os) }} + name: ${{ matrix.os }} (go ${{ matrix.go }}) steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: go-version: ${{ matrix.go }} - name: Go information @@ -43,14 +43,16 @@ jobs: # Use -coverpkg=./..., so that we include cross-package coverage. # If package ./A imports ./B, and ./A's tests also cover ./B, # this means ./B's coverage will be significantly higher than 0%. - run: go test -v -coverprofile=module-coverage.txt -coverpkg=./... ./... + run: go test -v -shuffle=on -coverprofile=module-coverage.txt -coverpkg=./... ./... - name: Run tests (32 bit) if: ${{ matrix.os != 'macos' }} # can't run 32 bit tests on OSX. uses: protocol/multiple-go-modules@v1.2 env: GOARCH: 386 with: - run: go test -v ./... + run: | + export "PATH=${{ env.PATH_386 }}:$PATH" + go test -v -shuffle=on ./... - name: Run tests with race detector if: ${{ matrix.os == 'ubuntu' }} # speed things up. Windows and OSX VMs are slow uses: protocol/multiple-go-modules@v1.2 @@ -60,7 +62,7 @@ jobs: shell: bash run: echo "COVERAGES=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_ENV - name: Upload coverage to Codecov - uses: codecov/codecov-action@f32b3a3741e1053eb607407145bc9619351dc93b # v2.1.0 + uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 with: files: '${{ env.COVERAGES }}' env_vars: OS=${{ matrix.os }}, GO=${{ matrix.go }} From a3b89f65dda68abeb5519f228effab4d8f928916 Mon Sep 17 00:00:00 2001 From: web3-bot Date: Wed, 11 Jan 2023 10:38:02 +0000 Subject: [PATCH 5/6] update .github/workflows/go-check.yml --- .github/workflows/go-check.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go-check.yml b/.github/workflows/go-check.yml index e127cf17..251f7faa 100644 --- a/.github/workflows/go-check.yml +++ b/.github/workflows/go-check.yml @@ -11,12 +11,12 @@ jobs: env: RUNGOGENERATE: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: "1.17.x" + go-version: "1.19.x" - name: Run repo-specific setup uses: ./.github/actions/go-check-setup if: hashFiles('./.github/actions/go-check-setup') != '' @@ -27,7 +27,7 @@ jobs: echo "RUNGOGENERATE=true" >> $GITHUB_ENV fi - name: Install staticcheck - run: go install honnef.co/go/tools/cmd/staticcheck@c8caa92bad8c27ae734c6725b8a04932d54a147b # 2021.1.2 (v0.2.2) + run: go install honnef.co/go/tools/cmd/staticcheck@376210a89477dedbe6fdc4484b233998650d7b3c # 2022.1.3 (v0.3.3) - name: Check that go.mod is tidy uses: protocol/multiple-go-modules@v1.2 with: @@ -71,4 +71,3 @@ jobs: git status --short exit 1 fi - From 099156cd56ca2d8ceb841c231d1610d173d42a06 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 11 Jan 2023 14:46:07 +0100 Subject: [PATCH 6/6] copy instead of for --- cli/helptext.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cli/helptext.go b/cli/helptext.go index c363c7de..22cb5119 100644 --- a/cli/helptext.go +++ b/cli/helptext.go @@ -587,9 +587,7 @@ func (ls lengthSlice) Less(a, b int) bool { func sortByLength(slice []string) []string { output := make(lengthSlice, len(slice)) - for i, val := range slice { - output[i] = val - } + copy(output, slice) sort.Sort(output) return []string(output) }