summaryrefslogtreecommitdiff
path: root/Master/texmf/scripts/texlive/updater-w32.bat
blob: 163138bd2a72e0d8ff5d89db68d83dda38120341 (plain)
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
@echo off
rem Update script for TeX Live infrastructure
rem called automatically if there are any infrastructure updates
rem
rem Copyright 2009 by Tomasz M. Trzeciak <t.m.trzeciak@googlemail.com>
rem This file is licensed under the GNU General Public License version 2
rem or any later version.
rem

:: ===================================================================
::                INFRASTRUCTURE UPDATE ON WINDOWS
:: ===================================================================
:: Infrastructure files cannot be updated directly from the tlmgr.pl 
:: script due to file locking problem on Windows - files that are in
:: use (either open or executing) cannot be removed or replaced.
:: Therefore the update process is performed by a batch script outside
:: of tlmgr.pl.
:: There are three pieces involved in the update: tlmgr.bat launcher, 
:: write_w32_updater subroutine in tlmgr.pl and this script. Their 
:: roles are as follows:
:: * tlmgr.bat is a watchdog - it launches tlmgr.pl and watches for
::   a trigger script that is to be executed. If trigger script exists
::   before tlmgr.pl is launched, it will be removed or tlmgr.bat will
::   abort if it fails to do so. This means that  the trigger script 
::   has to be created by the current invocation of tlmgr.pl
:: * write_w32_updater subroutine in tlmgr.pl prepares the update
::   and writes the trigger script. Packages in .xz  archives are
::   dowloaded/copied and uncompressed to .tar files. Also .tar 
::   backups of the current packages are made. If everything is 
::   successful, the trigger script is written, otherwise the update 
::   is aborted.
:: * run-updater-w32.bat trigger script passes package list together 
::   with revison numbers to the updater script. Additionally it locks
::   itself up write open (and the updater script as well) to prevent 
::   tlmgr.bat from starting another instance of tlmgr and/or update.
:: * updater-w32.bat, which is this script, does the actual update. It
::   makes some very specific assumptions. Arguments are expected to
::   be a package list passed in triples:
::       package-name old-revision-number new-revision-number
::   For each package-name a .tar archive package-name.tar is expected
::   (also for .source and .doc pseudo packages---those are for
::   distribution only and don't  appear separately in tlpdb).
::   Additionally a backup archive is expected:
::       __BACKUP_package-name.rXXX.tar, 
::   where XXX is (old) revision number (.source and .doc are included
::   in the backup).
::   The update itself proceeds as follows:
::     (1) untar all package archives
::     (2) include .tlpobj files into tlpdb
::     (3) print update info
::   Any error during (1) or (2) triggers the rollback action:
::     (1) print failed update info
::     (2) untar all package backups
::     (3) include .tlpobj files (from backup) into tlpdb
::     (4) print restore info
::   Any error during (2) or (3) and we go into panic mode.  At this
::   point there is no guarantee that the installation is still
::   working. There is not much we can do but to print failed restore 
::   info and give instructions to download and run 
::   'update-tlmgr-latest.exe' to repair the installation.
:: ===================================================================

rem Make environment changes local & enable cmd extensions
rem (we don't want delayed expansion becasue it's hard to echo bang !)
setlocal enableextensions disabledelayedexpansion
rem Make sure that we can use dynamic variables
(set errorlevel=)
(set date=)
(set time=)

rem Get TL installation root
for /f "delims=" %%I in ('kpsewhich -var-value=SELFAUTOPARENT') do (set tlroot=%%~fI)
if not exist "%tlroot%\texmf\scripts\texlive\tlmgr.pl" (
  echo %~n0: cannot locate installation root.>&2
  exit /b 1
)

rem Get log file location
for /f "delims=" %%I in ('kpsewhich -var-value=TEXMFSYSVAR') do (set logdir=%%~fI\web2c)
if not exist "%logdir%\" (set logdir=%tlroot%\temp)

rem Change to root
rem cd /d "%tlroot%"

rem Make a private copy of tar.exe
copy /y "%tlroot%\tlpkg\installer\tar.exe" "%tlroot%\temp\tar-w32.exe" >nul
if errorlevel 1 (
  echo %~n0: cannot copy tar.exe.>&2
  exit /b 1
)

rem Set up perl environment
set PERL5LIB=%tlroot%\tlpkg\tlperl\lib

rem Get package list from arguments
(set pkgpartslist=%*)
if not defined pkgpartslist (
  echo %~n0: no arguments given, how did you start me?>&2
  exit /b 1
)

rem Construct package list without .source and .doc packages
rem Count the total number of packages while doing that
set pkgcount=0
(set pkglist=)
call :foreachpkg remove_src_doc pkglist %pkgpartslist%

rem Set gui mode to console if not defined
if not defined guimode set guimode=0

echo DO NOT CLOSE THIS WINDOW!
echo TeX Live infrastructure update in progress...
call :foreachpkg untar "%tlroot%\temp\" %pkgpartslist%
if errorlevel 1 goto :rollback
call :foreachpkg incltlpobj "%tlroot%\tlpkg\tlpobj\" %pkgpartslist%
if errorlevel 1 goto :rollback
call :foreachpkg updateinfo "update" %pkglist%
call :printmsg%guimode% "TeX Live infrastructure update complete." 0 "TeX Live Manager 2008"
set exitcode=0
goto :finish

:rollback
call :foreachpkg updateinfo "failed update" %pkglist% >&2
echo Rolling back to previous version...
call :foreachpkg untar "%tlroot%\temp\__BACKUP_" %pkglist%
if errorlevel 1 goto :panic
call :foreachpkg incltlpobj "%tlroot%\tlpkg\tlpobj\" %pkglist%
if errorlevel 1 goto :panic
call :foreachpkg restoreinfo "restore" %pkglist%
call :printmsg%guimode% "TeX Live infrastructure update failed.\nPrevious version has been restored." 16  "ERROR: TeX Live Manager 2008" >&2
set exitcode=1
goto :finish

:panic
call :foreachpkg restoreinfo "failed restore" %pkglist% >&2
call :printmsg%guimode% "TeX Live infrastructure update failed and backup recovery failed as well.\nYour TeX Live installation may be broken, to repair it download and run:\nhttp://mirror.ctan.org/systems/texlive/tlnet/2008/update-tlmgr-latest.exe" 16 "FATAL ERROR: TeX Live Manager 2008" >&2
rem Evil has taken over - emit adequate exit code
exit /b 666

:finish
del "%tlroot%\temp\tar-w32.exe" "%tlroot%\temp\__BACKUP_*" >nul 2>&1 
exit /b %exitcode%

REM SUBROUTINES

:foreachpkg cmd prefix pkgname oldrev newrev ...
set pkgnr=0
:pkgloop
if [%3]==[] exit /b 0
call :%1 %2 %3 %4 %5
if errorlevel 1 exit /b 1
shift /3 & shift /3 & shift /3
goto :pkgloop

:remove_src_doc
if /i %~x2.==.source. exit /b 0
if /i %~x2.==.doc. exit /b 0
set %1=%pkglist% %2 %3 %4
set /a pkgcount+=1
exit /b 0

:untar %tlroot%\temp\[__BACKUP_] pkgname
set "suffix=tar"
if %~n1_==__BACKUP__ set "suffix=r%~3.tar"
"%tlroot%\temp\tar-w32.exe" -C "%tlroot%" -f "%~1%~2.%suffix%" -x && del "%~1%~2.%suffix%"
exit /b %errorlevel%

:incltlpobj %tlroot%\tlpkg\tlpobj\ pkgname
"%tlroot%\tlpkg\tlperl\bin\perl.exe" "%tlroot%\texmf\scripts\texlive\tlmgr.pl" _include_tlpobj "%~1%~2.tlpobj"
exit /b %errorlevel%

:updateinfo header pkgname oldrev newrev
set "infomsg= -> %~4"
:restoreinfo header pkgname oldrev newrev
set "infomsg=%~1: %~2 (%~3%infomsg%)"
set "infomsg=%infomsg:>=^>%"
set /a pkgnr+=1
echo [%pkgnr%/%pkgcount%] %infomsg%
echo [%date% %time%] %infomsg%>>"%logdir%\tlmgr.log"
set "infomsg="
exit /b 0

:printmsg0 "message text"
set infomsg=%~1
for %%I in ("%infomsg:\n=" "%") do echo.%%~I
exit /b 0

:printmsg1 "message text" icon  "title string"
echo MsgBox Replace("%~1", "\n", Chr(10)), %2, "%~3" >"%tlroot%\temp\dialogpopup.vbs"
cscript -nologo "%tlroot%\temp\dialogpopup.vbs"
del "%tlroot%\temp\dialogpopup.vbs"
exit /b %errorlevel%