aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/distro-manifest-generator.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/distro-manifest-generator.sh')
-rwxr-xr-xscripts/distro-manifest-generator.sh255
1 files changed, 206 insertions, 49 deletions
diff --git a/scripts/distro-manifest-generator.sh b/scripts/distro-manifest-generator.sh
index 9a910e5a5..834cde248 100755
--- a/scripts/distro-manifest-generator.sh
+++ b/scripts/distro-manifest-generator.sh
@@ -26,20 +26,132 @@
#
################################################################################
+mode=deploy
+manifest=
+verbose=0
+format=bash
+sourcefile=
+
+function info() { echo "$@" >&2; }
+function error() { echo "$BASH_SOURCE: $@" >&2; }
+function out() { echo -n "$@"; }
+function out_object() {
+ # expected stdin stream is:
+ # --------------
+ # key
+ # value
+ # key
+ # value
+ # ...
+ # --------------
+ local sep=""
+ local k
+ case $format in
+ bash)
+ while read x; do
+ [[ -z "$k" ]] && { k="$x"; continue; }
+ out "$sep${k}="
+ out_value "$x"
+ sep=$'\n'
+ k=
+ done
+ out "$sep"
+ ;;
+ json)
+ out "{"
+ while read x; do
+ [[ -z "$k" ]] && { k="$x"; continue; }
+ out "$sep\"${k}\":"
+ out_value "$x"
+ sep=","
+ k=
+ done
+ out "}"
+ ;;
+ esac
+}
+
+function out_array() {
+ # expected stdin stream is:
+ # --------------
+ # value
+ # value
+ # ...
+ # --------------
+ local sep=""
+ case $format in
+ bash)
+ while read x; do
+ out "$sep"
+ out_value "$x"
+ sep=" "
+ done
+ ;;
+ json)
+ out "["
+ while read x; do
+ out $sep
+ out_value "$x"
+ sep=","
+ done
+ out "]"
+ ;;
+ esac
+}
+
+function out_value() {
+ # string
+ # number
+ # object
+ # array
+ # 'true'
+ # 'false'
+ # 'null'
+
+ x=$1
+
+ # litterals
+ if [[ "$x" =~ ^(true|false|null)$ ]]; then
+ out "$x"
+ # number
+ elif [[ "$x" =~ ^[+-]?[0-9]+(\.[0-9]+)?$ ]]; then
+ out "$x"
+ # object
+ elif [[ "$x" =~ ^\{.*\}$ ]]; then
+ out "$x"
+ # array
+ elif [[ "$x" =~ ^\[.*\]$ ]]; then
+ out "$x"
+ # string
+ else
+ out "\"$(sed 's/\("\)/\\\1/g' <<<$x)\""
+ fi
+}
+
+function out_comment() {
+ case $format in
+ bash)
+ [[ "$verbose" == 1 ]] && echo "# $@" || true
+ ;;
+ json)
+ ;;
+ esac
+}
+
function _getgitmanifest() {
# this function takes the setup.manifest generated by setup script and uses DIST_METADIR
# to analyze git repos
local manifest=$1 mode=$2
- [[ -f $manifest ]] && source $manifest || { echo "$BASH_SOURCE: Invalid setup manifest '$manifest'" >&2; return 1; }
+ [[ -f $manifest ]] && source $manifest || { error "Invalid setup manifest '$manifest'"; return 1; }
[[ ! -d "$DIST_METADIR" ]] && {
- echo "$BASH_SOURCE: Invalid meta directory. Check variable DIST_METADIR in manifest file '$manifest'." >&2
- echo "$BASH_SOURCE: Also, check directory '$DIST_METADIR'." >&2
+ error "Invalid meta directory. Check variable DIST_METADIR in manifest file '$manifest'."
+ error "$BASH_SOURCE: Also, check directory '$DIST_METADIR'."
return 2
}
local GIT=$(which git) REALPATH=$(which realpath)
- [[ ! -x $GIT ]] && { echo "$BASH_SOURCE: Unable to find git command in $PATH." >&2; return 3; }
- [[ ! -x $REALPATH ]] && { echo "$BASH_SOURCE: Unable to find realpath command in $PATH." >&2; return 4; }
+ [[ ! -x $GIT ]] && { error "$BASH_SOURCE: Unable to find git command in $PATH."; return 3; }
+ [[ ! -x $REALPATH ]] && { error "$BASH_SOURCE: Unable to find realpath command in $PATH."; return 4; }
local gitrepo gitrev metagitdir sep=""
DIST_LAYERS=""
@@ -58,6 +170,18 @@ function _getgitmanifest() {
# layers checksum
DIST_LAYERS_MD5=$(echo $DIST_LAYERS|md5sum -|awk '{print $1;}')
+ # in json, transform layers in an object, features in array
+ [[ "$format" == "json" ]] && {
+ DIST_FEATURES=$(for x in $DIST_FEATURES; do
+ echo $x
+ done | out_array)
+ DIST_LAYERS=$(for x in $DIST_LAYERS; do
+ echo ${x%%:*}
+ echo ${x#*:}
+ done | out_object)
+ }
+
+
# compute build hash
DIST_BUILD_HASH="F${DIST_FEATURES_MD5:0:8}-L${DIST_LAYERS_MD5:0:8}"
DIST_BUILD_ID="${DIST_DISTRO_NAME}-${DIST_MACHINE}-F${DIST_FEATURES_MD5:0:8}-L${DIST_LAYERS_MD5:0:8}"
@@ -81,66 +205,99 @@ function _getgitmanifest() {
EXTRA_VARS[target]="DIST_LAYERS DIST_BUILD_HASH DIST_BUILD_ID"
EXTRA_VARS[sdk]="DIST_LAYERS DIST_BUILD_HASH DIST_BUILD_ID"
- echo "# setup variables in $mode mode"
- for x in ${SETUP_VARS[$mode]}; do
- echo "$x=\"${!x}\""
- done
- echo
+ # BITBAKE_VARS may be defined from external file to source (--source arg)
+ # this is used to dump extra vars from inside bitbake recipe
- echo "# set by $BASH_SOURCE"
- for x in ${EXTRA_VARS[$mode]}; do
- echo "$x=\"${!x}\""
- done
+ { for x in ${SETUP_VARS[$mode]} ${EXTRA_VARS[$mode]} ${BITBAKE_VARS[$mode]}; do
+ k=$x
+ [[ "$format" == "json" ]] && {
+ k=${k#DIST_} # remove prefix
+ k=${k,,*} # to lower case
+ }
+ echo $k
+ echo ${!x}
+ done } | out_object
}
function getmanifest() {
local rc=0
- echo "# DISTRO BUILD MANIFEST"
- echo
+ out_comment "DISTRO BUILD MANIFEST"
+ out_comment
# add layers manifest
- echo "# ----- this fragment has been generated by $BASH_SOURCE"
+ out_comment "----- this fragment has been generated by $BASH_SOURCE"
_getgitmanifest $1 $2 || rc=$?
- echo "# ------------ end of $BASH_SOURCE fragment --------"
+ out_comment "------------ end of $BASH_SOURCE fragment --------"
return $rc
}
+function __usage() {
+ cat <<EOF >&2
+Usage: $BASH_SOURCE [-v|--verbose] [-f|--format <fmt>] [-m|--mode <mode>] [-s|--source <file>] <setup_manifest_file>
+ Options:
+ -v|--verbose: generate comments in the output file
+ -s|--source: extra file to source (get extra variables generated from bitbake recipe)
+ -f|--format: specify output format: 'bash' or 'json'
+ -m|--mode: specify the destination for the generated manifest
+ 'deploy' : for the tmp/deploy/images/* directories
+ 'target' : for the manifest to be installed inside a target image
+ 'sdk' : for the manifest to be installed inside the SDK
+
+ <setup_manifest_file> is the input manifest generated from setup script
+EOF
+}
+
set -e
-verbose=0
-if [[ "$1" =~ ^(-v|--verbose)$ ]]; then
- shift
- verbose=1
-fi
-
-if [[ -f "$1" ]]; then
- manifest=$1
- shift
-
- # default mode
- mode=${1:-deploy}
- case $mode in
- deploy|target|sdk) mode=$mode;;
- *) echo "Invalid mode specified. Allow modes are: deploy target sdk"; exit 42;;
+tmp=$(getopt -o h,v,m:,f:,s: --long help,verbose,mode:,format:,source: -n "$BASH_SOURCE" -- "$@") || {
+ error "Invalid arguments."
+ __usage
+ exit 1
+}
+eval set -- $tmp
+
+while true; do
+ case "$1" in
+ -h|--help) __usage; exit 0;;
+ -v|--verbose) verbose=1; shift ;;
+ -f|--format) format=$2; shift 2;;
+ -m|--mode) mode=$2; shift 2;;
+ -s|--source) sourcefile=$2; shift 2;;
+ --) shift; break;;
+ *) fatal "Internal error";;
esac
+done
- getmanifest $manifest $mode | { [[ $verbose == 1 ]] && cat || sed -e 's/#.*$//g;/^\s*$/d'; }
- exit ${PIPESTATUS[0]}
-else
- cat <<EOF >&2
-Usage: $0 [-v|--verbose] <setup_manifest_file> [mode]
- Options:
- -v|--verbose: generate comments in the output file
+manifest=$1
+shift
+[[ ! -f "$manifest" ]] && { __usage; exit 1; }
- <setup_manifest_file> is generated from setup script in the specified build dir
+case $mode in
+ deploy|target|sdk) ;;
+ *) error "Invalid mode specified. Allowed modes are: 'deploy', 'target', 'sdk'"; __usage; exit 42;;
+esac
- [mode] specifies the destination for the generated manifest
- Accepted values:
- 'deploy' : for the tmp/deploy/images/* directories
- 'target' : for the manifest to be installed inside a target image
- 'sdk' : for the manifest to be installed inside the SDK
-EOF
- exit 56
-fi
+case $format in
+ bash|json) ;;
+ *) error "Invalid format specified. Allowed formats are 'json' or 'bash'"; __usage; exit 43;;
+esac
+
+info "Generating manifest: mode=$mode format=$format manifest=$manifest"
+[[ -f "$sourcefile" ]] && {
+ info "Sourcing file $sourcefile"
+ . $sourcefile
+ # this may define extra vars: to be taken into account BITBAKE_VARS must be defined
+}
+
+[[ "$format" == "json" ]] && {
+ # if jq is present, use it to format json output
+ jq=$(which jq || true)
+ [[ -n "$jq" ]] && {
+ getmanifest $manifest $mode | $jq ""
+ exit ${PIPESTATUS[0]}
+ }
+}
+
+getmanifest $manifest $mode