#!/bin/sh usage () { echo Usage: `basename $0` '[-h|-u] [-r ref] [--] command...'; } # Copyright (C) 2016 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only help () { usage # Example data: [ "$LAST" ] || LAST=v5.9.0 [ "$NEXT" ] || NEXT=5.10 [ "$TASK" ] || TASK=QTBUG-5678 ME=`basename $0` cat <&2; } die () { warn "$@"; exit 1; } banner () { echo; echo "====== $@ ======"; echo; } # Convert each .gitmodules stanza into a single line: modules () { sed -e 's/^\[submodule/\v[submodule/' <.gitmodules | tr '\n\v' '\f\n' echo } # Parse a single linearised stanza; discard if boring (or, when INVERT # is set, if interesting), else extract its directory name: INVERT= vetcheck () { # Can't return from within the while loop; piping input to it has # made it a sub-shell. (That also precludes assigning any # variables within the loop; values would be forgotten after.) echo "$@" | tr '\f' '\n' | while read name op value do [ "$op" = '=' ] || continue case "$name" in status) # No BC/SC promises in preview; and we # don't care about obsolete or ignore: case "$value" in essential|addon|deprecated) [ -z "$INVERT" ] || echo no ;; preview|obsolete|ignore) [ -n "$INVERT" ] || echo no ;; *) warn "Unrecognized module status: $value (treated as active)" [ -z "$INVERT" ] || echo no ;; esac;; # repotools has qt = false qt) [ "$value" = false ] && echo no ;; # non-versioned modules aren't relevant to us: branch) [ "$value" = master ] && echo no ;; esac done } vet () { # First pass: filter out modules we don't want: if vetcheck "$@" | grep -q no then return fi echo "$@" | grep -w 'status *= *' | \ tr '\f' '\n' | grep 'path *=' | cut -d = -f 2 } # Re-echo a module if it has all required refs: checkrefs () { for ref in $REFS # Use rev-parse --verify to test whether $ref exists in this repo: do (cd "$1" && git rev-parse -q --verify "$ref^{commit}" >/dev/null 2>&1) || return done echo "$1" } # List the API-relevant modules: relevant () { # Select released Qt modules: modules | while read stanza do vet "$stanza" done | while read path # Only those with src/ and a CMakeLists.txt matter: do if [ -d "$path/src" -a -f "$path/CMakeLists.txt" ] # Filter on the desired refs (if any): then checkrefs "$path" fi done } REFS= while [ $# -gt 0 ] do case "$1" in -u|--usage) usage; exit 0;; -h|--help) help; exit 0;; -i|--ignored) INVERT=yes; shift;; -r|--require) REFS="$REFS $2"; shift 2;; --) shift; break;; -*) usage >&2; die "Unrecognised option: $1";; *) break;; esac done [ -e .gitmodules ] || die "I must be run in the top-level (qt5) directory" if [ $# -eq 0 ] then usage >&2 die "You need to supply a command to run in each module !" fi relevant | while read dir do (cd "$dir" && banner "$dir" && eval "$@") || warn "Failed ($?) in $dir: $@" done