Skip to content
This repository was archived by the owner on Feb 1, 2023. It is now read-only.

Commit 7b44d1c

Browse files
author
Release Manager
committed
Trac #30888: Make $SAGE_LOCAL/bin/sage work again from any directory, in an environment without SAGE_* variables, following symlinks
The feature introduced in #25486 (Discover `SAGE_SCRIPTS_DIR` to make `$SAGE_LOCAL/bin/sage` work from any directory, in an environment without SAGE_* variables) was killed by #30128 (enforce sourcing of `sage-env-config` before `src/bin/sage-env`). We repair it, making sure that it works even if $0 is a symlink. URL: https://trac.sagemath.org/30888 Reported by: mkoeppe Ticket author(s): Michael Orlitzky Reviewer(s): Matthias Koeppe
2 parents 8736c42 + a63d256 commit 7b44d1c

File tree

1 file changed

+100
-20
lines changed

1 file changed

+100
-20
lines changed

src/bin/sage

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,91 @@
11
#!/usr/bin/env bash
22

3+
# WARNING: this function is copy/pasted from both src/bin/sage-env and
4+
# the top-level "sage" script. Please keep them synchronized.
5+
resolvelinks() {
6+
# $in is what still needs to be converted (normally has no starting slash)
7+
in="$1"
8+
# $out is the part which is converted (normally ends with trailing slash)
9+
out="./"
10+
11+
# Move stuff from $in to $out
12+
while [ -n "$in" ]; do
13+
# Normalize $in by replacing consecutive slashes by one slash
14+
in=$(echo "${in}" | sed 's://*:/:g')
15+
16+
# If $in starts with a slash, remove it and set $out to the root
17+
in_without_slash=${in#/}
18+
if [ "$in" != "$in_without_slash" ]; then
19+
in=$in_without_slash
20+
out="/"
21+
continue
22+
fi
23+
24+
# Check that the directory $out exists by trying to cd to it.
25+
# If this fails, then cd will show an error message (unlike
26+
# test -d "$out"), so no need to be more verbose.
27+
( cd "$out" ) || return $?
28+
29+
30+
# Get the first component of $in
31+
f=${in%%/*}
32+
33+
# If it is not a symbolic link, simply move it to $out
34+
if [ ! -L "$out$f" ]; then
35+
in=${in#"$f"}
36+
out="$out$f"
37+
38+
# If the new $in starts with a slash, move it to $out
39+
in_without_slash=${in#/}
40+
if [ "$in" != "$in_without_slash" ]; then
41+
in=$in_without_slash
42+
out="$out/"
43+
fi
44+
continue
45+
fi
46+
47+
# Now resolve the symbolic link "$f"
48+
f_resolved=`readlink -n "$out$f" 2>/dev/null`
49+
status=$?
50+
# status 127 means readlink could not be found.
51+
if [ $status -eq 127 ]; then
52+
# We don't have "readlink", try a stupid "ls" hack instead.
53+
# This will fail if we have filenames like "a -> b".
54+
fls=`ls -l "$out$f" 2>/dev/null`
55+
status=$?
56+
f_resolved=${fls##*-> }
57+
58+
# If $fls equals $f_resolved, then certainly
59+
# something is wrong
60+
if [ $status -eq 0 -a "$fls" = "$f_resolved" ]; then
61+
echo >&2 "Cannot parse output from ls -l '$out$f'"
62+
return 1
63+
fi
64+
fi
65+
if [ $status -ne 0 ]; then
66+
echo >&2 "Cannot read symbolic link '$out$f'"
67+
return $status
68+
fi
69+
70+
# In $in, replace $f by $f_resolved (leave $out alone)
71+
in="${in#${f}}"
72+
in="${f_resolved}${in}"
73+
done
74+
75+
# Return $out
76+
echo "$out"
77+
}
78+
79+
# Resolve the links in $0 so that local/bin/sage can be executed from
80+
# a symlink (Trac #30888).
81+
SELF=$(resolvelinks "${0}")
82+
383
# Display the current version of Sage
484
# usage: sage_version [-v]
585
# -v display the full version banner including release date
686
sage_version() {
7-
if [ -f "$0-version.sh" ]; then
8-
. "$0-version.sh"
87+
if [ -f "${SELF}-version.sh" ]; then
88+
. "${SELF}-version.sh"
989
else
1090
. "$SAGE_ROOT/src/bin/sage-version.sh"
1191
fi
@@ -60,22 +140,22 @@ usage() {
60140

61141
# Determine SAGE_ROOT, SAGE_LOCAL, and SAGE_VENV.
62142
unset SAGE_VENV
63-
if [ -x "$0-config" ]; then
143+
if [ -x "${SELF}-config" ]; then
64144
# optional sage-config console script, installed by sage_conf
65-
export SAGE_ROOT=$("$0-config" SAGE_ROOT)
66-
export SAGE_LOCAL=$("$0-config" SAGE_LOCAL)
145+
export SAGE_ROOT=$("${SELF}-config" SAGE_ROOT)
146+
export SAGE_LOCAL=$("${SELF}-config" SAGE_LOCAL)
67147
fi
68-
if [ -f "$0-src-env-config" ]; then
148+
if [ -f "${SELF}-src-env-config" ]; then
69149
# Not installed script, present only in src/bin/
70-
. "$0-src-env-config" >&2
150+
. "${SELF}-src-env-config" >&2
71151
fi
72-
if [ -z "$SAGE_VENV" -a -x "$0-venv-config" ]; then
152+
if [ -z "$SAGE_VENV" -a -x "${SELF}-venv-config" ]; then
73153
# installed by setup.py
74-
export SAGE_VENV=$("$0-venv-config" SAGE_VENV)
154+
export SAGE_VENV=$("${SELF}-venv-config" SAGE_VENV)
75155
fi
76-
if [ -f "$0-env-config" ]; then
156+
if [ -f "${SELF}-env-config" ]; then
77157
# As of Trac #22731, sage-env-config is optional.
78-
. "$0-env-config" >&2
158+
. "${SELF}-env-config" >&2
79159
fi
80160

81161
#####################################################################
@@ -88,7 +168,7 @@ fi
88168
if [ "$1" = '--nodotsage' ]; then
89169
export DOT_SAGE=`mktemp -d ${TMPDIR:-/tmp}/dotsageXXXXXX`
90170
shift
91-
command "$0" "$@"
171+
command "${SELF}" "$@"
92172
status=$?
93173
rm -rf "$DOT_SAGE"
94174
exit $status
@@ -204,14 +284,14 @@ fi
204284

205285

206286
#####################################################################
207-
# Source sage-env ($0 is the name of this "sage" script, so we can just
287+
# Source sage-env ($SELF is the name of this "sage" script, so we can just
208288
# append -env to that). We redirect stdout to stderr, which is safer
209289
# for scripts.
210290
#####################################################################
211-
if [ -f "$0-env" ]; then
212-
. "$0-env" >&2
291+
if [ -f "${SELF}-env" ]; then
292+
. "${SELF}-env" >&2
213293
if [ $? -ne 0 ]; then
214-
echo >&2 "Error setting environment variables by sourcing '$0-env';"
294+
echo >&2 "Error setting environment variables by sourcing '${SELF}-env';"
215295
echo >&2 "possibly contact sage-devel (see http://groups.google.com/group/sage-devel)."
216296
exit 1
217297
fi
@@ -1011,13 +1091,13 @@ if [ "$1" = '-gdb' -o "$1" = "--gdb" ]; then
10111091
shift
10121092
sage_setup
10131093
if [ "$SAGE_DEBUG" = "no" ]; then
1014-
gdb -x "$0-gdb-commands" \
1015-
-args python "$0-ipython" "$@" -i
1094+
gdb -x "${SELF}-gdb-commands" \
1095+
-args python "${SELF}-ipython" "$@" -i
10161096
else
10171097
sage_dir=$(sage-python -c 'import os, sage; print(os.path.dirname(sage.__file__))')
10181098
cygdb "$sage_dir" "$SAGE_SRC/sage" \
1019-
-- -x "$0-gdb-commands" \
1020-
-args python "$0-ipython" "$@" -i
1099+
-- -x "${SELF}-gdb-commands" \
1100+
-args python "${SELF}-ipython" "$@" -i
10211101
fi
10221102
exit $?
10231103
fi

0 commit comments

Comments
 (0)