diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 2219511..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: 2.1 - -references: - images: - go: &GOLANG_IMAGE docker.mirror.hashicorp.services/circleci/golang:1.15.3 - environments: - tmp: &TEST_RESULTS_PATH /tmp/test-results # path to where test results are saved - -# reusable 'executor' object for jobs -executors: - go: - docker: - - image: *GOLANG_IMAGE - environment: - - TEST_RESULTS: *TEST_RESULTS_PATH - -jobs: - go-test: - executor: go - steps: - - checkout - - run: mkdir -p $TEST_RESULTS - - - restore_cache: # restore cache from dev-build job - keys: - - go-version-modcache-v1-{{ checksum "go.mod" }} - - - run: go mod download - - # Save go module cache if the go.mod file has changed - - save_cache: - key: go-version-modcache-v1-{{ checksum "go.mod" }} - paths: - - "/go/pkg/mod" - - # check go fmt output because it does not report non-zero when there are fmt changes - - run: - name: check go fmt - command: | - files=$(go fmt ./...) - if [ -n "$files" ]; then - echo "The following file(s) do not conform to go fmt:" - echo "$files" - exit 1 - fi - - # run go tests with gotestsum - - run: | - PACKAGE_NAMES=$(go list ./...) - gotestsum --format=short-verbose --junitfile $TEST_RESULTS/gotestsum-report.xml -- $PACKAGE_NAMES - - store_test_results: - path: *TEST_RESULTS_PATH - - store_artifacts: - path: *TEST_RESULTS_PATH - -workflows: - version: 2 - test-and-build: - jobs: - - go-test diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f401df1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + labels: ["dependencies"] + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + labels: + - dependencies + # only update HashiCorp actions, external actions managed by TSCCR + allow: + - dependency-name: hashicorp/* + groups: + github-actions-breaking: + update-types: + - major + github-actions-backward-compatible: + update-types: + - minor + - patch diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml new file mode 100644 index 0000000..ca6882a --- /dev/null +++ b/.github/workflows/go-tests.yml @@ -0,0 +1,74 @@ +name: go-tests + +on: [push] + +env: + TEST_RESULTS: /tmp/test-results + +jobs: + + go-tests: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: [ 1.15.3, 1.19 ] + + steps: + - name: Setup go + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + with: + go-version: ${{ matrix.go-version }} + + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + + - name: Create test directory + run: | + mkdir -p ${{ env.TEST_RESULTS }} + + - name: Download go modules + run: go mod download + + - name: Cache / restore go modules + uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 + with: + path: | + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + # Check go fmt output because it does not report non-zero when there are fmt changes + - name: Run gofmt + run: | + go fmt ./... + files=$(go fmt ./...) + if [ -n "$files" ]; then + echo "The following file(s) do not conform to go fmt:" + echo "$files" + exit 1 + fi + + # Install gotestsum with go get for 1.15.3; otherwise default to go install + - name: Install gotestsum + run: | + GTS="gotest.tools/gotestsum@v1.8.2" + # We use the same error message prefix in either failure case, so just define it once here. + ERROR="Failed to install $GTS" + # First try to 'go install', if that fails try 'go get'... + go install "$GTS" || go get "$GTS" || { echo "$ERROR: both 'go install' and 'go get' failed"; exit 1; } + # Check that the gotestsum command was actually installed in the path... + command -v gotestsum > /dev/null 2>&1 || { echo "$ERROR: gotestsum command not installed"; exit 1; } + echo "OK: Command 'gotestsum' installed ($GTS)" + + - name: Run go tests + run: | + PACKAGE_NAMES=$(go list ./...) + gotestsum --format=short-verbose --junitfile $TEST_RESULTS/gotestsum-report.xml -- $PACKAGE_NAMES + + # Save coverage report parts + - name: Upload and save artifacts + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: Test Results + path: ${{ env.TEST_RESULTS }} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f16dd1..6d48174 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +# 1.7.0 (May 24, 2024) + +ENHANCEMENTS: + +- Remove `reflect` dependency ([#91](https://github.com/hashicorp/go-version/pull/91)) +- Implement the `database/sql.Scanner` and `database/sql/driver.Value` interfaces for `Version` ([#133](https://github.com/hashicorp/go-version/pull/133)) + +INTERNAL: + +- [COMPLIANCE] Add Copyright and License Headers ([#115](https://github.com/hashicorp/go-version/pull/115)) +- [COMPLIANCE] Update MPL-2.0 LICENSE ([#105](https://github.com/hashicorp/go-version/pull/105)) +- Bump actions/cache from 3.0.11 to 3.2.5 ([#116](https://github.com/hashicorp/go-version/pull/116)) +- Bump actions/checkout from 3.2.0 to 3.3.0 ([#111](https://github.com/hashicorp/go-version/pull/111)) +- Bump actions/upload-artifact from 3.1.1 to 3.1.2 ([#112](https://github.com/hashicorp/go-version/pull/112)) +- GHA Migration ([#103](https://github.com/hashicorp/go-version/pull/103)) +- github: Pin external GitHub Actions to hashes ([#107](https://github.com/hashicorp/go-version/pull/107)) +- SEC-090: Automated trusted workflow pinning (2023-04-05) ([#124](https://github.com/hashicorp/go-version/pull/124)) +- update readme ([#104](https://github.com/hashicorp/go-version/pull/104)) + # 1.6.0 (June 28, 2022) FEATURES: diff --git a/LICENSE b/LICENSE index c33dcc7..1409d6a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2014 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/README.md b/README.md index 4d25050..4b7806c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Versioning Library for Go -[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/main.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/main) +![Build Status](https://github.com/hashicorp/go-version/actions/workflows/go-tests.yml/badge.svg) [![GoDoc](https://godoc.org/github.com/hashicorp/go-version?status.svg)](https://godoc.org/github.com/hashicorp/go-version) go-version is a library for parsing versions and version constraints, diff --git a/constraint.go b/constraint.go index da5d1ac..29bdc4d 100644 --- a/constraint.go +++ b/constraint.go @@ -1,8 +1,10 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import ( "fmt" - "reflect" "regexp" "sort" "strings" @@ -199,7 +201,7 @@ func prereleaseCheck(v, c *Version) bool { case cPre && vPre: // A constraint with a pre-release can only match a pre-release version // with the same base segments. - return reflect.DeepEqual(c.Segments64(), v.Segments64()) + return v.equalSegments(c) case !cPre && vPre: // A constraint without a pre-release can only match a version without a diff --git a/constraint_test.go b/constraint_test.go index 5338c8e..e76d3b0 100644 --- a/constraint_test.go +++ b/constraint_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import ( diff --git a/version.go b/version.go index e87df69..7c683c2 100644 --- a/version.go +++ b/version.go @@ -1,9 +1,12 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import ( "bytes" + "database/sql/driver" "fmt" - "reflect" "regexp" "strconv" "strings" @@ -117,11 +120,8 @@ func (v *Version) Compare(other *Version) int { return 0 } - segmentsSelf := v.Segments64() - segmentsOther := other.Segments64() - // If the segments are the same, we must compare on prerelease info - if reflect.DeepEqual(segmentsSelf, segmentsOther) { + if v.equalSegments(other) { preSelf := v.Prerelease() preOther := other.Prerelease() if preSelf == "" && preOther == "" { @@ -137,6 +137,8 @@ func (v *Version) Compare(other *Version) int { return comparePrereleases(preSelf, preOther) } + segmentsSelf := v.Segments64() + segmentsOther := other.Segments64() // Get the highest specificity (hS), or if they're equal, just use segmentSelf length lenSelf := len(segmentsSelf) lenOther := len(segmentsOther) @@ -160,7 +162,7 @@ func (v *Version) Compare(other *Version) int { // this means Other had the lower specificity // Check to see if the remaining segments in Self are all zeros - if !allZero(segmentsSelf[i:]) { - //if not, it means that Self has to be greater than Other + // if not, it means that Self has to be greater than Other return 1 } break @@ -180,6 +182,21 @@ func (v *Version) Compare(other *Version) int { return 0 } +func (v *Version) equalSegments(other *Version) bool { + segmentsSelf := v.Segments64() + segmentsOther := other.Segments64() + + if len(segmentsSelf) != len(segmentsOther) { + return false + } + for i, v := range segmentsSelf { + if v != segmentsOther[i] { + return false + } + } + return true +} + func allZero(segs []int64) bool { for _, s := range segs { if s != 0 { @@ -405,3 +422,20 @@ func (v *Version) UnmarshalText(b []byte) error { func (v *Version) MarshalText() ([]byte, error) { return []byte(v.String()), nil } + +// Scan implements the sql.Scanner interface. +func (v *Version) Scan(src interface{}) error { + switch src := src.(type) { + case string: + return v.UnmarshalText([]byte(src)) + case nil: + return nil + default: + return fmt.Errorf("cannot scan %T as Version", src) + } +} + +// Value implements the driver.Valuer interface. +func (v *Version) Value() (driver.Value, error) { + return v.String(), nil +} diff --git a/version_collection.go b/version_collection.go index cc888d4..83547fe 100644 --- a/version_collection.go +++ b/version_collection.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version // Collection is a type that implements the sort.Interface interface diff --git a/version_collection_test.go b/version_collection_test.go index 14783d7..b6298a8 100644 --- a/version_collection_test.go +++ b/version_collection_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import ( diff --git a/version_test.go b/version_test.go index 08cbf01..8256794 100644 --- a/version_test.go +++ b/version_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package version import (