Skip to content

Instantly share code, notes, and snippets.

@lzambarda
Last active March 8, 2022 15:47
Show Gist options
  • Save lzambarda/2767e6480ca751ca34cf085b5a44c440 to your computer and use it in GitHub Desktop.
Save lzambarda/2767e6480ca751ca34cf085b5a44c440 to your computer and use it in GitHub Desktop.
Bash script to use with go generate to register queries on the fly
# This script generates a register_queries.go file which uses embed
# to pack queries in a binary.
#
# The generated file will panic if additional queries are added to
# the query folder.
#
# This can then be hooked up in any go file with:
#
# //go:generate sh ./generator.sh query queries
# var queries map[string]string
#
# Note that the generated file won't compile in go if the folder is
# empty. This is due to how embed works.
# https://github.com/golang/go/blob/c016133c50512e9a83e7442bd7ac614fe7ca62de/src/cmd/go/internal/load/pkg.go#L2123
#!/bin/sh
if [ $# -ne "2" ]; then
echo "Error, usage is: generator.sh <query_folder_name> <query_map_name>"
exit 1
fi
query_folder_name=$1
query_map_name=$2
constants=""
map_entries=""
for query in $PWD/$query_folder_name/*.sql; do
[ -f "$query" ] || continue
echo "Registering query $query"
query="$(basename $query)"
varName="$(echo $query | cut -f 1 -d '.' | perl -pe 's/_(\w)/\U$1/g')Query"
constants="${constants}\n$varName = \"$query\""
mapEntries="${mapEntries}\n$varName : true,"
done
package="$(grep -ohE "^package [a-z]+$" $PWD/*.go | uniq)"
if [ -z "$package" ]; then
echo "Error, cannot identify go package at $PWD"
exit 1
fi
target_file="$PWD/register_queries.go"
cat <<EOF > $target_file
// Code generated by repo/generator/generator.sh. DO NOT EDIT.
$(echo $package)
const ($(echo $constants)
)
//go:embed $query_folder_name
var embeddedQueryFS embed.FS
func init() {
$query_map_name = map[string]string{}
toLoad := map[string]bool{$(echo $mapEntries)
}
queryFiles, err := embeddedQueryFS.ReadDir("query")
if err != nil {
panic(err)
}
for _, queryFile := range queryFiles {
if _, ok := toLoad[queryFile.Name()]; !ok {
panic(fmt.Errorf("query file %q is not specified as to be loaded", queryFile.Name()))
}
query, err := embeddedQueryFS.ReadFile(path.Join("query", queryFile.Name()))
if err != nil {
panic(errors.Wrapf(err, "reading %q from source embedded FS", queryFile.Name()))
}
$query_map_name[queryFile.Name()] = string(query)
}
}
EOF
go fmt $target_file
goimports -w $target_file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment