#!/usr/bin/env bash # # sage-spkg: install a Sage package # # This script is typically invoked by giving the command # sage {-i|-p} <options> <package name>... # # sage-spkg itself only accepts one <package name>. # # sage-spkg <options> <package name> [<installation tree>] # # Options: see usage() below. # # A package may assume that the following environment # variables are defined: # # SAGE_ROOT -- root directory of sage distribution # SAGE_LOCAL -- prefix where packages are installed (usually $SAGE_ROOT/local) # SAGE_INST_LOCAL-- prefix where to install this package; # this is set by the optional argument <installation tree> # and defaults to $SAGE_LOCAL. # SAGE_DISTFILES -- directory that stores upstream tarballs # SAGE_DESTDIR -- temporary root the package will be installed to # PKG_BASE -- the base name of the package itself (e.g. 'patch') # PKG_VER -- the version number of the package # PKG_NAME -- $PKG_BASE-$PKG_VER # LIBRARY_PATH, PYTHONPATH, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH # CC, CXX, CFLAGS, CXXFLAGS, LDFLAGS, MAKE # # Your package script should try to build using the giving CC, CXX, # CFLAGS, MAKE, etc, via a file spkg-install in your script. # # This script does the following: # # 1. Set environment variables (by calling sage-env) # 2. Extract the metadata and upstream sources into a build directory # 3. Run the script in the package called spkg-install # 4. Return error 1 if anything goes wrong. # # AUTHORS: # # - Robert Bradshaw, R. Andrew Ohana (2013): #14480: extend functionality to # support the unified git repository. # # - Jeroen Demeyer (2012-02-27): #12602: refactor code to find packages, # download them and extract them. # # - Jeroen Demeyer (2012-02-27): #12479: big reorganization. # # - Volker Braun, Jeroen Demeyer (2012-01-18): #11073: remove the # spkg/base repository, move this file from local/bin/sage-spkg to # spkg/bin/sage-spkg. # # - William Stein, John Palmieri and others (Sage 4.8 and earlier). # #***************************************************************************** # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** # Avoid surprises with character ranges [a-z] in regular expressions # See Issue #15791; some locales can produce different results for # character ranges; using C.UTF-8 to ensure UTF-8 default encoding in Python # introduces extra complications, see #30053, so we don't do it, but # assume we are on Python3.x, for x at least 7. export LC_ALL=C usage() { cat <<EOF Usage: sage {-i|-p} <options> <package name> Search Sage's list of packages (see 'sage --package list') for a matching package, and if a match is found, install it. Modes of operation (provide at most one): -d, --download-only: only download the package -b, --build-and-stage-only: build and install (stage) only, do not run post-install or check -p, --post-install-only: unload the staged installation directory and run other post-installation steps only -x, --check-only: exclusively run the test suite; this may assume that: * the package has been installed already and/or that * the build directory has not been deleted -e, --erase-build-directory-only: erase (delete) the build directory only --info: print information on the package only --help: print this help only Other options: -y: automatically reply "y" for all prompts regarding experimental and old-style packages; warning: there is no guarantee that these packages will build correctly; use at your own risk -n: automatically reply "n" for all prompts regarding experimental and old-style packages -o: allow fetching the package from its upstream URL when it is not available from the Sage mirrors (yet) -c: after installing, run the test suite for the package; exit with an error on test suite failures -w: after installing, run the test suite for the package; print a warning on test suite failures -s: save (do not delete) the build directory, even when the installation was successful EOF } # error_msg(header, command) # This is for printing an error message if something went wrong. # The first argument is the header to print. If given, the second # argument should be some proposed command to run in the subshell # such as "make". error_msg() { cat >&2 <<MESSAGE ************************************************************************ $1 ************************************************************************ Please email sage-devel (http://groups.google.com/group/sage-devel) explaining the problem and including the log files $SAGE_LOGS/$PKG_NAME.log and $SAGE_ROOT/config.log Describe your computer, operating system, etc. MESSAGE if [ -n "$2" ]; then cat >&2 <<MESSAGE If you want to try to fix the problem yourself, *don't* just cd to `pwd` and type '$2' or whatever is appropriate. Instead, the following commands setup all environment variables correctly and load a subshell for you to debug the error: (cd '`pwd`' && '$SAGE_ROOT/sage' --buildsh) When you are done debugging, you can type "exit" to leave the subshell. MESSAGE fi cat >&2 <<MESSAGE ************************************************************************ MESSAGE } exit_with_error_msg() { error_msg "$@" exit 1 } # Handle -n, -t, -q options for recursive make # See Issue #12016. if echo "$MAKE $MAKEFLAGS -$MAKEFLAGS" |grep '[ ]-[A-Za-z]*[qnt]' >/dev/null; then if echo "$MAKE $MAKEFLAGS -$MAKEFLAGS" |grep '[ ]-[A-Za-z]*q' >/dev/null; then # Pretend the target is *not* up-to-date exit 1 else exit 0 fi fi if [ $# -eq 0 ]; then usage exit 0 fi ################################################################## # Set environment variables ################################################################## # The following sets environment variables for building packages. # Since this is sourced, it returns a non-zero value on errors rather # than exiting. Using dot suggested by W. Cheung. . sage-env-config . sage-env || exit_with_error_msg "Error setting environment variables by sourcing sage-env" . sage-build-env-config . sage-build-env || exit_with_error_msg "Error setting environment variables by sourcing sage-build-env" # Remove '.' from PYTHONPATH, to avoid trouble with setuptools / easy_install # (cf. #10192, #10176): if [ -n "$PYTHONPATH" ]; then # We also collapse multiple slashs into a single one (first substitution), # remove leading './'s and trailing '/.'s (second and third), and # remove leading, trailing and redundant ':'s (last three substitutions): new_pp=`echo ":$PYTHONPATH:" \ | sed \ -e 's|//*|/|g' \ -e 's|:\(\./\)\{1,\}|:|g' \ -e 's|\(/\.\)\{1,\}:|:|g' \ -e 's|\(:\.\)\{1,\}:|:|g' \ -e 's|::*|:|g' -e 's|^::*||' -e 's|::*$||'` if [ "$PYTHONPATH" != "$new_pp" ]; then echo "Cleaning up PYTHONPATH:" echo " Old: \"$PYTHONPATH\"" echo " New: \"$new_pp\"" PYTHONPATH=$new_pp export PYTHONPATH # maybe redundant, but in any case safe fi fi ################################################################## # Handle special command-line options ################################################################## # Parse options INFO=0 YES=0 KEEP_EXISTING=0 INSTALL=1 POST_INSTALL=1 ERASE_ONLY=0 MODE_SWITCHES= while true; do case "$1" in --info) MODE_SWITCHES+=", $1" INFO=1;; --help) usage exit 0;; -y) YES=1;; -n) YES=-1;; -d|--download-only) MODE_SWITCHES+=", $1" SAGE_INSTALL_FETCH_ONLY=1;; -s) export SAGE_KEEP_BUILT_SPKGS=yes;; -c|--check) export SAGE_CHECK=yes;; -w|--check-warning-only) export SAGE_CHECK=warn;; -b|--build-and-stage-only) MODE_SWITCHES+=", $1" POST_INSTALL=0; export SAGE_CHECK=no;; -p|--post-install-only) MODE_SWITCHES+=", $1" INSTALL=0; export SAGE_CHECK=no;; -x|--check-only) MODE_SWITCHES+=", $1" INSTALL=0; POST_INSTALL=0; export SAGE_CHECK=yes;; -k|--keep-existing) KEEP_EXISTING=yes;; -e|--erase-build-directory-only) MODE_SWITCHES+=", $1" ERASE_ONLY=1;; -o|--allow-upstream) SAGE_DOWNLOAD_FILE_OPTIONS+=" --allow-upstream";; -*) echo >&2 "Error: unknown option '$1'" exit 2;; *) break;; esac shift done MODE_SWITCHES=${MODE_SWITCHES#, } case "$MODE_SWITCHES" in *,*) echo >&2 "Error: at most one of the mode switches may be given, got $MODE_SWITCHES" echo >&2 usage exit 1 ;; esac # One should be able to install a package using # sage -i <package-name> PKG_SRC="$1" # Does PKG_SRC contain a slash? if echo "$PKG_SRC" | grep / >/dev/null; then echo >&2 "Error: Installing old-style SPKGs is no longer supported" exit 1 fi PKG_NAME="$PKG_SRC" export PKG_BASE=`echo "$PKG_NAME" | sed 's/-.*//'` # strip version number case $# in 1) SAGE_INST_LOCAL="$SAGE_LOCAL" ;; 2) SAGE_INST_LOCAL="$2" ;; *) usage exit 1 ;; esac export SAGE_INST_LOCAL if [ -z "$SAGE_BUILD_DIR" ]; then export SAGE_BUILD_DIR="$SAGE_INST_LOCAL/var/tmp/sage/build" fi export SAGE_SPKG_INST="$SAGE_INST_LOCAL/var/lib/sage/installed" export SAGE_SPKG_SCRIPTS="$SAGE_INST_LOCAL/var/lib/sage/scripts" export SAGE_SPKG_WHEELS="$SAGE_INST_LOCAL/var/lib/sage/wheels" # PKG_SRC should look like "package-VERSION" or just "package". # VERSION, if provided, must match the version in build/pkgs. PKG_VER="${PKG_NAME#${PKG_BASE}}" export PKG_VER="${PKG_VER#-}" eval $(sage-package properties --format=shell $PKG_BASE) eval PKG_SCRIPTS=\$path_$PKG_BASE \ PKG_TYPE=\$type_$PKG_BASE \ PKG_SRC_TYPE=\$source_$PKG_BASE \ LOCAL_PKG_VER=\$version_with_patchlevel_$PKG_BASE if [ -n "$PKG_VER" -a "$PKG_VER" != "$LOCAL_PKG_VER" ]; then echo >&2 "Error: Selecting a different version of a package is no longer supported" exit 1 fi if [ -z "$PKG_VER" ]; then export PKG_NAME="${PKG_BASE}" else export PKG_NAME="${PKG_BASE}-${PKG_VER}" fi # Set the $SAGE_DESTDIR variable to be passed to the spkg-install # script (the script itself could set this, but better to standardize # this in one place) export SAGE_DESTDIR="${SAGE_BUILD_DIR}/${PKG_NAME}/inst" # The actual prefix where the installation will be staged. This is the # directory that you need to work in if you want to change the staged # installation tree (before final installation to $SAGE_INST_LOCAL) at the # end of spkg-install. export SAGE_DESTDIR_LOCAL="${SAGE_DESTDIR}${SAGE_INST_LOCAL}" INSTALLED_SCRIPTS_DEST="$SAGE_SPKG_SCRIPTS/$PKG_BASE" INSTALLED_SCRIPTS="prerm piprm postrm check" WRAPPED_SCRIPTS="build install preinst pipinst postinst $INSTALLED_SCRIPTS" warning_for_experimental_packages() { ############################ case "$PKG_TYPE:$PKG_SRC_TYPE" in experimental:normal|experimental:wheel) if [ $YES != 1 ]; then echo "Error: The package $PKG_NAME is marked as experimental." echo "Use 'sage -i -y $PKG_BASE' to force installation of this package" echo "or use the configure option --enable-experimental-packages" exit 1 fi;; esac } ############################## warning_for_experimental_packages ensure_pkg_src() { ############################################### case "$PKG_SRC_TYPE" in normal|wheel) PKG_SRC=$(sage-package download $SAGE_DOWNLOAD_FILE_OPTIONS $PKG_BASE) || exit_with_error_msg "Error downloading tarball of $PKG_BASE" # Do a final check that PKG_SRC is a file with an absolute path cd / if [ ! -f "$PKG_SRC" ]; then echo >&2 "Error: spkg file '$PKG_SRC' not found." echo >&2 "This shouldn't happen, it is a bug in the sage-spkg script." exit 1 fi # Go back to SAGE_ROOT where we have less chance of completely messing # up the system if we do something wrong. cd "$SAGE_ROOT" || exit $? # If SAGE_SPKG_COPY_UPSTREAM is set, it should be the name of a directory # to which all upstream files are copied. This is used in sage-sdist. if [ -n "$SAGE_SPKG_COPY_UPSTREAM" ]; then mkdir -p "$SAGE_SPKG_COPY_UPSTREAM" && cp -p "$PKG_SRC" "$SAGE_SPKG_COPY_UPSTREAM" if [ $? -ne 0 ]; then error_msg "Error copying upstream tarball to directory '$SAGE_SPKG_COPY_UPSTREAM'" exit 1 fi fi ;; none) echo >&2 echo >&2 "Note: $PKG_BASE is a dummy package that the Sage distribution uses" echo >&2 "to provide information about equivalent system packages." echo >&2 "It cannot be installed using the Sage distribution." echo >&2 "Please install it manually, for example using the system packages" echo >&2 "recommended at the end of a run of './configure'" echo >&2 "See below for package-specific information." echo >&2 sage-spkg-info $PKG_BASE echo >&2 echo >&2 "Error: $PKG_BASE is a dummy package and " echo >&2 "cannot be installed using the Sage distribution." exit 1 ;; esac } ################################################# ensure_pkg_src setup_directories() { ############################################ for dir in "$SAGE_SPKG_INST" "$SAGE_SPKG_SCRIPTS" "$SAGE_BUILD_DIR"; do mkdir -p "$dir" || exit_with_error_msg "Error creating directory $dir" done # Issue #5852: check write permissions if [ ! -w "$SAGE_BUILD_DIR" ]; then exit_with_error_msg "Error: no write access to build directory $SAGE_BUILD_DIR" fi if [ ! -d "$SAGE_INST_LOCAL" ]; then # If you just unpack Sage and run "sage -p <pkg>" then local does not yet exist mkdir "$SAGE_INST_LOCAL" fi if [ ! -w "$SAGE_INST_LOCAL" ]; then exit_with_error_msg "Error: no write access to installation directory $SAGE_INST_LOCAL" fi # Make absolutely sure that we are in the build directory before doing # a scary "rm -rf" below. cd "$SAGE_BUILD_DIR" || exit $? if [ "x$SAGE_KEEP_BUILT_SPKGS" != "xyes" ]; then rm -rf "$PKG_NAME" else if [ -e "$PKG_NAME" ]; then echo "Moving old directory $PKG_NAME to $SAGE_BUILD_DIR/old..." mkdir -p old || exit_with_error_msg "Error creating directory $SAGE_BUILD_DIR/old" rm -rf old/"$PKG_NAME" mv "$PKG_NAME" old/ fi fi if [ -e "$PKG_NAME" ]; then exit_with_error_msg "Error (re)moving $PKG_NAME" fi } ############################################## setup_directories extract_the_package() { ########################################## cd "$SAGE_BUILD_DIR" || exit $? echo "Setting up build directory $SAGE_BUILD_DIR/$PKG_NAME" case "$PKG_SRC_TYPE" in script) # Transplant the 'src' symlink, copy scripts. mkdir -p "$PKG_NAME" if [ -d "$PKG_SCRIPTS"/src ]; then ln -s $(cd "$PKG_SCRIPTS"/src && pwd -P) "$PKG_NAME"/src fi for a in $WRAPPED_SCRIPTS; do if [ -r "$PKG_SCRIPTS"/spkg-$a.in ]; then cp "$PKG_SCRIPTS"/spkg-$a.in "$PKG_NAME"/ elif [ -x "$PKG_SCRIPTS"/spkg-$a ]; then cp "$PKG_SCRIPTS"/spkg-$a "$PKG_NAME"/ fi done cd "$PKG_NAME" || exit $? ;; normal|wheel) # Copy whole directory, resolving symlinks cp -RLp "$PKG_SCRIPTS" "$PKG_NAME" cd "$PKG_NAME" || exit $? case "$PKG_SRC" in *.whl) # (Platform-independent) wheel # Do not extract, do not create a src directory, # just copy to dist/ and create a simple install script. mkdir -p dist cp "$PKG_SRC" dist/ if [ ! -f spkg-install.in ]; then echo "sdh_store_and_pip_install_wheel ." > spkg-install.in fi ;; *) # Source tarball sage-uncompress-spkg -d src "$PKG_SRC" || exit_with_error_msg "Error: failed to extract $PKG_SRC" cd src sage-apply-patches || exit_with_error_msg "Error applying patches" cd .. ;; esac ;; *) error_msg "Unhandled source type $PKG_SRC_TYPE" ;; esac if [ "$SAGE_KEEP_BUILT_SPKGS" = "yes" ]; then touch .keep fi } ############################################ extract_the_package # The package has been extracted, prepare_for_installation() { ##################################### # Rewrites the given bash pseudo-script with a boilerplate header that includes # the shebang line and sourcing sage-env. Make sure the name of the script is # passed in as an absolute path. write_script_wrapper() { local script="$1" local script_dir="$2" local fallback_script_dir="$3" trap "echo >&2 Error: Unexpected error writing wrapper script for $script; exit \$_" ERR if head -1 "$script.in" | grep '^#!.*$' >/dev/null; then echo >&2 "Error: ${script##*/} should not contain a shebang line; it will be prepended automatically." exit 1 fi local tmpscript="$(dirname "$script")/.tmp-${script##*/}" cat > "$tmpscript" <<__EOF__ #!/usr/bin/env bash export SAGE_ROOT="$SAGE_ROOT" export SAGE_SRC="$SAGE_SRC" export SAGE_PKG_DIR="$script_dir" export SAGE_SPKG_SCRIPTS="$SAGE_SPKG_SCRIPTS" export SAGE_SPKG_WHEELS="$SAGE_SPKG_WHEELS" export PKG_NAME="$PKG_NAME" export PKG_BASE="$PKG_BASE" export PKG_VER="$PKG_VER" for lib in "\$SAGE_ROOT/build/bin/sage-dist-helpers" "\$SAGE_SRC/bin/sage-src-env-config" "\$SAGE_SRC/bin/sage-env-config" "\$SAGE_SRC/bin/sage-env" "\$SAGE_ROOT/build/bin/sage-build-env-config" "\$SAGE_ROOT/build/bin/sage-build-env"; do source "\$lib" if [ \$? -ne 0 ]; then echo >&2 "Error: failed to source \$lib" echo >&2 "Is \$SAGE_ROOT the correct SAGE_ROOT?" exit 1 fi done export SAGE_INST_LOCAL="$SAGE_INST_LOCAL" sdh_guard if [ \$? -ne 0 ]; then echo >&2 "Error: sdh_guard not found; Sage environment was not set up properly" exit 1 fi __EOF__ if [ -n "$fallback_script_dir" ]; then cat >> "$tmpscript" <<__EOF__ cd "\$SAGE_PKG_DIR" 2>/dev/null || cd "$fallback_script_dir" __EOF__ else cat >> "$tmpscript" <<__EOF__ cd "\$SAGE_PKG_DIR" if [ \$? -ne 0 ]; then echo >&2 "Error: could not cd to the package build directory \$SAGE_PKG_DIR" exit 1 fi __EOF__ fi cat "$script.in" >> "$tmpscript" mv "$tmpscript" "$script" chmod +x "$script" trap - ERR } # Prepare script for uninstallation of packages that use sdh_pip_install # or sdh_store_and_pip_install_wheel. touch spkg-piprm.in # Prepare script for deferred installation of packages that use sdh_pip_install # or sdh_store_and_pip_install_wheel. touch spkg-pipinst.in for script in $WRAPPED_SCRIPTS; do # 'Installed' scripts are not run immediately out of the package build # directory, and may be run later. # For the installed *rm scripts, set their root directory to $SAGE_ROOT. # For the installed check scripts, some need the temporary build directory, # others are OK with $PKG_SCRIPTS. So try to run out of the temporary # build directory but fall back to the latter. case $script in check) script_dir="$(pwd)" fallback_script_dir="$PKG_SCRIPTS" ;; *rm) script_dir="\$SAGE_ROOT" fallback_script_dir= ;; *) script_dir="$(pwd)" fallback_script_dir= ;; esac script="spkg-$script" if [ -f "$script.in" ]; then write_script_wrapper "$(pwd)/$script" "$script_dir" "$fallback_script_dir" fi done } ####################################### prepare_for_installation actually_build_and_install() { ################################### case "$PKG_SRC" in *.whl) # Silence is golden. ;; *) echo "Host system: $(uname -a)" echo "C compiler: $CC$($CC -v 2>&1 | while read -r line; do echo -n ", $line"; done)" ;; esac # Poison the proxy variable to forbid downloads in spkg-install # for normal/wheel standard packages case "$PKG_TYPE:$PKG_SRC_TYPE" in standard:normal|standard:wheel) export http_proxy=http://192.0.2.0:5187/ export https_proxy=$http_proxy export ftp_proxy=$http_proxy export rsync_proxy=$http_proxy ;; esac # Make sage-logger show the full logs unset SAGE_SILENT_BUILD unset V # First uninstall the previous version of this package, if any if [ "$KEEP_EXISTING" != "yes" ]; then sage-spkg-uninstall "$PKG_BASE" "$SAGE_INST_LOCAL" fi # To work around #26996: Create lib and set a symlink so that writes into lib64/ end up in lib/ (mkdir -p "$SAGE_DESTDIR_LOCAL/lib" && cd "$SAGE_DESTDIR_LOCAL" && ln -sf lib lib64) # Run the pre-install script, if any if [ -f spkg-preinst ]; then sage-logger -P spkg-preinst "$SAGE_SUDO ./spkg-preinst" || exit_with_error_msg "Error running the preinst script for $PKG_NAME." fi if [ -f spkg-build ]; then # Package has both spkg-build and spkg-install; execute the latter with SAGE_SUDO sage-logger -P spkg-build "./spkg-build" || exit_with_error_msg "Error building package $PKG_NAME" "make" sage-logger -P spkg-install "$SAGE_SUDO ./spkg-install" || exit_with_error_msg "Error installing package $PKG_NAME" "make" else # Package only has spkg-install sage-logger -P spkg-install "./spkg-install" || exit_with_error_msg "Error installing package $PKG_NAME" "make" fi } ##################################### actually_build_and_install unload_destdir() { ############################################### # To work around #26996: Remove the symlink set, # or we get "cp: cannot overwrite directory" rm -f "$SAGE_DESTDIR_LOCAL/lib64" # All spkgs should eventually support this, but fall back on old behavior in # case DESTDIR=$SAGE_DESTDIR installation was not used if [ -d "$SAGE_DESTDIR" ]; then echo "Moving package files from temporary location $SAGE_DESTDIR to $SAGE_INST_LOCAL" # Some `find` implementations will put superfluous slashes in the # output if we give them a directory name with a slash; so make sure # any trailing slash is removed; https://github.com/sagemath/sage/issues/26013 PREFIX="${SAGE_DESTDIR_LOCAL%/}" rm -f "$PREFIX"/lib/*.la || exit_with_error_msg "Error deleting unnecessary libtool archive files" # Generate installed file manifest FILE_LIST="$(cd "$PREFIX" && find . -type f -o -type l | sed 's|^\./||' | sort)" # Copy files into $SAGE_INST_LOCAL $SAGE_SUDO cp -Rp "$PREFIX/." "$SAGE_INST_LOCAL" || exit_with_error_msg "Error moving files for $PKG_NAME." # Remove the $SAGE_DESTDIR entirely once all files have been moved to their # final location. rm -rf "$SAGE_DESTDIR" else echo "The temporary location $SAGE_DESTDIR does not exist; has it been unloaded already?" exit 1 fi # At this stage the path in $SAGE_DESTDIR no longer exists, so the variable # should be unset unset SAGE_DESTDIR unset SAGE_DESTDIR_LOCAL } ################################################# unload_destdir install_scripts() { ############################################## # Some spkg scripts, if they exist, should also be installed to # $SAGE_SPKG_SCRIPTS; they are not included in the package's manifest, but are # removed by sage-spkg-uninstall if [ ! -f "$INSTALLED_SCRIPTS_DEST"/spkg-requirements.txt ]; then # No packages to uninstall with pip, so remove the prepared uninstall script # and the prepared deferred installation script rm -f spkg-piprm spkg-piprm.in spkg-pipinst spkg-pipinst.in fi for script in $INSTALLED_SCRIPTS; do script="spkg-$script" if [ -f "$script" ]; then mkdir -p "$INSTALLED_SCRIPTS_DEST" || exit_with_error_msg "Error creating the spkg scripts directory $INSTALLED_SCRIPTS_DEST." cp -a "$script" "$INSTALLED_SCRIPTS_DEST" || exit_with_error_msg "Error copying the $script script to $INSTALLED_SCRIPTS_DEST." fi done } ################################################ install_scripts post_install() { ################################################# # Run the post-install script, if any # But first complete the delayed installation of wheels. if [ -f spkg-pipinst ]; then sage-logger -P spkg-pipinst "$SAGE_SUDO ./spkg-pipinst" || exit_with_error_msg "Error running the pipinst script for $PKG_NAME." fi if [ -f spkg-postinst ]; then sage-logger -P spkg-postinst "$SAGE_SUDO ./spkg-postinst" || exit_with_error_msg "Error running the postinst script for $PKG_NAME." fi } ################################################### post_install run_test_suite() { ############################################### # Note: spkg-check tests are run after the package has been copied into # SAGE_INST_LOCAL. It might make more sense to run the tests before, but the # spkg-check scripts were written before use of DESTDIR installs, and so # fail in many cases. This might be good to change later. if ! cd "$SAGE_BUILD_DIR/$PKG_NAME" 2>/dev/null; then cd "$PKG_SCRIPTS" || exit $? fi if [ -f "$INSTALLED_SCRIPTS_DEST"/spkg-check ]; then echo "Running the test suite for $PKG_NAME..." export PKG_BASE sage-logger -P spkg-check "$INSTALLED_SCRIPTS_DEST"/spkg-check if [ $? -ne 0 ]; then TEST_SUITE_RESULT="failed" if [ "$SAGE_CHECK" = "warn" ]; then # The following warning message must be consistent # with SAGE_ROOT/build/make/install (see #32781) error_msg "Warning: Failures testing package $PKG_NAME (ignored)" "make check" else exit_with_error_msg "Error testing package $PKG_NAME" "make check" fi else TEST_SUITE_RESULT="passed" echo "Passed the test suite for $PKG_NAME." fi elif [ -f "$PKG_SCRIPTS"/spkg-check.in -o -f "$PKG_SCRIPTS"/spkg-check ]; then echo "The test suite for $PKG_NAME cannot be run because the script" echo "$INSTALLED_SCRIPTS_DEST/spkg-check" echo "is missing. Install/re-install package $PKG_NAME to run the test suite." exit 1 else echo "Package $PKG_NAME has no test suite." TEST_SUITE_RESULT="not available" fi } ################################################# run_test_suite write_installation_record() { #################################### # For each line in $FILE_LIST, enclose in double quotes: NEW_LIST="" for f in $FILE_LIST; do NEW_LIST+="\"$f\" " done # Now remove the last line (it's blank), indent each line (skipping # the first) and append a comma (skipping the last). FILE_LIST="$(echo "$NEW_LIST" | sed '$d' | sed '2,$s/^/ /; $!s/$/,/')" # Mark that the new package has been installed (and tested, if # applicable). PKG_NAME_INSTALLED="$SAGE_SPKG_INST/$PKG_NAME" cat > "$PKG_NAME_INSTALLED" << __EOF__ { "package_name": "$PKG_BASE", "package_version": "$PKG_VER", "install_date": "$(date)", "system_uname": "$(uname -a)", "sage_version": "$(cat "${SAGE_ROOT}/VERSION.txt")", "test_result": "$TEST_SUITE_RESULT", "files": [ $FILE_LIST ] } __EOF__ } ###################################### write_installation_record delete_the_temporary_build_directory() { ######################### echo "Deleting build directory $SAGE_BUILD_DIR/$PKG_NAME" # On Solaris, the current working directory cannot be deleted, # so we "cd" out of $SAGE_BUILD_DIR/$PKG_NAME. See #12637. cd "$SAGE_BUILD_DIR" rm -rf "$SAGE_BUILD_DIR/$PKG_NAME" } ########################### delete_the_temporary_build_directory delete_the_temporary_build_directory_if_required() { ############# if [ ! -e "$SAGE_BUILD_DIR/$PKG_NAME/.keep" ]; then delete_the_temporary_build_directory else echo "You can safely delete the build directory $SAGE_BUILD_DIR/$PKG_NAME" fi } ############### delete_the_temporary_build_directory_if_required ################################################################## # MAIN ################################################################## if [ $INFO -ne 0 ]; then exec sage-spkg-info $PKG_BASE fi if [ $ERASE_ONLY = 1 ]; then delete_the_temporary_build_directory exit 0 fi if [ $INSTALL = 1 ]; then warning_for_experimental_packages ensure_pkg_src fi if [ -n "$SAGE_INSTALL_FETCH_ONLY" ]; then exit 0 fi if [ $INSTALL = 1 ]; then setup_directories extract_the_package prepare_for_installation actually_build_and_install fi if [ $POST_INSTALL = 1 ]; then cd "$SAGE_BUILD_DIR/$PKG_NAME" || exit $? unload_destdir install_scripts post_install fi if [ "$SAGE_CHECK" = "yes" -o "$SAGE_CHECK" = "warn" ]; then run_test_suite fi if [ $POST_INSTALL = 1 ]; then write_installation_record delete_the_temporary_build_directory_if_required echo "Finished installing $PKG_NAME" fi