diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e33138b..6c12a5d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.20', '1.21'] + go-version: ['1.21', '1.22'] fail-fast: true steps: - name: Checkout diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 99cfd8fe..0dd22daa 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: security-events: write strategy: matrix: - go-version: ['1.20', '1.21'] + go-version: ['1.21', '1.22'] fail-fast: false steps: - name: Checkout repository diff --git a/README.md b/README.md index 70662555..7c3013c7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The ORAS Go library follows [Semantic Versioning](https://semver.org/), where br The version `2` is actively developed in the [`main`](https://github.com/oras-project/oras-go/tree/main) branch with all new features. > [!Note] -> The `main` branch follows [Go's Security Policy](https://github.com/golang/go/security/policy) and supports the two latest versions of Go (currently `1.20` and `1.21`). +> The `main` branch follows [Go's Security Policy](https://github.com/golang/go/security/policy) and supports the two latest versions of Go (currently `1.21` and `1.22`). Examples for common use cases can be found below: diff --git a/go.mod b/go.mod index 20a4bc5a..85b83d90 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module oras.land/oras-go/v2 -go 1.20 +go 1.21 require ( github.com/opencontainers/go-digest v1.0.0 diff --git a/internal/ioutil/io.go b/internal/ioutil/io.go index 888d26f8..105230d1 100644 --- a/internal/ioutil/io.go +++ b/internal/ioutil/io.go @@ -46,13 +46,21 @@ func CopyBuffer(dst io.Writer, src io.Reader, buf []byte, desc ocispec.Descripto // nopCloserType is the type of `io.NopCloser()`. var nopCloserType = reflect.TypeOf(io.NopCloser(nil)) +// nopCloserWriterToType is the type of `io.nopCloserWriterTo` +var nopCloserWriterToType = reflect.TypeOf(io.NopCloser(struct { + io.Reader + io.WriterTo +}{})) -// UnwrapNopCloser unwraps the reader wrapped by `io.NopCloser()`. +// UnwrapNopCloser returns the underlying reader if rc is a NopCloser +// else it simply returns rc. // Similar implementation can be found in the built-in package `net/http`. -// Reference: https://github.com/golang/go/blob/go1.17.6/src/net/http/transfer.go#L423-L425 +// Reference: https://github.com/golang/go/blob/go1.22.1/src/net/http/transfer.go#L1090-L1105 func UnwrapNopCloser(rc io.Reader) io.Reader { - if reflect.TypeOf(rc) == nopCloserType { + switch reflect.TypeOf(rc) { + case nopCloserType, nopCloserWriterToType: return reflect.ValueOf(rc).Field(0).Interface().(io.Reader) + default: + return rc } - return rc }