diff --git a/.codeclimate.yml b/.codeclimate.yml index cf80241..f407dcb 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,7 +1,5 @@ --- engines: - golint: - enabled: true gofmt: enabled: true govet: diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9c6015c..6346ff1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,59 +2,68 @@ ## Getting Started -## Layout - This is a single top-level namespace filled with packages. Each directory is potentially a package. Binary builds are done on packages with a main subpackage. -## Building Locally +## Install Golang -### Go Version +### Using asdf-vm +We utilize a `.go-version` file that can be used by [asdf-vm](https://github.com/kennyp/asdf-golang) like so: -Requires Go `>= 1.14`. +```bash +cd /path/to/sopstool/repository/ +asdf plugin add golang +asdf install golang +``` -1. Install go (currently 1.14) +### Using goenv - You may want to use a version manager. +[goenv](https://github.com/syndbg/goenv) will prefer the `GOENV_VERSION` environment variable first before looking for the `.go-version` file when [determining which Golang version](https://github.com/syndbg/goenv/blob/master/HOW_IT_WORKS.md#choosing-the-go-version) to install. If you do not have this set (`echo $GOENV_VERSION` is empty), install like so: - - [asdf](https://github.com/kennyp/asdf-golang) +```bash +cd /path/to/sopstool/repository/ +goenv install +``` - ```sh - asdf install golang 1.14 - # use global to update default go version. local set just for current directory - asdf local golang 1.14 - ``` +### Using gimme +[gimme](https://github.com/travis-ci/gimme) uses `eval` in a simple way: - - [goenv](https://github.com/syndbg/goenv) is another option. +```bash +eval "$(gimme 1.17)" +``` - ```sh - goenv install 1.14 - go version - # go version go1.14 darwin/amd64 - ``` +### From the developers - - [gimme](https://github.com/travis-ci/gimme) +You can download and install the Golang [directly from the website](https://go.dev/dl/). -1. Install gomock +### Additional Go Libraries - ```sh - go get -u github.com/golang/mock/gomock && go install github.com/golang/mock/mockgen - ``` +Install [gomock](https://github.com/golang/mock) + +```sh +go get -u github.com/golang/mock/gomock && go install github.com/golang/mock/mockgen +``` -### Build +Install [golangci-lint](https://golangci-lint.run/) -With go 1.11+ and addition of [Modules](https://github.com/golang/go/wiki/Modules), go projects can be located outside the GOPATH. +```sh +brew tap golangci/tap +brew install golangci/tap/golangci-lint +``` + +## Build -If you are having issues review [faq](https://github.com/golang/go/wiki/Modules#faqs--most-common) +With Go 1.11+ and addition of [Modules](https://github.com/golang/go/wiki/Modules), Go projects can be located outside the `$GOPATH`. -If generate has already run, then it does not need to run again. +If you are having issues, review the [FAQ](https://github.com/golang/go/wiki/Modules#faqs--most-common). + +If `generate` has already run, then it does not need to run again. ```sh go build go fmt ./... -golint ./... ``` -### Unit Test +## Unit Tests Each module is unit tested, and passes all tests. @@ -62,6 +71,14 @@ Each module is unit tested, and passes all tests. go test ./... ``` +## Linting + +`golangci-lint` runs several popular Go linters quickly: + +```sh +golangci-lint run +``` + ## Releasing This project uses [GoReleaser](https://goreleaser.com/) for builds and releases. Doing the tag/release below triggers the appropriate actions. @@ -70,25 +87,25 @@ This project uses [GoReleaser](https://goreleaser.com/) for builds and releases. You can preview the package changes by running `scripts/release-preview`. This will show a summary of changes since the last release. -1. Prepare the release +1. Prepare the release: ```sh git checkout master && git pull ``` - Commit and tag with the intended version bump + Commit and tag with the intended version bump: ```sh git commit -am "Tagging release $VERSION" && git tag v$VERSION ``` - for example: + For example: ```sh git commit -am "Tagging release 0.1.1" && git tag v0.1.1 ``` - Then push the tag and commit to github + Then push the tag and commit to Github: ```sh git push && git push --tags # or git push --follow-tags but YMMV @@ -133,4 +150,4 @@ Document all public APIs to help users understand the module at a glance. Also c ### Style -Clean up style warnings thrown by gofmt/golint (configured at the base of this repository). These will be marked as build failures in CI. Also consider using 'gofmt' to automatically clean up your code style while conforming to the configuration. +Clean up style warnings thrown by gofmt/golangci-lint (configured at the base of this repository in `.golangci.yml`). These will be marked as build failures in CI. Also consider using these tools to automatically clean up your code style while conforming to the configuration. diff --git a/.gitignore b/.gitignore index 0f834f9..8b0d0c4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ sopstool c.out *.cover .idea +.vscode \ No newline at end of file diff --git a/.go-version b/.go-version new file mode 100644 index 0000000..b48f322 --- /dev/null +++ b/.go-version @@ -0,0 +1 @@ +1.17 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..c6e70ca --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,20 @@ +run: + timeout: 2m + +linters: + disable-all: true + enable: + # defaults + - govet + - staticcheck + - gosimple + - typecheck + - revive + # additional + - goimports + - gosec + - misspell + - whitespace + +output: + format: colored-line-number diff --git a/.goreleaser.yml b/.goreleaser.yml index 34af178..bf23dca 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -7,12 +7,12 @@ builds: - darwin - linux goarch: - # sops is only available for amd64 - amd64 + - arm64 archives: - - id: zips - name_template: "{{ .ProjectName }}_{{ .Os }}" + - id: newzips + name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" checksum: # You can change the name of the checksums file. @@ -26,7 +26,12 @@ checksum: name_template: "{{ .ProjectName }}_checksums.txt" nfpms: - - file_name_template: "{{ .ProjectName }}_{{ .Os }}" + - id: default + # You can change the file name of the package. + # + # Default: `{{ .PackageName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}` + file_name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" + # file_name_template: "{{ .ProjectName }}_{{ .Os }}" vendor: Ibotta homepage: https://github.com/Ibotta/sopstool maintainer: Ibotta @@ -41,7 +46,9 @@ nfpms: - sops brews: - - tap: + - ids: + - newzips + tap: # Repo to push the tap owner: Ibotta name: homebrew-public @@ -90,7 +97,8 @@ blobs: folder: "{{ .ProjectName }}" dockers: - - goos: linux + - id: amd64image + goos: linux # GOARCH of the built binary that should be used. goarch: amd64 # GOARM of the built binary that should be used. @@ -102,6 +110,14 @@ dockers: image_templates: - "ibotta/{{ .ProjectName }}:latest" - "ibotta/{{ .ProjectName }}:{{ .Version }}" + - "ibotta/{{ .ProjectName }}:{{ .Tag }}" + - "ibotta/{{ .ProjectName }}:v{{ .Major }}" + - "ibotta/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}" + - "ibotta/{{ .ProjectName }}:latest-amd64" + - "ibotta/{{ .ProjectName }}:{{ .Version }}-amd64" + - "ibotta/{{ .ProjectName }}:{{ .Tag }}-amd64" + - "ibotta/{{ .ProjectName }}:v{{ .Major }}-amd64" + - "ibotta/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}-amd64" # Skips the docker push. Could be useful if you also do draft releases. # If set to auto, the release will not be pushed to the docker repository # in case there is an indicator for prerelease in the tag e.g. v1.0.0-rc1 diff --git a/.travis.yml b/.travis.yml index f115792..a8e200b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,14 +45,14 @@ cache: - "$HOME/gopath/pkg/mod" before_script: + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.45.2 - go mod download && go build script: # See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions + - 'golangci-lint run' - 'if [ "$TRAVIS_PULL_REQUEST" = "true" ]; then bash go test ./...; fi' - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./scripts/coverage_test; fi' - -after_script: - goreleaser --snapshot --skip-publish --rm-dist deploy: diff --git a/README.md b/README.md index 052f026..9f3ceb7 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ sopstool is a multi-file wrapper around [sops](https://github.com/mozilla/sops). sopstool provides functionality to manage multiple secret files at once, and even use as an entrypoint to decrypt at startup, for container images. Much of this behavior is inspired by the great [blackbox project](https://github.com/StackExchange/blackbox). +## 1.0.0 Release and Breaking Changes +1.0.0 release of `sopstool` introduces M1 / darwin-arm64 support. We also want to match build artifacts produced by GoReleaser to what `sops` produces. Therefore, this version introduces a breaking change where we no longer produce artifacts like `sopstool_linux.(deb|rpm|tar.gz)` and `sopstool_darwin.tar.gz`. Instead, you'll see artifacts like `sopstool_darwin_(arm64|amd64)_(deb|rpm|tar.gz)` and `sopstool_linux_(arm64|amd64)_(deb|rpm|tar.gz)` in future releases. + ## Installation The most direct install uses a shell script hosted in this repository. This script will install the latest sops (if the command does not exist) and sopstool to `./bin` by default. @@ -27,6 +30,8 @@ curl https://raw.githubusercontent.com/Ibotta/sopstool/master/install.sh | SOPS_ ### Docker +**Note**: We currently only build a docker image for [Linux - amd64](.goreleaser.yml#L100). + To use sopstool in your docker container, you can use the direct install method above, but since Docker 1.13, there is a better way by using build stages! In your Dockerfile: diff --git a/cmd/clean.go b/cmd/clean.go index 0c5f77c..fdff92f 100644 --- a/cmd/clean.go +++ b/cmd/clean.go @@ -39,7 +39,6 @@ func CleanCommand(cmd *cobra.Command, args []string) error { return err } } - } return nil diff --git a/cmd/root.go b/cmd/root.go index 6b3f794..3f4769c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -30,9 +30,9 @@ var encrypter filecrypt.FileCrypt = filecrypt.SopsCryptInstance() var RootCmd = &cobra.Command{ Use: "sopstool", Short: "Wrapper around sops for multiple files", - Long: fmt.Sprintf(`sopstool + Long: `sopstool -sops wrapper supporting multiple files and helper commands.`), + sops wrapper supporting multiple files and helper commands.`, } // Execute adds all child commands to the root command and sets flags appropriately. diff --git a/filecrypt/sops.go b/filecrypt/sops.go index 6756486..e5e57a2 100644 --- a/filecrypt/sops.go +++ b/filecrypt/sops.go @@ -12,7 +12,7 @@ type sopsCrypt struct { var sops = sopsCrypt{ execWrap: oswrap.ExecWrapInstance(), - osWrap: oswrap.OsWrapInstance(), + osWrap: oswrap.Instance(), } // SopsCryptInstance gets an instance of the sops wrapper diff --git a/filecrypt/sops_test.go b/filecrypt/sops_test.go index d4cd0f9..0f3664c 100644 --- a/filecrypt/sops_test.go +++ b/filecrypt/sops_test.go @@ -25,7 +25,6 @@ func TestEncryptFile(t *testing.T) { } sops.execWrap = origEw - return }) } @@ -46,7 +45,6 @@ func TestDecryptFile(t *testing.T) { } sops.execWrap = origEw - return }) t.Run("run dec returns error", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -63,7 +61,6 @@ func TestDecryptFile(t *testing.T) { } sops.execWrap = origEw - return }) } @@ -84,7 +81,6 @@ func TestDecryptFilePrint(t *testing.T) { } sops.execWrap = origEw - return }) } @@ -105,7 +101,6 @@ func TestRemoveFile(t *testing.T) { } sops.osWrap = origOw - return }) } @@ -126,7 +121,6 @@ func TestRemoveCryptFile(t *testing.T) { } sops.osWrap = origOw - return }) } @@ -146,7 +140,6 @@ func TestRotateFile(t *testing.T) { } sops.execWrap = origEw - return }) } @@ -166,6 +159,5 @@ func TestEditFile(t *testing.T) { } sops.execWrap = origEw - return }) } diff --git a/go.mod b/go.mod index 2e5fb43..a5ef46e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Ibotta/sopstool go 1.17 require ( - github.com/golang/mock v1.5.0 + github.com/golang/mock v1.6.0 github.com/mozilla-services/yaml v0.0.0-20201007153854-c369669a6625 github.com/spf13/cobra v1.2.1 ) diff --git a/go.sum b/go.sum index 0d12e14..a47bc60 100644 --- a/go.sum +++ b/go.sum @@ -87,6 +87,8 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -446,6 +448,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/oswrap/exec.go b/oswrap/exec.go index c0b7504..691743c 100644 --- a/oswrap/exec.go +++ b/oswrap/exec.go @@ -13,7 +13,7 @@ type ExecWrap interface { type execWrap struct{} -//todo use OsWrapInstance() instead of package local ow? +//todo use oswrap.Instance() instead of package local ow? var ew ExecWrap = execWrap{} // ExecWrapInstance gets the execution wrapper interface diff --git a/oswrap/exec_test.go b/oswrap/exec_test.go index 2916c25..777f33e 100644 --- a/oswrap/exec_test.go +++ b/oswrap/exec_test.go @@ -2,6 +2,7 @@ package oswrap import ( "errors" + "io/ioutil" "os" "os/exec" "testing" @@ -31,7 +32,6 @@ func TestRunCommandDirect(t *testing.T) { } ow = origOW - return }) t.Run("run given with no args", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -51,7 +51,6 @@ func TestRunCommandDirect(t *testing.T) { } ow = origOW - return }) t.Run("run err", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -70,7 +69,6 @@ func TestRunCommandDirect(t *testing.T) { } ow = origOW - return }) } @@ -87,7 +85,7 @@ func TestRunCommandStdoutToFile(t *testing.T) { mock.EXPECT().Create(gomock.Eq("filename")).DoAndReturn(func(f string) (*os.File, error) { //TODO replace all file stuff with afero - return os.Create("/tmp/TestRunCommandStdoutToFile") + return ioutil.TempFile("/tmp", "TestRunCommandStdoutToFile") }) defer os.Remove("/tmp/TestRunCommandStdoutToFile") @@ -100,7 +98,6 @@ func TestRunCommandStdoutToFile(t *testing.T) { } ow = origOW - return }) t.Run("run given with no args", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -113,7 +110,7 @@ func TestRunCommandStdoutToFile(t *testing.T) { mock.EXPECT().Create(gomock.Eq("filename")).DoAndReturn(func(f string) (*os.File, error) { //TODO replace all file stuff with afero - return os.Create("/tmp/TestRunCommandStdoutToFile") + return ioutil.TempFile("/tmp", "TestRunCommandStdoutToFile") }) defer os.Remove("/tmp/TestRunCommandStdoutToFile") @@ -126,7 +123,6 @@ func TestRunCommandStdoutToFile(t *testing.T) { } ow = origOW - return }) t.Run("run err", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -139,7 +135,7 @@ func TestRunCommandStdoutToFile(t *testing.T) { mock.EXPECT().Create(gomock.Eq("filename")).DoAndReturn(func(f string) (*os.File, error) { //TODO replace all file stuff with afero - return os.Create("/tmp/TestRunCommandStdoutToFile") + return ioutil.TempFile("/tmp", "TestRunCommandStdoutToFile") }) defer os.Remove("/tmp/TestRunCommandStdoutToFile") @@ -154,7 +150,6 @@ func TestRunCommandStdoutToFile(t *testing.T) { } ow = origOW - return }) t.Run("file err", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -176,7 +171,6 @@ func TestRunCommandStdoutToFile(t *testing.T) { } ow = origOW - return }) // TODO test when Close err, but requires mocking of file } @@ -201,7 +195,6 @@ func TestRunSyscallExec(t *testing.T) { } ow = origOW - return }) t.Run("run given with no args", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -221,7 +214,6 @@ func TestRunSyscallExec(t *testing.T) { } ow = origOW - return }) t.Run("exec error", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -241,7 +233,6 @@ func TestRunSyscallExec(t *testing.T) { } ow = origOW - return }) t.Run("lookpath error", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -258,6 +249,5 @@ func TestRunSyscallExec(t *testing.T) { } ow = origOW - return }) } diff --git a/oswrap/os.go b/oswrap/os.go index 9d1bc6a..3c011f0 100644 --- a/oswrap/os.go +++ b/oswrap/os.go @@ -24,8 +24,8 @@ type osWrap struct{} var ow OsWrap = osWrap{} -// OsWrapInstance gets an instance of the os wrapper -func OsWrapInstance() OsWrap { +// oswrap.Instance gets an instance of the os wrapper +func Instance() OsWrap { return ow } diff --git a/sopsinstall.sh b/sopsinstall.sh index 9de4433..4a80325 100644 --- a/sopsinstall.sh +++ b/sopsinstall.sh @@ -333,7 +333,7 @@ LOWEST_V_VERSION=$(printf "$VERSION\n$MIN_V_VERSION" \ if [ "$LOWEST_V_VERSION" != "$MIN_V_VERSION" ]; then NAME=sops-${VERSION}.${OS} else - NAME=sops-v${VERSION}.${OS} + NAME=sops-v${VERSION}.${OS}.${ARCH} fi # adjust binary name based on OS diff --git a/sopstoolinstall.sh b/sopstoolinstall.sh index 7305197..5a53df7 100644 --- a/sopstoolinstall.sh +++ b/sopstoolinstall.sh @@ -63,7 +63,9 @@ execute() { get_binaries() { case "$PLATFORM" in darwin/amd64) BINARIES="sopstool" ;; + darwin/arm64) BINARIES="sopstool" ;; linux/amd64) BINARIES="sopstool" ;; + linux/arm64) BINARIES="sopstool" ;; *) log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new" exit 1 @@ -361,7 +363,7 @@ adjust_arch log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}" -NAME=${PROJECT_NAME}_${OS} +NAME=${PROJECT_NAME}_${OS}_${ARCH} TARBALL=${NAME}.${FORMAT} TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL} CHECKSUM=${PROJECT_NAME}_checksums.txt diff --git a/sopsyaml/sopsyaml.go b/sopsyaml/sopsyaml.go index 4fbfe20..95a644d 100644 --- a/sopsyaml/sopsyaml.go +++ b/sopsyaml/sopsyaml.go @@ -18,7 +18,7 @@ const ( encryptedFilesKey = "encrypted_files" ) -var osWrap = oswrap.OsWrapInstance() +var osWrap = oswrap.Instance() // SopsConfig holds info about an instance of the config file type SopsConfig struct { diff --git a/sopsyaml/sopsyaml_test.go b/sopsyaml/sopsyaml_test.go index d965e06..52925d0 100644 --- a/sopsyaml/sopsyaml_test.go +++ b/sopsyaml/sopsyaml_test.go @@ -8,7 +8,7 @@ import ( "testing" mock_oswrap "github.com/Ibotta/sopstool/oswrap/mock" - "github.com/Ibotta/sopstool/test_helpers" + "github.com/Ibotta/sopstool/testhelpers" "github.com/golang/mock/gomock" "github.com/mozilla-services/yaml" ) @@ -20,7 +20,7 @@ func TestFindConfigFile(t *testing.T) { defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil }) @@ -35,17 +35,16 @@ func TestFindConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("not found after never getting Stat", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(test_helpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(testhelpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") // Never git }).AnyTimes() - mock.EXPECT().Stat(test_helpers.RegexMatches(`^.*\.sops.yaml$`)).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(testhelpers.RegexMatches(`^.*\.sops.yaml$`)).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }).AnyTimes() @@ -57,24 +56,23 @@ func TestFindConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("levels deep", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(test_helpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(testhelpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") // Never git }).AnyTimes() - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }) - mock.EXPECT().Stat(gomock.Eq("../.sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq("../.sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }) - mock.EXPECT().Stat(gomock.Eq("../../.sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq("../../.sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil //found }) @@ -89,21 +87,20 @@ func TestFindConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("different start", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(test_helpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(testhelpers.RegexMatches(`^.*\.git$`)).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") // Never git }).AnyTimes() - mock.EXPECT().Stat(gomock.Not(gomock.Eq("directory/.sops.yaml"))).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Not(gomock.Eq("directory/.sops.yaml"))).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }).AnyTimes() - mock.EXPECT().Stat(gomock.Eq("directory/.sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq("directory/.sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil //found }) @@ -119,17 +116,16 @@ func TestFindConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("stops at git repo", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".git")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".git")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil //find git immediately }) - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }) @@ -141,7 +137,6 @@ func TestFindConfigFile(t *testing.T) { } osWrap = origOw - return }) } @@ -152,7 +147,7 @@ func TestLoadConfigFile(t *testing.T) { defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string) ([]byte, error) { return nil, fmt.Errorf("a file read error") }) @@ -165,14 +160,13 @@ func TestLoadConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("yaml error", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string) ([]byte, error) { yml := []byte(` ~~~not yaml at all @@ -193,14 +187,13 @@ func TestLoadConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("successful parse", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq("filepath")).DoAndReturn(func(c string) ([]byte, error) { yml := []byte(` yaml: - in @@ -223,7 +216,6 @@ yaml: } osWrap = origOw - return }) } @@ -232,8 +224,6 @@ func TestWriteConfigFile(t *testing.T) { t.Run("cant unmarshal", func(t *testing.T) { //TODO what are valid errors here t.Skipf("Unsure what would error in yaml yet") - - return }) t.Run("cant write", func(t *testing.T) { t.Skipf("Reflection of FileMode is messed up") @@ -261,7 +251,6 @@ func TestWriteConfigFile(t *testing.T) { } osWrap = origOw - return }) t.Run("write", func(t *testing.T) { t.Skipf("Reflection of FileMode is messed up") @@ -287,7 +276,6 @@ func TestWriteConfigFile(t *testing.T) { } osWrap = origOw - return }) } @@ -364,10 +352,10 @@ func TestGetConfigEncryptFiles(t *testing.T) { defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil }) - mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) ([]byte, error) { yml := []byte(` foo: bar encrypted_files: @@ -391,17 +379,16 @@ encrypted_files: } osWrap = origOw - return }) t.Run("err on file find", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".git")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".git")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil //find git immediately }).AnyTimes() - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, fmt.Errorf("Not Found") }).AnyTimes() @@ -414,17 +401,16 @@ encrypted_files: } osWrap = origOw - return }) t.Run("err on config load", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil }) - mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) ([]byte, error) { yml := []byte(`~~not good`) return yml, nil @@ -439,17 +425,16 @@ encrypted_files: } osWrap = origOw - return }) t.Run("err config extract", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_oswrap.NewMockOsWrap(ctrl) - mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) (*os.FileInfo, error) { + mock.EXPECT().Stat(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) (*os.FileInfo, error) { return nil, nil }) - mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string, args ...string) ([]byte, error) { + mock.EXPECT().ReadFile(gomock.Eq(".sops.yaml")).DoAndReturn(func(c string) ([]byte, error) { yml := []byte(`encrypted_files: [1,2,3]`) return yml, nil @@ -463,7 +448,6 @@ encrypted_files: } osWrap = origOw - return }) } @@ -556,7 +540,6 @@ func TestWriteEncryptFilesToDisk(t *testing.T) { } osWrap = origOw - return }) t.Run("file write error", func(t *testing.T) { t.Skipf("Reflection of FileMode is messed up") @@ -578,6 +561,5 @@ func TestWriteEncryptFilesToDisk(t *testing.T) { } osWrap = origOw - return }) } diff --git a/test_helpers/matchers.go b/testhelpers/matchers.go similarity index 96% rename from test_helpers/matchers.go rename to testhelpers/matchers.go index b38a8ba..2caf38d 100644 --- a/test_helpers/matchers.go +++ b/testhelpers/matchers.go @@ -1,4 +1,4 @@ -package test_helpers +package testhelpers import ( "fmt"