#!/usr/bin/env bash
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
readonly SCRIPT_NAME = " $( basename ${ BASH_SOURCE [0] } ) "
readonly SCRIPT_DIR = " $( dirname " ${ BASH_SOURCE [0] } " ) "
readonly SOURCE_DIR = " $( dirname " $( dirname " ${ SCRIPT_DIR } " ) " ) "
readonly FN_DIR = " $( dirname " ${ SCRIPT_DIR } " ) /functions "
source " ${ SCRIPT_DIR } /functions.sh "
set -uo pipefail
usage( ) {
cat <<-EOF
Usage: ${ SCRIPT_NAME } <module root> [ <allowed relative package path>...]
Description:
Verifies that only the specified packages may be imported from the given module
Options:
-h | --help Print this help text.
EOF
}
function err_usage {
err " $1 "
err ""
err " $( usage) "
}
function main {
local module_root = ""
declare -a allowed_packages = ( )
while test $# -gt 0
do
case " $1 " in
-h | --help )
usage
return 0
; ;
* )
if test -z " $module_root "
then
module_root = " $1 "
else
allowed_packages += ( " $1 " )
fi
shift
esac
done
# If we could guarantee this ran with bash 4.2+ then the final argument could
# be just ${allowed_packages[@]}. However that with older versions of bash
# in combination with set -u causes bash to emit errors about using unbound
# variables when no allowed packages have been specified (i.e. the module should
# generally be disallowed with no exceptions). This syntax is very strange
# but seems to be the prescribed workaround I found.
check_imports " $module_root " ${ allowed_packages [@]+ " ${ allowed_packages [@] } " }
return $?
}
function check_imports {
local module_root = " $1 "
shift
local allowed_packages = " $@ "
module_imports = $( go list -test -f '{{join .TestImports "\n"}}' ./... | grep " $module_root " | sort | uniq)
module_test_imports = $( go list -test -f '{{join .TestImports "\n"}}' ./... | grep " $module_root " | sort | uniq)
any_error = 0
for imp in $module_imports
do
is_import_allowed " $imp " " $module_root " $allowed_packages
allowed = $?
if test $any_error -ne 1
then
any_error = $allowed
fi
done
if test $any_error -eq 1
then
echo " Only the following direct imports are allowed from module $module_root : "
for pkg in $allowed_packages
do
echo " * $pkg "
done
fi
return $any_error
}
function is_import_allowed {
local pkg_import = $1
shift
local module_root = $1
shift
local allowed_packages = " $@ "
# check if the import path is a part of the module we are restricting imports for
if test " $( go list -f '{{.Module.Path}}' $pkg_import ) " != " $module_root "
then
return 0
fi
for pkg in $allowed_packages
do
if test " ${ module_root } / $pkg " = = " $pkg_import "
then
return 0
fi
done
err " Import of package $pkg_import is not allowed "
return 1
}
main " $@ "
exit $?