--- /dev/null
+#!/bin/bash
+
+set -e
+set -u
+
+VERBOSE="n"
+DEBUG="n"
+
+VERSION="0.1"
+
+# console colors:
+RED=""
+YELLOW=""
+GREEN=""
+BLUE=""
+NORMAL=""
+
+HAS_TTY='y'
+
+BASENAME="$(basename ${0})"
+BASE_DIR="$(dirname ${0})"
+
+declare -a MODULES=()
+PUPPET_ENV='*'
+ENV_DIR="/etc/puppetlabs/code/environments"
+
+#-------------------------------------------------------------------
+detect_color() {
+
+ local safe_term="${TERM//[^[:alnum:]]/?}"
+ local match_lhs=""
+ local use_color="false"
+ local term=
+
+ if [[ -f ~/.dir_colors ]] ; then
+ match_lhs="${match_lhs}$( grep '^TERM ' ~/.dir_colors | sed -e 's/^TERM *//' -e 's/ .*//')"
+ fi
+ if [[ -f /etc/DIR_COLORS ]] ; then
+ match_lhs="${match_lhs}$( grep '^TERM ' /etc/DIR_COLORS | sed -e 's/^TERM *//' -e 's/ .*//')"
+ fi
+ if [[ -z ${match_lhs} ]] ; then
+ type -P dircolors >/dev/null && \
+ match_lhs=$(dircolors --print-database | grep '^TERM ' | sed -e 's/^TERM *//' -e 's/ .*//')
+ fi
+ for term in ${match_lhs} ; do
+ if [[ "${safe_term}" == "${term}" || "${TERM}" == "${term}" || "${TERM}" =~ .*color ]] ; then
+ use_color="true"
+ break
+ fi
+ done
+
+ # console colors:
+ if [[ "${use_color}" = "true" ]] ; then
+ RED="\033[38;5;196m"
+ YELLOW="\033[38;5;226m"
+ GREEN="\033[38;5;46m"
+ # shellcheck disable=SC2034
+ BLUE="\033[38;5;27m"
+ CYAN="\033[38;5;14m"
+ NORMAL="\033[39m"
+ else
+ RED=""
+ YELLOW=""
+ GREEN=""
+ # shellcheck disable=SC2034
+ BLUE=""
+ CYAN=""
+ NORMAL=""
+ fi
+
+}
+detect_color
+
+#------------------------------------------------------------------------------
+description() {
+ echo -e $( cat <<-EOF
+ Retrieving version number of given Puppet module(s) in all environments.
+
+ EOF
+ )
+}
+
+#------------------------------------------------------------------------------
+usage() {
+ cat <<-EOF
+ Usage: ${BASENAME} [OPTIONS] [-E <ENVIRONMENT>] <MODULE> [<MODULE ...]
+ ${BASENAME} [-h|--help]
+ ${BASENAME} [-V|--version]
+
+ Options:
+ -E|--env|--environment ENVIRONMENT
+ The Puppet environment, in wich to search for the module version.
+ If not given, '*' (all) environments are searched.
+ -d|--debug Debug output (bash -x).
+ -v|--verbose Set verbosity on.
+ --nocolor Don't use colors on display.
+ -h|--help Show this output and exit.
+ -V|--version prints out version number of the script and exit
+ EOF
+}
+
+#------------------------------------------------------------------------------
+get_options() {
+
+ local tmp=
+ local base_dir=
+
+ set +e
+ tmp=$( getopt -o E:dvhV \
+ --long env:,environment:,debug,verbose,nocolor,help,version \
+ -n "${BASENAME}" -- "$@" )
+ if [[ $? != 0 ]] ; then
+ echo "" >&2
+ usage >&2
+ exit 1
+ fi
+ set -e
+
+ # Note the quotes around `$TEMP': they are essential!
+ eval set -- "${tmp}"
+
+ local p=
+
+ while true ; do
+ # echo "Evaluating option '$1' ..."
+ case "$1" in
+ -E|--env|--environment)
+ PUPPET_ENV="$2"
+ shift
+ shift
+ ;;
+ -d|--debug)
+ DEBUG="y"
+ shift
+ ;;
+ -v|--verbose)
+ VERBOSE="y"
+ shift
+ ;;
+ --nocolor)
+ RED=""
+ YELLOW=""
+ GREEN=""
+ BLUE=""
+ NORMAL=""
+ shift
+ ;;
+ -h|--help)
+ description
+ usage
+ exit 0
+ ;;
+ -V|--version)
+ echo "${BASENAME} version: ${VERSION}"
+ exit 0
+ ;;
+ --) shift
+ break
+ ;;
+ *) echo "Internal error!"
+ exit 1
+ ;;
+ esac
+ done
+
+ if [[ "${DEBUG}" = "y" ]] ; then
+ set -x
+ fi
+
+ if [[ ! -d "${ENV_DIR}" ]] ; then
+ error "Puppet environments directory '${RED}${ENV_DIR}${NORMAL}' does not exists."
+ exit 5
+ fi
+
+ if [[ "$#" -lt 1 ]] ; then
+ error "No module name to search for the version given."
+ usage >&2
+ exit 1
+ else
+ local mod
+ for mod in "$@" ; do
+ MODULES+=( "${mod}" )
+ done
+ fi
+
+}
+
+#########################################
+# Some often used funktions
+
+#------------------------------------------------------------------------------
+my_date() {
+ date +'%F %T.%N %:::z'
+}
+
+#------------------------------------------------------------------------------
+debug() {
+ if [[ "${VERBOSE}" != "y" ]] ; then
+ return 0
+ fi
+ echo -e " * [$(my_date)] [${BASENAME}:DEBUG]: $@" >&2
+}
+
+#------------------------------------------------------------------------------
+info() {
+ echo -e " ${GREEN}*${NORMAL} [$(my_date)] [${BASENAME}:${GREEN}INFO${NORMAL}] : $@" >&2
+}
+
+#------------------------------------------------------------------------------
+warn() {
+ echo -e " ${YELLOW}*${NORMAL} [$(my_date)] [${BASENAME}:${YELLOW}WARN${NORMAL}] : $@" >&2
+}
+
+#------------------------------------------------------------------------------
+error() {
+ echo -e " ${RED}*${NORMAL} [$(my_date)] [${BASENAME}:${RED}ERROR${NORMAL}]: $@" >&2
+}
+
+#------------------------------------------------------------------------------
+get_module_version() {
+
+ local env=
+ local env_dir=
+ local module=
+ local ver=
+ local md_file=
+ local -a envs=()
+ local -a env_dirs=()
+ local -a md_files=()
+ local -A versions=()
+
+ for env_dir in ${ENV_DIR}/${PUPPET_ENV} ; do
+ if [[ ! -d "${env_dir}" ]] ; then
+ error "Puppet environment '${RED}${PUPPET_ENV}${NORMAL}' does not exsist."
+ exit 7
+ fi
+ env=$( basename "${env_dir}" )
+ env_dirs+=( "${env_dir}" )
+ done
+
+ # grep '"version"' /etc/puppetlabs/code/environments/*/modules/infra/metadata.json | sed -e 's|/etc/puppetlabs/code/environments/||' -e 's|/modules/.*/metadata.json:[ ]*||' -e 's/"version"//' -e 's/,//g'
+
+ for module in "${MODULES[@]}" ; do
+
+ echo
+ echo -e "Versions of module '${CYAN}${module}${NORMAL}':"
+
+ md_files=()
+ envs=()
+ for env_dir in "${env_dirs[@]}" ; do
+ md_file="${env_dir}/modules/${module}/metadata.json"
+ if [[ ! -f "${md_file}" ]] ; then
+ warn "No ${CYAN}metadata.json${NORMAL} for module '${YELLOW}${module}${NORMAL}' found."
+ continue
+ fi
+ env=$( basename "${env_dir}" )
+ envs+=( "${env}" )
+ md_files+=( "${env_dir}/modules/${module}/metadata.json" )
+ done
+ if [[ "${#md_files[*]}" == 0 ]] ; then
+ error "Module '${RED}${module}${NORMAL}' seems not to exists."
+ continue
+ fi
+
+ local max_len_env=1
+ for env in "${envs[@]}" ; do
+ local len=$( printf "${env}" | wc -c )
+ if [[ "${len}" -gt "${max_len_env}" ]] ; then
+ max_len_env="${len}"
+ fi
+ done
+ max_len_env=$(( max_len_env + 1 ))
+
+ for md_file in "${md_files[@]}" ; do
+ env=$( echo "${md_file}" | sed -e "s|${ENV_DIR}/||" -e 's|/modules/.*/metadata.json||' )
+ ver=$( grep --no-filename '"version"' "${md_file}" | sed -e 's/"version"//' -e 's/,//g' -e 's/^[ ]*:[ ]*//g' -e 's/"//g' )
+ printf "%-${max_len_env}s ${CYAN}${ver}${NORMAL}\n" "${env}:"
+ done
+
+ done
+
+}
+
+################################################################################
+##
+## Main
+##
+################################################################################
+
+#------------------------------------------------------------------------------
+main() {
+
+ get_options "$@"
+
+ get_module_version
+
+ echo
+ info "Finished."
+
+}
+
+main "$@"
+
+exit 0
+
+# vim: ts=4 et list