diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 8363882..62c61e4 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -12,7 +12,7 @@ description: "Runs `goimports`, requires golang" - id: go-vet name: 'go vet' - entry: run-go-vet.sh + entry: run-go-vet.py files: '\.go$' language: 'script' description: "Runs `go vet`, requires golang" @@ -83,7 +83,7 @@ description: "Runs `go generate`, requires golang" - id: go-mod-tidy name: 'go-mod-tidy' - entry: run-go-mod-tidy.sh + entry: run-go-mod-tidy.py pass_filenames: false language: 'script' description: "Runs `go mod tidy -v`, requires golang" diff --git a/_workspace.py b/_workspace.py new file mode 100644 index 0000000..d18c292 --- /dev/null +++ b/_workspace.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import json +import os +import subprocess + + +def get_package_path(path, modules): + for module in modules: + mod_path = module["AbsolutePath"] + file_path = os.path.abspath(path) + + if file_path == mod_path or file_path.startswith(mod_path + os.path.sep): + return module["ModPath"] + file_path[len(mod_path) :] + + raise ValueError("no module found for path") + + +def get_modules(): + if not os.path.exists("go.work"): + return { + "AbsolutePath": os.path.abspath("."), + "ModPath": subprocess.check_output(["go", "list"]), + } + + workspace_config = json.loads( + subprocess.check_output(["go", "work", "edit", "-json"]) + ) + return [ + { + "AbsolutePath": os.path.abspath(workspace["DiskPath"]), + "ModPath": workspace["ModPath"], + } + for workspace in workspace_config["Use"] + ] \ No newline at end of file diff --git a/run-go-build.sh b/run-go-build.sh index c324604..b150112 100755 --- a/run-go-build.sh +++ b/run-go-build.sh @@ -1,3 +1,12 @@ #!/usr/bin/env bash -FILES=$(go list ./... | grep -v /vendor/) + +set -eu -o pipefail + +MODULES=. +if [[ -f go.work ]]; then + MODULES="$(go work edit -json | python -c 'import json,sys;print("\n".join(w["ModPath"] for w in json.load(sys.stdin)["Use"]))')" +fi + +FILES="$(xargs -I '{}' go list '{}/...' <<< "${MODULES}" | grep -v /vendor/)" + exec go build $FILES diff --git a/run-go-mod-tidy.py b/run-go-mod-tidy.py new file mode 100755 index 0000000..27e31fb --- /dev/null +++ b/run-go-mod-tidy.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +from _workspace import get_modules + + +def main(args): + modules = get_modules() + for module in modules: + subprocess.check_call( + ["go", "mod", "tidy"], + cwd=module['AbsolutePath'], + ) + + try: + subprocess.check_call( + ["git", "diff", "--exit-code", "go.mod", "go.sum"], + cwd=module['AbsolutePath'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + except subprocess.CalledProcessError: + print("go.mod or go.sum differs, please re-add it to your commit", file=sys.stderr) + return 3 + + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/run-go-unit-tests.sh b/run-go-unit-tests.sh index e680949..2a6b585 100755 --- a/run-go-unit-tests.sh +++ b/run-go-unit-tests.sh @@ -1,9 +1,16 @@ #!/usr/bin/env bash +set -eu -o pipefail + fail() { echo "unit tests failed" exit 1 } -FILES=$(go list ./... | grep -v /vendor/) || fail +MODULES=. +if [[ -f go.work ]]; then + MODULES="$(go work edit -json | python -c 'import json,sys;print("\n".join(w["ModPath"] for w in json.load(sys.stdin)["Use"]))')" +fi + +FILES=$(xargs -I '{}' go list '{}/...' <<< "${MODULES}" | grep -v /vendor/) || fail go test -tags=unit -timeout 30s -short -v ${FILES} || fail diff --git a/run-go-vet.py b/run-go-vet.py new file mode 100755 index 0000000..d3d6996 --- /dev/null +++ b/run-go-vet.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import os +import sys + +from _workspace import get_modules, get_package_path + + +def main(args): + modules = get_modules() + paths = set(get_package_path(os.path.dirname(arg), modules) for arg in args) + os.execvp("go", ["go", "vet", *paths]) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/run-go-vet.sh b/run-go-vet.sh deleted file mode 100755 index 0d21ea4..0000000 --- a/run-go-vet.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -e -pkg=$(go list) -for dir in $(echo $@|xargs -n1 dirname|sort -u); do - go vet $pkg/$dir -done