1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
#!/bin/sh -e
# $Id$
# Copyright 2008-2023 Norbert Preining
# This file is licensed under the GNU General Public License version 2
# or any later version.
#
# Creates an executable script update-tlmgr-r*.sh (in the current
# directory) for updating the texlive.infra package and its per-platform
# subpackages on Unix, similar to the .exe we create for Windows. (Both
# are created in the nightly cron from tl-update-tlcritical.) We use
# the makeself utility to create the executable.
#
# The resulting update-tlmgr-*.sh is run (by the user) in the TL
# installation directory to be updated; it uses kpsewhich from PATH to
# determine what to do update.
#
# Debugging/development/testing:
# - create test hierarchy; either run install-tl as you like, or:
# tl-try-install Master/tlpkg/dev/profiles/TLinfra+exe.pro # or whatever
# This creates /tmp/ki with various platforms.
# - then see tl-try-makeself:
# running that will copy tlcritical to /tmp/krit,
# run this script (tl-makeself-from-tlnet) there,
# then update /tmp/ki from /tmp/krit, that is,
# doing an update as a user would do in their installed hierarchy.
#
# update-tlmgr-r*.sh --list # list files included in archive
# update-tlmgr-r*.sh -- --debug # run embedded script with -vx and more
mydir=`cd \`dirname "$0"\` && pwd` # Master/tlpkg/bin
PATH=$mydir:$PATH # for tlpkginfo
TLNET=$1
if test ! -d "$TLNET"; then
echo "$0: No tlnet directory given as argument, aborting." >&2
exit 1
fi
ARCHIVE=$TLNET/archive
if test ! -d "$ARCHIVE"; then
echo "$0: Subdirectory archive/ in $TLNET not found, aborting." >&2
exit 1
fi
# extract some version values from the tlnet tlpdb.
NETRELEASE=`sed -n 's!^depend release/!!p' "$TLNET/tlpkg/texlive.tlpdb"`
MINRELEASE=`sed -n 's!^depend minrelease/!!p' "$TLNET/tlpkg/texlive.tlpdb"`
if test -z "$NETRELEASE" || test -z "$MINRELEASE"; then
echo "$0: could not find (min)release in $TLNET/tlpkg/texlive.tlpdb, bye"\
>&2; exit 1
fi
CWD=`pwd` # save original dir
TMP=`mktemp --suffix=tlmksel -d` # work in new temp dir
cd "$TMP"
mkdir master
cd master
# unpack texlive.infra archives for all platforms, except w32.
# this gives us the tlpobj files along with the actual content files.
infrapkg=texlive.infra
#
# determine revision of infrastructure while we're here,
# for naming the archive later.
infrarev=`tlpkginfo --revision $infrapkg "$TLNET"`
if test -z "$infrarev"; then
echo "$0: tlpkginfo --revision $infrapkg $TLNET failed, goodbye." >&2
exit 1
fi
#
for i in "$ARCHIVE"/$infrapkg*.tar.xz; do
: "uncompressing $i" # for debugging
xz -d <"$i" | tar -xf - || exit 1
done
cd .. # back to the (temp) dir where we building things up
#
# create the script which will be run on the user's machine to do the update.
#
cat >runme.sh <<END_RUNME
#!/bin/sh
# \$Id$
# Updater for tlmgr and TL infrastructure on Unix. Public domain.
# Runs in unpacked archive directory.
# Created by `basename $0` at `date`.
creation_date="`date`"
NETRELEASE=$NETRELEASE
MINRELEASE=$MINRELEASE
infrapkg=$infrapkg
END_RUNME
# append to runme literally now -- no more variable expansions.
cat >>runme.sh <<'END_RUNME'
# see if we can determine where the TL to be upgraded lives.
# need tlpdb and a tlpobj dir (i.e., not the svn Master tree) at least.
# We are depending on the user's PATH to find kpsewhich, tlmgr, etc.
ROOT=`kpsewhich --var-value=SELFAUTOPARENT`
if test -r "$ROOT/tlpkg/texlive.tlpdb" && test -d "$ROOT/tlpkg/tlpobj/"; then
echo "$0: updating in $ROOT..."
tlmgrversion=`tlmgr version | grep '^TeX Live.*version' | awk '{print $NF}'`
if test -z "$tlmgrversion"; then
echo "$0: tlmgr version did not include version, goodbye." >&2
tlmgr version >&2
echo "($0: makeself creation date = $creation_date.)" >&2
exit 1
fi
#
echo "$0: tlmgr version says this is TeX Live $tlmgrversion,"
echo "$0: and this updater script created: $creation_date."
#
# Extra-verbose debugging option.
if test "x$1" = "x--debug"; then
shift
opt_debug=1
set -vx
else
opt_debug=
fi
#
if test "x$1" = "x--upgrade"; then
if test "x$NETRELEASE" = "x$tlmgrversion"; then
echo "$0: have TL $tlmgrversion, new version also $NETRELEASE;">&2
echo "$0: using --upgrade doesn't make sense; terminating." >&2
echo "($0: makeself creation date = $creation_date.)" >&2
exit 1
elif test "$tlmgrversion" -lt "$MINRELEASE"; then
echo "$0: upgrading from $tlmgrversion not supported;" >&2
echo "$0: can only upgrade from $MINRELEASE to $NETRELEASE." >&2
echo "$0: terminating." >&2
echo "($0: makeself creation date = $creation_date.)" >&2
exit 1
else
echo "$0: ok, doing full release upgrade " \
"from $tlmgrversion to $NETRELEASE."
fi
else
echo "$0: proceeding with tlmgr update."
fi
# move the architecture-specific files away so we don't blindly copy
# them all. The loop below and tlmgr invocation at the end will update.
mv ./master/bin .
mkdir ./installer
mv ./master/tlpkg/installer/tar.exe ./installer
mv ./master/tlpkg/installer/xz ./installer
mv ./master/tlpkg/installer/wget ./installer
mv ./master/tlpkg/installer/lz4 ./installer # could be anywhere
# install the architecture-independent files.
(cd master && tar cf - *) | (cd "$ROOT" && tar xf -) || exit 1
t_instdir=$ROOT/tlpkg/installer # target installer dir
t_xzdir=$t_instdir/xz
t_wgetdir=$t_instdir/wget
#
# ensure these target directories exist.
mkdir -p "$t_xzdir" "$t_wgetdir"
# Start the list of tlpobjs we will install with the
# platform-independent part of the infrastructure package.
#
# We use the tlpobjs from our own dir here, using relative names,
# since we constructed this directory tree and thus know there are no
# spaces in the names. That is not true for $ROOT. (The files are the
# same since we just updated $ROOT with the untar above.)
src_tlpobj=master/tlpkg/tlpobj
tlpobjs=$src_tlpobj/$infrapkg.tlpobj
if test -n "$opt_debug"; then
(: "here (`pwd`):"; ls) >&2
(: "installer:"; ls installer) >&2
(: "installer/wget:"; ls installer/wget) >&2
(: "installer/xz:"; ls installer/xz) >&2
(: "ROOT/bin=$ROOT/bin:"; ls "$ROOT"/bin) >&2
fi
# for each installed directory of binaries ...
for a in "$ROOT"/bin/*; do
test -d "$a" || continue # skip any cruft files
b=`basename "$a"` # just the architecture name
# skip 'man' directories if they are still present
if test "$b" = "man"; then
continue
fi
echo "$0: updating $a ..."
# add the tlpobjs for this platform to the list.
tlpobjs="$tlpobjs $src_tlpobj/$infrapkg.$b.tlpobj"
# install the bin dir for this platform.
(cd bin >&2 && tar cf - "$b") | (cd "$ROOT/bin" && tar xf -) || exit 1
# copy the xz binaries:
if test -r installer/xz/xz."$b"; then
cp installer/xz/xz."$b" "$t_xzdir/" || exit 1
elif test -r installer/xz/xz."$b".exe; then
# with .exe, for Cygwin.
cp installer/xz/xz."$b".exe "$t_xzdir/" || exit 1
elif echo "$b" | egrep 'win32|windows' >/dev/null \
&& test -r installer/xz/xz.exe; then
# annoyingly, we left windows out of the name, special cases all around:
cp installer/xz/xz.exe "$t_xzdir/" || exit 1
cp installer/wget/wget.exe "$t_wgetdir/" || exit 1
cp installer/tar.exe "$t_instdir/" || exit 1
else
echo "$0: no xz.[$b][.exe] binary for $a in `pwd`/installer/xz." >&2
exit 1
fi
#
# Cygwin (among others) does not need to provide wget, so don't
# worry about .exe here.
test -r installer/wget/wget.$b \
&& { cp installer/wget/wget.$b "$t_wgetdir/" || exit 1; }
done
else
cat <<END_ABORT_NODIR >&2
$0: Cannot find TeX Live root using kpsewhich --var-value=SELFAUTOPARENT.
$0: (no tlpkg/texlive.tlpdb and/or tlpkg/tlpobj/.)
$0: Please set your PATH as needed, otherwise it's hopeless.
END_ABORT_NODIR
exit 1
fi
# Invoke special tlmgr action with the tlpobjs we found.
# Hopefully the result will be a clean tlpdb state.
# We are running the new tlmgr, from our own archive, here,
# due to the untar above.
tlmgr_path=`which tlmgr 2>/dev/null` # provide complete path if we can
test -z "$tlmgr_path" && tlmgr_path=tlmgr # but no biggie if we can't
echo "$0: $tlmgr_path including objects: $tlpobjs"
#debug: (pwd; ls -l $tlpobjs; ls -lR) >/tmp/ls
#debug: -vv here gives more info. (Also -vx on the #! line above.)
if tlmgr -v _include_tlpobj $tlpobjs; then :; else
echo "$0: $tlmgr_path failed, goodbye." >&2
exit 1
fi
echo "$0: done."
END_RUNME
#
#debug: cp -f runme.sh /tmp
chmod ugo+x runme.sh
# make the self-extracting archive back in the directory from which
# we were invoked.
cd "$CWD"
# we must use the non-distro (Alma Linux 8) version of makeself, because
# that happened to have a bug causing unnecessary hard links to end up
# in the archive, which bsdtar (aka macOS) fails on.
# https://tug.org/pipermail/tlu/2023-November/000639.html
/usr/local/share/makeself/makeself.sh -q --keep-umask \
$TMP \
update-tlmgr-r$infrarev.sh \
"TeX Live Manager Updater" \
./runme.sh
rm -rf $TMP
# vim:set tabstop=2 expandtab: #
|