diff options
author | Stephane Desneux <stephane.desneux@iot.bzh> | 2018-11-21 22:04:28 +0000 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2018-11-23 19:18:02 +0000 |
commit | 7d027fc6280a9ffe234736a38c8aed32243a4dd6 (patch) | |
tree | f5b933afc9649f69bea86650873fd48350ab2fc8 /scripts | |
parent | 0998dd12e5d6e4cf5471b97fe2150b56303358ac (diff) |
distro-manifest-generator: add support for JSON output formatguppy_6.99.1guppy/6.99.16.99.1
Distro build manifest is easier to parse if output is made in a structured
format. Adding JSON output format will allow bindings to read information
more easily.
The files created are now:
On target:
* /etc/platform-info/build (shell format)
* /etc/platform-info/build.json (JSON format)
In image deploy dir (.../tmp/deploy/images/$MACHINE/):
* build-info (shell format)
* build-info.json (JSON format)
In sdk deploy dir (.../tmp/deploy/sdk/):
* poky-agl-<version details>.build-info (shell format)
* poky-agl-<version details>.build-info.json (JSON format)
Bug-AGL: SPEC-720, SPEC-1917
Change-Id: If45d2c5dd96b15ce790aa7f7f97c24f119ad117b
Signed-off-by: Stephane Desneux <stephane.desneux@iot.bzh>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/distro-manifest-generator.sh | 255 |
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 |