diff --git a/.github/workflows/bindings-go.yml b/.github/workflows/bindings-go.yml index f90d90e0..2ce54093 100644 --- a/.github/workflows/bindings-go.yml +++ b/.github/workflows/bindings-go.yml @@ -26,7 +26,52 @@ on: name: bindings-go +env: + GO_VERSION: 1.22.x + jobs: + lint: + permissions: + contents: read + pull-requests: read + checks: write # to allow the action to annotate code in the pr. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # Build and install libpathrs.so. + - uses: dtolnay/rust-toolchain@stable + - name: build libpathrs + run: make release + - name: install libpathrs + run: sudo ./install.sh --libdir=/usr/lib + # Run golangci-lint. + - uses: golangci/golangci-lint-action@v6 + with: + version: v1.60 + working-directory: go-pathrs + + go-fix: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + # Build and install libpathrs.so. + - uses: dtolnay/rust-toolchain@stable + - name: build libpathrs + run: make release + - name: install libpathrs + run: sudo ./install.sh --libdir=/usr/lib + # Run go-fix. + - uses: actions/setup-go@v5 + with: + go-version: "${{ env.GO_VERSION }}" + - name: run go fix + run: | + cd go-pathrs + go fix ./... + git diff --exit-code + smoke-test: strategy: fail-fast: false @@ -52,6 +97,8 @@ jobs: complete: needs: + - lint + - go-fix - smoke-test runs-on: ubuntu-latest steps: diff --git a/go-pathrs/.golangci.yml b/go-pathrs/.golangci.yml new file mode 100644 index 00000000..d972fd2b --- /dev/null +++ b/go-pathrs/.golangci.yml @@ -0,0 +1,45 @@ +# libpathrs: safe path resolution on Linux +# Copyright (C) 2019-2024 Aleksa Sarai +# Copyright (C) 2019-2024 SUSE LLC +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License along +# with this program. If not, see . + +linters: + enable: + - bidichk + - copyloopvar + - cyclop + - errname + - errorlint + - exhaustive + - goconst + - godot + - gofumpt + - goimports + - gomoddirectives + - gosec + - intrange + - mirror + - misspell + - mnd + - nilerr + - nilnil + - nolintlint + - perfsprint + - prealloc + - reassign + - revive + - unconvert + - unparam + - usestdlibvars + - wastedassign diff --git a/go-pathrs/handle_linux.go b/go-pathrs/handle_linux.go index 278a7c68..512794e3 100644 --- a/go-pathrs/handle_linux.go +++ b/go-pathrs/handle_linux.go @@ -36,7 +36,7 @@ type Handle struct { inner *os.File } -// HandleFromFile creates a new Handle from an exisitng file handle. The handle +// HandleFromFile creates a new Handle from an existing file handle. The handle // will be copied by this method, so the original handle should still be freed // by the caller. // @@ -76,7 +76,7 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) { if err != nil { return nil, err } - return os.NewFile(uintptr(newFd), h.inner.Name()), nil + return os.NewFile(newFd, h.inner.Name()), nil }) } @@ -97,7 +97,7 @@ func (h *Handle) IntoFile() *os.File { } // Clone creates a copy of a Handle, such that it has a separate lifetime to -// the original (while refering to the same underlying file). +// the original (while referring to the same underlying file). func (h *Handle) Clone() (*Handle, error) { return HandleFromFile(h.inner) } diff --git a/go-pathrs/libpathrs_linux.go b/go-pathrs/libpathrs_linux.go index 355d5292..7c58bbcc 100644 --- a/go-pathrs/libpathrs_linux.go +++ b/go-pathrs/libpathrs_linux.go @@ -33,11 +33,11 @@ char *cast_ptr(void *ptr) { return ptr; } */ import "C" -func fetchError(errId C.int) error { - if errId >= 0 { +func fetchError(errID C.int) error { + if errID >= 0 { return nil } - cErr := C.pathrs_errorinfo(errId) + cErr := C.pathrs_errorinfo(errID) defer C.pathrs_errorinfo_free(cErr) var err error diff --git a/go-pathrs/root_linux.go b/go-pathrs/root_linux.go index 876d2062..2a29644f 100644 --- a/go-pathrs/root_linux.go +++ b/go-pathrs/root_linux.go @@ -19,9 +19,9 @@ package pathrs import ( + "errors" "fmt" "os" - "syscall" ) @@ -77,7 +77,7 @@ func (r *Root) Resolve(path string) (*Handle, error) { if err != nil { return nil, err } - handleFile, err := mkFile(uintptr(handleFd)) + handleFile, err := mkFile(handleFd) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) { if err != nil { return nil, err } - handleFile, err := mkFile(uintptr(handleFd)) + handleFile, err := mkFile(handleFd) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error if err != nil { return nil, err } - return mkFile(uintptr(handleFd)) + return mkFile(handleFd) }) } @@ -163,11 +163,11 @@ func (r *Root) Remove(path string) error { return nil } // Both failed, adjust the error in the same way that os.Remove does. - if err, ok := rmdirErr.(*Error); ok && err.errno != syscall.ENOTDIR { - return rmdirErr - } else { - return unlinkErr + err := rmdirErr + if errors.Is(err, syscall.ENOTDIR) { + err = unlinkErr } + return err } // RemoveAll recursively deletes a path and all of its children. This is @@ -211,7 +211,7 @@ func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { if err != nil { return nil, err } - handleFile, err := mkFile(uintptr(handleFd)) + handleFile, err := mkFile(handleFd) if err != nil { return nil, err } @@ -274,7 +274,7 @@ func (r *Root) IntoFile() *os.File { } // Clone creates a copy of a Root handle, such that it has a separate lifetime -// to the original (while refering to the same underlying directory). +// to the original (while referring to the same underlying directory). func (r *Root) Clone() (*Root, error) { return RootFromFile(r.inner) } diff --git a/go-pathrs/utils_linux.go b/go-pathrs/utils_linux.go index 4d258f19..668cb9be 100644 --- a/go-pathrs/utils_linux.go +++ b/go-pathrs/utils_linux.go @@ -34,9 +34,10 @@ func dupFd(fd uintptr, name string) (*os.File, error) { return os.NewFile(uintptr(newFd), name), nil } +//nolint:cyclop // this function needs to handle a lot of cases func toUnixMode(mode os.FileMode) (uint32, error) { sysMode := uint32(mode.Perm()) - switch mode & os.ModeType { + switch mode & os.ModeType { //nolint:exhaustive // we only care about ModeType bits case 0: sysMode |= unix.S_IFREG case os.ModeDir: