Created
October 29, 2022 09:23
-
-
Save ardnew/f1389c545026d3064e247e541770b7e8 to your computer and use it in GitHub Desktop.
Shell script to add go.mod replace directives when working with multiple local modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
usage() { | |
cat <<__usage__ | |
-- DESCRIPTION ----------------------------------------------------------------- | |
Insert a 'replace' directive into each given Go module (default: PWD) that | |
defines a local file path of a Go package to import instead of the published | |
package named in any of the given modules' import lists. | |
-- SYNOPSIS -------------------------------------------------------------------- | |
${0##*/} IMPORT PATH [MODULE ...] | |
-- ARGUMENTS ------------------------------------------------------------------- | |
- IMPORT Package path used in Go import clauses | |
- PATH Local filepath to use for the imported package | |
- MODULE (optional) Local filepath of Go module to modify | |
default: $PWD | |
__usage__ | |
exit | |
} | |
# halt prints an error message to stderr and exits the script with the given | |
# status code. The error message is provided as a printf-style format string | |
# and associated parameters. | |
# % halt [STATUS [FORMAT [PARAM...]]] | |
halt() { | |
local ret=${1:-127} | |
local pre='error' msg=${2:-'(unspecified)'} | |
[[ $ret =~ ^[0-9]*$ ]] || | |
ret=126 | |
[[ $# -gt 0 && $1 -eq 0 ]] && | |
pre='exit' msg=${2:-'OK'} | |
[[ $# -ge 3 ]] && | |
msg=$( printf -- "${2}" "${@:3}" ) | |
printf -- '%s(%d): %s\n' "${pre}" ${ret} "${msg}" >&2 | |
exit ${ret} | |
} | |
relpath() { | |
[ $# -ge 2 ] && | |
perl -MFile::Spec::Functions=abs2rel -le \ | |
'print abs2rel(@ARGV)' "${2}" "${1}" | |
} | |
replace() { | |
[ $# -ge 2 ] || return 1 | |
go mod edit -replace "${1}=${2}" | |
go mod tidy | |
} | |
[ $# -ge 2 ] || usage | |
module=( "${@:3}" ) | |
[ ${#module[@]} -gt 0 ] || module=( "$PWD" ) | |
for mod in "${module[@]}"; do | |
[ -d "$mod" ] && mod="$mod/go.mod" | |
[ "${mod##*/}" = "go.mod" ] && [ -f "$mod" ] || | |
halt 100 "module file invalid or not found: %s" "$mod" | |
path=${mod%/go.mod} | |
pushd "$path" &>/dev/null || | |
halt 101 "failed to open directory: %s" "$path" | |
replace "$1" "$( relpath "${PWD}" "$2" )" || | |
halt 102 "command failed: %s" "go mod edit / tidy" | |
popd &>/dev/null | |
done |
Warning
This script should no longer be used.
Tip
Go 1.18 added support for multi-module workspaces. You should now use a replace directive in go.work
to replace paths in multiple modules.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I can never remember the syntax used in the
go.mod
file, and I recently found a need to update multiple modules at once.TODO