From bfe1b6e9a1655ec62cfb4c0405b67fec8f493c4c Mon Sep 17 00:00:00 2001
From: Andrei Stepanov <astepano@redhat.com>
Date: Sep 20 2018 13:35:37 +0000
Subject: Add get-test-deps (resolve-test-dependencies) script


Signed-off-by: Andrei Stepanov <astepano@redhat.com>

---

diff --git a/beakerlib-libraries.spec b/beakerlib-libraries.spec
index ba80235..70dd3a1 100644
--- a/beakerlib-libraries.spec
+++ b/beakerlib-libraries.spec
@@ -29,12 +29,15 @@ Beakerlib Libraries are used by beakerlib tests to encapsulate common complex ta
 %build
 
 %install
-rm -rf %{buildroot}
-mkdir -p %{buildroot}%{libraries_path}
-cp -rf * %{buildroot}%{libraries_path}
+find . -maxdepth 2 -mindepth 2 '(' -path './bin/*' -o -path './.git*' ')' -prune -o -type d \
+    -exec sh -c 'install -v -d $RPM_BUILD_ROOT%libraries_path/$(dirname "{}")/Library' ';' \
+    -exec sh -c 'cp -v -a "{}" $RPM_BUILD_ROOT%libraries_path/$(dirname "{}")/Library'  ';'
+install -d "$RPM_BUILD_ROOT/%_bindir"
+install -m755 "bin/get-test-deps" "$RPM_BUILD_ROOT/%_bindir"
 
 %clean
 rm -rf $RPM_BUILD_ROOT
 
 %files
-%{libraries_path}
+%libraries_path
+%_bindir/get-test-deps
diff --git a/bin/get-test-deps b/bin/get-test-deps
new file mode 100755
index 0000000..c211d47
--- /dev/null
+++ b/bin/get-test-deps
@@ -0,0 +1,194 @@
+#!/bin/bash
+#
+# DESCRIPTION
+# -----------
+# This script resolves dependencies of the given beakerlib libraries installed
+# in BEAKER_LIBRARY_PATH. Dependencies are resolved from Makefiles which
+# contains Requires and RhtsRequires fields specifying RPM dependencies.
+#
+# RhtsRequires are mandatory RPM requirements that need to be installed before
+# running the test.
+#
+# Requires are optional RPM requirements that the harness should try to install
+# on the system-under-test (SUT), but they are not mandatory.
+#
+# RETURNS
+# -------
+# After the script finishes, it prints two lines, with space delimited list of
+# components from RhtsRequires and Requires.
+#
+# BEAKERLIB_LIBRARY_PATH - path with the libraries
+#
+# AUTHORS
+# -------
+#  Jakub Heger <jheger@redhat.com>
+#  Martin Kyral <mkyral@redhat.com>
+#  Miroslav Vadkerti <mvadkert@redhat.com>
+#  Andrei Stepanov <astepano@redhat.com>
+#
+
+PROG="${PROG:-${0##*/}}"
+[ -z "$BEAKERLIB_LIBRARY_PATH" ] && BEAKERLIB_LIBRARY_PATH="/mnt/libraries"
+
+function print_info() {
+    printf ":: %s\n" "$@"
+}
+
+function print_error() {
+    printf "Error: %s\n" "$@"
+}
+
+function exit_error() {
+    print_error "$@"
+    exit 1
+}
+
+function help() {
+cat <<EOF
+    usage: $PROG [-ih] TEST_PATH
+
+    Output 2 lines, each of them is list of RPMS:
+
+        RhtsRequires -- hard requirements
+        Requires -- soft requirements
+
+    Options:
+      -i         Install requirements.
+      -h         Print this help.
+
+    Notes:
+      This script will fail if not able to install package from RhtsRequires.
+
+EOF
+}
+
+
+# ENTER
+
+OPTS="hi"
+DO_INSTALL=
+while getopts $OPTS OPTION
+do
+  case $OPTION in
+    i)
+       DO_INSTALL=yes
+       shift
+       ;;
+    h)
+       help
+       exit
+       ;;
+  esac
+done
+
+TEST="$1"
+[ -z "$TEST" ] && exit_error "No test specified"
+[ -f "$TEST/Makefile" ] || exit 0
+
+REQUIRES_DEPS=
+RHTSREQUIRES_DEPS=
+PROCESSED_LIBS=
+
+#
+# Process a beakerlib library and recursively resolve it's dependencies.
+#
+# Params:
+# $1 - library name - e.g. httpd/http
+#
+function process_library() {
+  # skip already processed beakerlib libraries
+  grep -wq "$1" <<< "$PROCESSED_LIBS" && return
+  PROCESSED_LIBS="$PROCESSED_LIBS $1"
+
+  local COMPONENT=${1///*}
+  local LIBRARY=${1##*/}
+
+  # check if library exists
+  libdir=
+  if [ -d "${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/Library/$LIBRARY" ]; then
+    libdir="${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/Library/$LIBRARY"
+  elif [ -d "${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/$LIBRARY" ]; then
+    libdir="${BEAKERLIB_LIBRARY_PATH}/$COMPONENT/$LIBRARY"
+  else
+    print_error "Could not find library '$1' in '$BEAKERLIB_LIBRARY_PATH'"
+    return
+  fi
+
+  resolve_deps "$libdir"
+}
+
+#
+# Recursively resolves test dependencies of beakerlib test specified with a path.
+#
+# Params:
+# $1 - path to a beakerlib test
+#
+function resolve_deps() {
+  local REQUIRES=$(sed -n 's/^[^#]*\"Requires:[[:space:]]*\(.*\)".*/\1/Ip' "$1/Makefile")
+  local RHTSREQUIRES=$(sed -n 's/^[^#]*RhtsRequires:[[:space:]]*\(.*\)".*/\1/Ip' "$1/Makefile")
+
+  for REQ in $REQUIRES; do
+    if egrep -qv '^\$\(' <<< "$REQ"; then
+      REQUIRES_DEPS="$REQUIRES_DEPS $REQ"
+    fi
+  done
+
+  for RHTSREQ in $RHTSREQUIRES; do
+    if egrep -q "^library\(" <<< "$RHTSREQ"; then
+      process_library $(sed 's/library(\(.*\))/\1/' <<< "$RHTSREQ")
+    elif egrep -qv '^\$\(' <<< "$RHTSREQ"; then
+      RHTSREQUIRES_DEPS="$RHTSREQUIRES_DEPS $RHTSREQ"
+    fi
+  done
+}
+
+resolve_deps "$TEST"
+
+RHTSREQUIRES_DEPS="$(echo "$RHTSREQUIRES_DEPS" | xargs -n1 | sort | uniq | tr '\n' ' ')"
+REQUIRES_DEPS="$(echo "$REQUIRES_DEPS" | xargs -n1 | sort | uniq | tr '\n' ' ')"
+
+echo "$RHTSREQUIRES_DEPS"
+echo "$REQUIRES_DEPS"
+
+if [ -z "$DO_INSTALL" ]; then
+  exit
+fi
+
+YUM=
+if [ -x "/usr/bin/yum" ]; then
+  YUM=yum
+elif [ -x "/usr/bin/dnf" ]; then
+  YUM=dnf
+fi
+
+if [ -n "$YUM" ]; then
+  # Hard req
+  if [ -n "${RHTSREQUIRES_DEPS## }" ]; then
+    $YUM install -y $RHTSREQUIRES_DEPS || exit 1
+  fi
+
+  # Soft req
+  if [ -n "${REQUIRES_DEPS## }" ]; then
+    $YUM install -y --skip-broken $REQUIRES_DEPS || :
+  fi
+elif [ -x "/usr/bin/rpm-ostree" ]; then
+  # Hard req
+  if [ -n "${RHTSREQUIRES_DEPS## }" ]; then
+    rpm-ostree install -y $RHTSREQUIRES_DEPS || exit 1
+  fi
+
+  # Soft req
+  if [ -n "${REQUIRES_DEPS## }" ]; then
+    rpm-ostree install -y $REQUIRES_DEPS || :
+  fi
+
+  # Apply changes
+  if [ -n "${RHTSREQUIRES_DEPS## }${REQUIRES_DEPS## }" ]; then
+    rpm-ostree ex livefs
+  fi
+else
+  echo "Cannot guess package manager."
+  exit 1
+fi
+
+# vim: ts=2 sw=2 sts=2 ft=sh et ai:

