Ticket #13373: latest-online-spkg.sh

File latest-online-spkg.sh, 5.7 KB (added by leif, 9 years ago)

Tentative / preliminary "stand-alone" shell script to replace sage-latest-online-package; doesn't use/support Python (even if available) [yet].

Line 
1#!/usr/bin/env bash
2
3# Get/print the (package name plus version suffix of) the latest spkg version
4# available online, searching all "repos" (i.e., package categories such as
5# "optional", "standard" etc., see variable PACKAGE_REPOS below) on $SAGE_SERVER
6# (if set, otherwise on the default server, www.sagemath.org).
7# Currently the single argument the script takes is the *base* name of the
8# spkg, without any version or filename extension.
9#
10# We might support further options (or command line arguments), e.g. to select
11# the "repo(s)", or (additional) servers to search.
12#
13# This script is supposed to work outside the Sage environment as well.
14
15DEFAULT_SERVER="www.sagemath.org"
16PACKAGE_DIR="packages"
17PACKAGE_REPOS="optional standard experimental archive" # Order matters!
18PACKAGE_LIST="list" # Filename of the (plain text) package list
19
20if [ $# -ne 1 ]; then
21    echo >&2 "Error: $0 takes exactly one argument, the base name of the Sage package to look for."
22    exit 2
23else
24    # We may check whether $1 is a "proper" spkg name without (dashs and) any
25    # version or patch level, and without e.g. the '.spkg' extension.
26    # Or just strip such if present, although the original Python script did
27    # not do that.
28    # Returning 'foo-1.4.3' in case the user asked for (e.g.) 'foo-2' on the
29    # other hand is perhaps undesirable.
30    PACKAGE_BASENAME=$1
31fi
32
33if [ -z "$SAGE_SERVER" ]; then
34    SAGE_SERVER=$DEFAULT_SERVER
35else
36    # SAGE_SERVER set; strip any trailing slash(es) if present:
37    SAGE_SERVER=`echo $SAGE_SERVER | sed 's|/*$||'`
38fi
39
40# TODO: Probably check whether Python is available, and if so, call the
41#       original 'sage-latest-online-package' Python script.
42
43if [ -z "$URL_GRABBER" ]; then
44    if command -v wget &>/dev/null; then
45        URL_GRABBER=wget
46        URL_GRABBER_OPTS="-nv -O -"
47        # Hmmm.  Neither '-nv' nor '-q' is what we really want; the former is
48        # still too verbose, while the latter also suppresses error messages.
49        # Use '-o <logfile>' (and cat that to stderr only in case of an error)?
50    elif command -v curl &>/dev/null; then
51        URL_GRABBER=curl
52        URL_GRABBER_OPTS="-q -s -S -o -" # probably also '-f'
53    else
54        echo >&2 "Error: $0: No program to fetch (text) files from the web found."
55        echo >&2 "       Either install 'wget' or 'curl', or set the environment"
56        echo >&2 "       variables URL_GRABBER and URL_GRABBER_OPTS to use some"
57        echo >&2 "       alternate, installed program.  (In the latter case,"
58        echo >&2 "       URL_GRABBER_OPTS have to contain the option(s) to"
59        echo >&2 "       [silently] print the contents of the specified URL"
60        echo >&2 "       to standard output (rather than saving it to some file)."
61        exit 3
62    fi
63elif ! command -v $URL_GRABBER &>/dev/null; then
64    # Don't quote $URL_GRABBER above, to allow options in it.
65    echo >&2 "Error: $0: URL_GRABBER(=$URL_GRABBER) specified, but not found along PATH."
66    exit 4
67elif [ -z "$URL_GRABBER_OPTS" ]; then
68    echo >&2 "Warning: URL_GRABBER(=$URL_GRABBER) specified, but URL_GRABBER_OPTS are empty."
69fi
70
71
72# Check various package "repositories" (such as "optional", "standard") on the
73# given server in order, but return only the first match (if any):
74some_error=false
75for repo in $PACKAGE_REPOS; do
76    url="$SAGE_SERVER/$PACKAGE_DIR/$repo/$PACKAGE_LIST"
77    pkg_list=`$URL_GRABBER $URL_GRABBER_OPTS "$url"` # Don't redirect stderr.
78    if [ $? -ne 0 ]; then
79        # echo >&2 "Error: $0: '$URL_GRABBER' failed.  Probably see above for further details."
80        # exit 5
81        echo >&2 "Warning: $0: '$URL_GRABBER' failed to fetch list of $repo spkgs from $SAGE_SERVER."
82        echo >&2 "         (Probably see above for further details.)"
83        # Not [yet] necessarily fatal, first try further repos...
84        some_error=true
85    elif [ -z "$pkg_list" ]; then
86        echo >&2 "Warning: List of $repo spkgs on $SAGE_SERVER is empty."
87        # Not [yet] necessarily fatal, first try further repos...
88        some_error=true
89    else
90        # Grabbing the spkg list succeeded, now look for the desired spkg:
91        # At least in theory, the list could contain multiple versions of
92        # the requested spkg, although the original Python version didn't
93        # (properly) handle that case either -- it would just have returned
94        # the first match (without sorting the list).
95        matching_pkgs=""
96        for pkg in $pkg_list; do
97            if [ "`echo $pkg | sed 's/-.*//'`" = "$PACKAGE_BASENAME" ]; then
98                matching_pkgs="$matching_pkgs $pkg"
99            fi
100        done
101        case "`echo $matching_pkgs | wc -w`" in
102            0) # None found, try next repo (if any)
103               ;;
104            1) # Ok, single matching package found, don't search further repos.
105               echo $matching_pkgs
106               exit 0
107               ;;
108            *) # More than 1 matching package found -- what now?
109               last_matching_pkg=`echo $matching_pkgs | tr ' ' '\n' | sort | tail -1`
110               echo >&2 "Warning: More than one version of $PACKAGE_BASENAME found in $repo spkgs on $SAGE_SERVER:"
111               echo >&2 "         $matching_pkgs"
112               echo >&2 "         Choosing the last in alphabetical order, i.e. $last_matching_pkg."
113               echo $last_matching_pkg
114               exit 0
115        esac
116    fi
117done
118
119# No matching package found, failed to fetch package list(s), or (some) list(s) empty...
120# "Return" (i.e., print to stdout) some error message?  I think 'sage-spkg' will echo this
121# in case of an error (exit code non-zero) as well.
122if $some_error; then
123    echo "No matching package found on $SAGE_SERVER, but couldn't fetch all package lists either."
124else
125    echo "No package matching $PACKAGE_BASENAME found on $SAGE_SERVER."
126fi
127exit 1
128