SL-33966: Viewer installed files are not described in a centralized source
This introduces the viewer_manifest.py and associated libraries. Check out https://osiris.lindenlab.com/mediawiki/index.php/Installer_Manifest for some more information. The gist of it is that all files to be included in the viewer installations are described in viewer_manifest.py. viewer_manifest.py also acts as a packager, if you give it the right options. All of the old methods of packaging (Makefile_Mac, scons, and the various .bat files) still work, but they are mostly just shells for calls to viewer_manifest.py. You're now required to have python 2.3 or later on your machine to be able to package up an installer, but thankfully most people already have this.master
parent
5bdbc85a14
commit
b7b4135e55
|
|
@ -0,0 +1,858 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; secondlife setup.nsi
|
||||
;;; Copyright 2004-2006, Linden Research, Inc.
|
||||
;;; For info, see http://www.nullsoft.com/free/nsis/
|
||||
;;;
|
||||
;;; NSIS 2.02 or higher required
|
||||
;;; Author: James Cook, Don Kjer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Compiler flags
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; Detect NSIS compiler version
|
||||
!define "NSIS${NSIS_VERSION}"
|
||||
!ifdef "NSISv2.02" | "NSISv2.03" | "NSISv2.04" | "NSISv2.05" | "NSISv2.06"
|
||||
;;; before 2.07 defaulted lzma to solid (whole file)
|
||||
SetCompressor lzma
|
||||
!else
|
||||
;;; after 2.07 required /solid for whole file compression
|
||||
SetCompressor /solid lzma
|
||||
!endif
|
||||
|
||||
SetOverwrite on ; overwrite files
|
||||
SetCompress auto ; compress iff saves space
|
||||
SetDatablockOptimize off ; only saves us 0.1%, not worth it
|
||||
XPStyle on ; add an XP manifest to the installer
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Project flags
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
%%VERSION%%
|
||||
|
||||
;;; Tweak for different servers/builds (this placeholder is replaced by viewer_manifest.py)
|
||||
%%GRID_VARS%%
|
||||
|
||||
Name ${INSTNAME}
|
||||
|
||||
SubCaption 0 " Setup" ; override "license agreement" text
|
||||
|
||||
BrandingText " " ; bottom of window text
|
||||
Icon res\install_icon.ico ; our custom icon
|
||||
UninstallIcon res\uninstall_icon.ico ; our custom icon
|
||||
WindowIcon on ; show our icon in left corner
|
||||
BGGradient off ; no big background window
|
||||
CRCCheck on ; make sure CRC is OK
|
||||
InstProgressFlags smooth colored ; new colored smooth look
|
||||
ShowInstDetails nevershow ; no details, no "show" button
|
||||
SetOverwrite on ; stomp files by default
|
||||
AutoCloseWindow true ; after all files install, close window
|
||||
|
||||
!ifdef UPDATE
|
||||
LicenseText "This package will update Second Life to version ${VERSION_LONG}." "Next >"
|
||||
!else
|
||||
LicenseText "This package will install Second Life on your computer." "Next >"
|
||||
!endif
|
||||
|
||||
LicenseData "releasenotes.txt"
|
||||
|
||||
InstallDir "$PROGRAMFILES\${INSTNAME}"
|
||||
InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" ""
|
||||
!ifdef UPDATE
|
||||
DirText "Installation Directory" "Select the Second Life directory to update:"
|
||||
!else
|
||||
DirText "Installation Directory" "Select the directory to install Second Life in:"
|
||||
!endif
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Variables
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Var INSTPROG
|
||||
Var INSTEXE
|
||||
Var INSTFLAGS
|
||||
Var INSTSHORTCUT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Sections
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
Section "" ; (default section)
|
||||
|
||||
SetShellVarContext all ; install for all users (if you change this, change it in the uninstall as well)
|
||||
|
||||
|
||||
; Start with some default values.
|
||||
StrCpy $INSTFLAGS "${INSTFLAGS}"
|
||||
StrCpy $INSTPROG "${INSTNAME}"
|
||||
StrCpy $INSTEXE "${INSTEXE}"
|
||||
StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
||||
|
||||
IfSilent +2
|
||||
Goto NOT_SILENT
|
||||
Call CheckStartupParams ; Figure out where, what and how to install.
|
||||
NOT_SILENT:
|
||||
Call CheckWindowsVersion ; warn if on Windows 98/ME
|
||||
Call CheckIfAdministrator ; Make sure the user can install/uninstall
|
||||
Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version
|
||||
Call CloseSecondLife ; Make sure we're not running
|
||||
Call RemoveNSIS ; Check for old NSIS install to remove
|
||||
|
||||
;;; Don't remove cache files during a regular install, removing the inventory cache on upgrades results in lots of damage to the servers.
|
||||
;Call RemoveCacheFiles ; Installing over removes potentially corrupted
|
||||
; VFS and cache files.
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Files
|
||||
;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
|
||||
%%INSTALL_FILES%%
|
||||
|
||||
; If this is a silent update, we don't need to re-create these shortcuts or registry entries.
|
||||
IfSilent POST_INSTALL
|
||||
|
||||
; Shortcuts in start menu
|
||||
CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT"
|
||||
SetOutPath "$INSTDIR"
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$INSTEXE" "$INSTFLAGS"
|
||||
|
||||
!ifdef MUSEUM
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum.lnk" \
|
||||
|
||||
"$INSTDIR\$INSTEXE" "$INSTFLAGS -simple"
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum Spanish.lnk" \
|
||||
|
||||
"$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish"
|
||||
!endif
|
||||
|
||||
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Trial Account.url" \
|
||||
"InternetShortcut" "URL" \
|
||||
"http://www.secondlife.com/registration/"
|
||||
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Your Account.url" \
|
||||
"InternetShortcut" "URL" \
|
||||
"http://www.secondlife.com/account/"
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" \
|
||||
"$INSTDIR\releasenotes.txt"
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Scripting Language Help.lnk" \
|
||||
"$INSTDIR\lsl_guide.html"
|
||||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \
|
||||
'"$INSTDIR\uninst.exe"' '/P="$INSTPROG"'
|
||||
|
||||
; Other shortcuts
|
||||
SetOutPath "$INSTDIR"
|
||||
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS"
|
||||
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS"
|
||||
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
|
||||
'"$INSTDIR\uninst.exe"' '/P="$INSTPROG"'
|
||||
|
||||
!ifdef MUSEUM
|
||||
CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple"
|
||||
|
||||
CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish"
|
||||
|
||||
CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple"
|
||||
|
||||
CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish"
|
||||
|
||||
!endif
|
||||
|
||||
; Write registry
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" "$INSTFLAGS"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG (remove only)"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe" /P="$INSTPROG"'
|
||||
|
||||
; Write URL registry info
|
||||
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life"
|
||||
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" ""
|
||||
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
|
||||
WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"'
|
||||
|
||||
Goto WRITE_UNINST
|
||||
|
||||
POST_INSTALL:
|
||||
; Run a post-executable script if necessary.
|
||||
Call PostInstallExe
|
||||
|
||||
WRITE_UNINST:
|
||||
; write out uninstaller
|
||||
WriteUninstaller "$INSTDIR\uninst.exe"
|
||||
|
||||
; end of default section
|
||||
SectionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; PostInstallExe
|
||||
; This just runs any post installation scripts.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function PostInstallExe
|
||||
push $0
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "PostInstallExe"
|
||||
;MessageBox MB_OK '$0'
|
||||
ExecWait '$0'
|
||||
pop $0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; CheckStartupParameters
|
||||
; Sets INSTFLAGS, INSTPROG, and INSTEXE.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CheckStartupParams
|
||||
push $0
|
||||
push $R0
|
||||
|
||||
; Look for a registry entry with info about where to update.
|
||||
Call GetProgramName
|
||||
pop $R0
|
||||
StrCpy $INSTPROG "$R0"
|
||||
StrCpy $INSTEXE "$R0.exe"
|
||||
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" ""
|
||||
; If key doesn't exist, skip install
|
||||
IfErrors ABORT
|
||||
StrCpy $INSTDIR "$0"
|
||||
|
||||
; We now have a directory to install to. Get the startup parameters and shortcut as well.
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags"
|
||||
IfErrors +2
|
||||
StrCpy $INSTFLAGS "$0"
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut"
|
||||
IfErrors +2
|
||||
StrCpy $INSTSHORTCUT "$0"
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe"
|
||||
IfErrors +2
|
||||
StrCpy $INSTEXE "$0"
|
||||
Goto FINISHED
|
||||
|
||||
ABORT:
|
||||
MessageBox MB_OK "Could not find the program '$INSTPROG'. Silent update failed."
|
||||
Quit
|
||||
|
||||
FINISHED:
|
||||
;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS"
|
||||
pop $R0
|
||||
pop $0
|
||||
FunctionEnd
|
||||
|
||||
Function un.CheckStartupParams
|
||||
push $0
|
||||
push $R0
|
||||
|
||||
; Look for a registry entry with info about where to update.
|
||||
Call un.GetProgramName
|
||||
pop $R0
|
||||
StrCpy $INSTPROG "$R0"
|
||||
StrCpy $INSTEXE "$R0.exe"
|
||||
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" ""
|
||||
; If key doesn't exist, skip install
|
||||
IfErrors ABORT
|
||||
StrCpy $INSTDIR "$0"
|
||||
|
||||
; We now have a directory to install to. Get the startup parameters and shortcut as well.
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags"
|
||||
IfErrors +2
|
||||
StrCpy $INSTFLAGS "$0"
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut"
|
||||
IfErrors +2
|
||||
StrCpy $INSTSHORTCUT "$0"
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe"
|
||||
IfErrors +2
|
||||
StrCpy $INSTEXE "$0"
|
||||
Goto FINISHED
|
||||
|
||||
ABORT:
|
||||
MessageBox MB_OK "Could not find the program '$INSTPROG'. Silent update failed."
|
||||
Quit
|
||||
|
||||
FINISHED:
|
||||
;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS"
|
||||
pop $R0
|
||||
pop $0
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; After install completes, offer readme file
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function .onInstSuccess
|
||||
MessageBox MB_YESNO \
|
||||
"Start Second Life now?" /SD IDYES IDNO NoReadme
|
||||
; Assumes SetOutPath $INSTDIR
|
||||
Exec '"$INSTDIR\$INSTEXE" $INSTFLAGS'
|
||||
NoReadme:
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Remove old NSIS version. Modifies no variables.
|
||||
; Does NOT delete the LindenWorld directory, or any
|
||||
; user files in that directory.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function RemoveNSIS
|
||||
Push $0
|
||||
; Grab the installation directory of the old version
|
||||
DetailPrint "Checking for old version..."
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" ""
|
||||
|
||||
; If key doesn't exist, skip uninstall
|
||||
IfErrors NO_NSIS
|
||||
|
||||
; Clean up legacy beta shortcuts
|
||||
Delete "$SMPROGRAMS\Second Life Beta.lnk"
|
||||
Delete "$DESKTOP\Second Life Beta.lnk"
|
||||
Delete "$SMPROGRAMS\Second Life.lnk"
|
||||
|
||||
; Clean up old newview.exe file
|
||||
Delete "$INSTDIR\newview.exe"
|
||||
|
||||
; Intentionally don't delete the stuff in
|
||||
; Documents and Settings, so we keep the user's settings
|
||||
|
||||
NO_NSIS:
|
||||
Pop $0
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Make sure we're not on Windows 98 / ME
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CheckWindowsVersion
|
||||
DetailPrint "Checking Windows version..."
|
||||
Call GetWindowsVersion
|
||||
Pop $R0
|
||||
; Just get first two characters, ignore 4.0 part of "NT 4.0"
|
||||
StrCpy $R0 $R0 2
|
||||
; Blacklist certain OS versions
|
||||
StrCmp $R0 "95" win_ver_bad
|
||||
StrCmp $R0 "98" win_ver_bad
|
||||
StrCmp $R0 "ME" win_ver_bad
|
||||
StrCmp $R0 "NT" win_ver_bad
|
||||
Return
|
||||
win_ver_bad:
|
||||
MessageBox MB_YESNO 'Second Life only supports Windows XP, Windows 2000, and Mac OS X.$\n$\nAttempting to install on Windows $R0 can result in crashes and data loss.$\n$\nInstall anyway?' IDNO win_ver_abort
|
||||
Return
|
||||
win_ver_abort:
|
||||
Quit
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Make sure the user can install/uninstall
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CheckIfAdministrator
|
||||
DetailPrint "Checking for permission to install..."
|
||||
UserInfo::GetAccountType
|
||||
Pop $R0
|
||||
StrCmp $R0 "Admin" is_admin
|
||||
MessageBox MB_OK 'You appear to be using a "limited" account.$\nYou must be an "administrator" to install Second Life.'
|
||||
Quit
|
||||
is_admin:
|
||||
Return
|
||||
FunctionEnd
|
||||
|
||||
Function un.CheckIfAdministrator
|
||||
DetailPrint "Checking for permission to uninstall..."
|
||||
UserInfo::GetAccountType
|
||||
Pop $R0
|
||||
StrCmp $R0 "Admin" is_admin
|
||||
MessageBox MB_OK 'You appear to be using a "limited" account.$\nYou must be an "administrator" to uninstall Second Life.'
|
||||
Quit
|
||||
is_admin:
|
||||
Return
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Checks to see if the current version has already been installed (according to the registry).
|
||||
; If it has, allow user to bail out of install process.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CheckIfAlreadyCurrent
|
||||
Push $0
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version"
|
||||
StrCmp $0 ${VERSION_LONG} 0 DONE
|
||||
MessageBox MB_OKCANCEL "It appears that Second Life ${VERSION_LONG} is already installed.$\n$\nWould you like to install it again?" /SD IDOK IDOK DONE
|
||||
Quit
|
||||
|
||||
DONE:
|
||||
Pop $0
|
||||
Return
|
||||
FunctionEnd
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Close the program, if running. Modifies no variables.
|
||||
; Allows user to bail out of install process.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function CloseSecondLife
|
||||
Push $0
|
||||
FindWindow $0 "Second Life" ""
|
||||
IntCmp $0 0 DONE
|
||||
MessageBox MB_OKCANCEL "Second Life can't be installed while it is already running.$\n$\nFinish what you're doing then select OK to close Second Life and continue.$\nSelect CANCEL to cancel installation." IDOK CLOSE IDCANCEL CANCEL_INSTALL
|
||||
|
||||
CANCEL_INSTALL:
|
||||
Quit
|
||||
|
||||
CLOSE:
|
||||
DetailPrint "Waiting for Second Life to shut down..."
|
||||
SendMessage $0 16 0 0
|
||||
|
||||
LOOP:
|
||||
FindWindow $0 "Second Life" ""
|
||||
IntCmp $0 0 DONE
|
||||
Sleep 500
|
||||
Goto LOOP
|
||||
|
||||
DONE:
|
||||
Pop $0
|
||||
Return
|
||||
FunctionEnd
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Delete files in Documents and Settings\<user>\SecondLife\cache
|
||||
; Delete files in Documents and Settings\All Users\SecondLife\cache
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function RemoveCacheFiles
|
||||
|
||||
; Delete files in Documents and Settings\<user>\SecondLife
|
||||
Push $0
|
||||
Push $1
|
||||
Push $2
|
||||
DetailPrint "Deleting cache files in Documents and Settings folder"
|
||||
|
||||
StrCpy $0 0 ; Index number used to iterate via EnumRegKey
|
||||
|
||||
LOOP:
|
||||
EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
|
||||
StrCmp $1 "" DONE ; no more users
|
||||
|
||||
ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
|
||||
StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing
|
||||
|
||||
; Required since ProfileImagePath is of type REG_EXPAND_SZ
|
||||
ExpandEnvStrings $2 $2
|
||||
|
||||
; When explicitly uninstalling, everything goes away
|
||||
RMDir /r "$2\Application Data\SecondLife\cache"
|
||||
|
||||
CONTINUE:
|
||||
IntOp $0 $0 + 1
|
||||
Goto LOOP
|
||||
DONE:
|
||||
Pop $2
|
||||
Pop $1
|
||||
Pop $0
|
||||
|
||||
; Delete files in Documents and Settings\All Users\SecondLife
|
||||
Push $0
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
|
||||
StrCmp $0 "" +2
|
||||
RMDir /r "$0\SecondLife\cache"
|
||||
Pop $0
|
||||
|
||||
; Delete filse in C:\Windows\Application Data\SecondLife
|
||||
; If the user is running on a pre-NT system, Application Data lives here instead of
|
||||
; in Documents and Settings.
|
||||
RMDir /r "$WINDIR\Application Data\SecondLife\cache"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Delete files in Documents and Settings\<user>\SecondLife
|
||||
; Delete files in Documents and Settings\All Users\SecondLife
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function un.DocumentsAndSettingsFolder
|
||||
|
||||
; Delete files in Documents and Settings\<user>\SecondLife
|
||||
Push $0
|
||||
Push $1
|
||||
Push $2
|
||||
|
||||
DetailPrint "Deleting files in Documents and Settings folder"
|
||||
|
||||
StrCpy $0 0 ; Index number used to iterate via EnumRegKey
|
||||
|
||||
LOOP:
|
||||
EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
|
||||
StrCmp $1 "" DONE ; no more users
|
||||
|
||||
ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
|
||||
StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing
|
||||
|
||||
; Required since ProfileImagePath is of type REG_EXPAND_SZ
|
||||
ExpandEnvStrings $2 $2
|
||||
|
||||
; If uninstalling a normal install remove everything
|
||||
; Otherwise (preview/dmz etc) just remove cache
|
||||
StrCmp $INSTFLAGS "" RM_ALL RM_CACHE
|
||||
RM_ALL:
|
||||
RMDir /r "$2\Application Data\SecondLife"
|
||||
GoTo CONTINUE
|
||||
RM_CACHE:
|
||||
RMDir /r "$2\Application Data\SecondLife\Cache"
|
||||
|
||||
CONTINUE:
|
||||
IntOp $0 $0 + 1
|
||||
Goto LOOP
|
||||
DONE:
|
||||
|
||||
Pop $2
|
||||
Pop $1
|
||||
Pop $0
|
||||
|
||||
; Delete files in Documents and Settings\All Users\SecondLife
|
||||
Push $0
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
|
||||
StrCmp $0 "" +2
|
||||
RMDir /r "$0\SecondLife"
|
||||
Pop $0
|
||||
|
||||
; Delete filse in C:\Windows\Application Data\SecondLife
|
||||
; If the user is running on a pre-NT system, Application Data lives here instead of
|
||||
; in Documents and Settings.
|
||||
RMDir /r "$WINDIR\Application Data\SecondLife"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Close the program, if running. Modifies no variables.
|
||||
; Allows user to bail out of uninstall process.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function un.CloseSecondLife
|
||||
Push $0
|
||||
FindWindow $0 "Second Life" ""
|
||||
IntCmp $0 0 DONE
|
||||
MessageBox MB_OKCANCEL "Second Life can't be uninstalled while it is already running.$\n$\nFinish what you're doing then select OK to close Second Life and continue.$\nSelect CANCEL to cancel installation." IDOK CLOSE IDCANCEL CANCEL_UNINSTALL
|
||||
|
||||
CANCEL_UNINSTALL:
|
||||
Quit
|
||||
|
||||
CLOSE:
|
||||
DetailPrint "Waiting for Second Life to shut down..."
|
||||
SendMessage $0 16 0 0
|
||||
|
||||
LOOP:
|
||||
FindWindow $0 "Second Life" ""
|
||||
IntCmp $0 0 DONE
|
||||
Sleep 500
|
||||
Goto LOOP
|
||||
|
||||
DONE:
|
||||
Pop $0
|
||||
Return
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Delete the installed files
|
||||
;;; This deletes the uninstall executable, but it works
|
||||
;;; because it is copied to temp directory before running
|
||||
;;;
|
||||
;;; Note: You must list all files here, because we only
|
||||
;;; want to delete our files, not things users left in the
|
||||
;;; application directories.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function un.ProgramFiles
|
||||
|
||||
;; Remove mozilla file first so recursive directory deletion doesn't get hung up
|
||||
Delete "$INSTDIR\app_settings\mozilla\components"
|
||||
|
||||
;; This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py
|
||||
%%DELETE_FILES%%
|
||||
|
||||
;; Optional/obsolete files. Delete won't fail if they don't exist.
|
||||
Delete "$INSTDIR\dronesettings.ini"
|
||||
Delete "$INSTDIR\message_template.msg"
|
||||
Delete "$INSTDIR\newview.pdb"
|
||||
Delete "$INSTDIR\newview.map"
|
||||
Delete "$INSTDIR\SecondLife.pdb"
|
||||
Delete "$INSTDIR\SecondLife.map"
|
||||
Delete "$INSTDIR\comm.dat"
|
||||
Delete "$INSTDIR\*.glsl"
|
||||
Delete "$INSTDIR\motions\*.lla"
|
||||
Delete "$INSTDIR\trial\*.html"
|
||||
Delete "$INSTDIR\newview.exe"
|
||||
;; Remove entire help directory
|
||||
Delete "$INSTDIR\help\Advanced\*"
|
||||
RMDir "$INSTDIR\help\Advanced"
|
||||
Delete "$INSTDIR\help\basics\*"
|
||||
RMDir "$INSTDIR\help\basics"
|
||||
Delete "$INSTDIR\help\Concepts\*"
|
||||
RMDir "$INSTDIR\help\Concepts"
|
||||
Delete "$INSTDIR\help\welcome\*"
|
||||
RMDir "$INSTDIR\help\welcome"
|
||||
Delete "$INSTDIR\help\*"
|
||||
RMDir "$INSTDIR\help"
|
||||
|
||||
Delete "$INSTDIR\uninst.exe"
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER
|
||||
|
||||
FOLDERFOUND:
|
||||
MessageBox MB_YESNO "There are still files in your SecondLife program directory.$\n$\nThese are possibly files you created or moved to:$\n$INSTDIR$\n$\nDo you want to remove them?" IDNO NOFOLDER
|
||||
RMDir /r "$INSTDIR"
|
||||
|
||||
NOFOLDER:
|
||||
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Uninstall settings
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
UninstallText "This will uninstall Second Life ${VERSION_LONG} from your system."
|
||||
ShowUninstDetails show
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Uninstall section
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Section Uninstall
|
||||
|
||||
; Start with some default values.
|
||||
StrCpy $INSTFLAGS "${FARMFLAG}"
|
||||
StrCpy $INSTPROG "${INSTNAME}"
|
||||
StrCpy $INSTEXE "${INSTEXE}"
|
||||
StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
||||
Call un.CheckStartupParams ; Figure out where, what and how to uninstall.
|
||||
Call un.CheckIfAdministrator ; Make sure the user can install/uninstall
|
||||
|
||||
; uninstall for all users (if you change this, change it in the install as well)
|
||||
SetShellVarContext all
|
||||
|
||||
; Make sure we're not running
|
||||
Call un.CloseSecondLife
|
||||
|
||||
; Clean up registry keys
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG"
|
||||
|
||||
; Clean up shortcuts
|
||||
Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*"
|
||||
RMDir "$SMPROGRAMS\$INSTSHORTCUT"
|
||||
|
||||
Delete "$DESKTOP\$INSTSHORTCUT.lnk"
|
||||
Delete "$INSTDIR\$INSTSHORTCUT.lnk"
|
||||
Delete "$INSTDIR\Uninstall $INSTSHORTCUT.lnk"
|
||||
|
||||
; Clean up cache and log files.
|
||||
; Leave them in-place for non AGNI installs.
|
||||
|
||||
!ifdef UNINSTALL_SETTINGS
|
||||
Call un.DocumentsAndSettingsFolder
|
||||
!endif
|
||||
|
||||
Call un.ProgramFiles
|
||||
|
||||
SectionEnd ; end of uninstall section
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (From the NSIS wiki, DK)
|
||||
; GetParameterValue
|
||||
;
|
||||
; Usage:
|
||||
; !insertmacro GetParameterValue "/L=" "1033"
|
||||
; pop $R0
|
||||
;
|
||||
; Returns on top of stack
|
||||
;
|
||||
; Example command lines:
|
||||
; foo.exe /S /L=1033 /D=C:\Program Files\Foo
|
||||
; or:
|
||||
; foo.exe /S "/L=1033" /D="C:\Program Files\Foo"
|
||||
; gpv "/L=" "1033"
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
!macro GetParameterValue SWITCH DEFAULT
|
||||
Push $0
|
||||
Push $1
|
||||
Push $2
|
||||
Push $3
|
||||
Push $4
|
||||
|
||||
;$CMDLINE='"My Setup\Setup.exe" /L=1033 /S'
|
||||
Push "$CMDLINE"
|
||||
Push '${SWITCH}"'
|
||||
!insertmacro StrStr
|
||||
Pop $0
|
||||
StrCmp "$0" "" gpv_notquoted
|
||||
;$0='/L="1033" /S'
|
||||
StrLen $2 "$0"
|
||||
Strlen $1 "${SWITCH}"
|
||||
IntOp $1 $1 + 1
|
||||
StrCpy $0 "$0" $2 $1
|
||||
;$0='1033" /S'
|
||||
Push "$0"
|
||||
Push '"'
|
||||
!insertmacro StrStr
|
||||
Pop $1
|
||||
StrLen $2 "$0"
|
||||
StrLen $3 "$1"
|
||||
IntOp $4 $2 - $3
|
||||
StrCpy $0 $0 $4 0
|
||||
Goto gpv_done
|
||||
|
||||
gpv_notquoted:
|
||||
Push "$CMDLINE"
|
||||
Push "${SWITCH}"
|
||||
!insertmacro StrStr
|
||||
Pop $0
|
||||
StrCmp "$0" "" gpv_done
|
||||
;$0='/L="1033" /S'
|
||||
StrLen $2 "$0"
|
||||
Strlen $1 "${SWITCH}"
|
||||
StrCpy $0 "$0" $2 $1
|
||||
;$0=1033 /S'
|
||||
Push "$0"
|
||||
Push ' '
|
||||
!insertmacro StrStr
|
||||
Pop $1
|
||||
StrLen $2 "$0"
|
||||
StrLen $3 "$1"
|
||||
IntOp $4 $2 - $3
|
||||
StrCpy $0 $0 $4 0
|
||||
Goto gpv_done
|
||||
|
||||
gpv_done:
|
||||
StrCmp "$0" "" 0 +2
|
||||
StrCpy $0 "${DEFAULT}"
|
||||
|
||||
Pop $4
|
||||
Pop $3
|
||||
Pop $2
|
||||
Pop $1
|
||||
Exch $0
|
||||
!macroend
|
||||
|
||||
; And I had to modify StrStr a tiny bit.
|
||||
; Possible upgrade switch the goto's to use ${__LINE__}
|
||||
|
||||
!macro STRSTR
|
||||
Exch $R1 ; st=haystack,old$R1, $R1=needle
|
||||
Exch ; st=old$R1,haystack
|
||||
Exch $R2 ; st=old$R1,old$R2, $R2=haystack
|
||||
Push $R3
|
||||
Push $R4
|
||||
Push $R5
|
||||
StrLen $R3 $R1
|
||||
StrCpy $R4 0
|
||||
; $R1=needle
|
||||
; $R2=haystack
|
||||
; $R3=len(needle)
|
||||
; $R4=cnt
|
||||
; $R5=tmp
|
||||
; loop;
|
||||
StrCpy $R5 $R2 $R3 $R4
|
||||
StrCmp $R5 $R1 +4
|
||||
StrCmp $R5 "" +3
|
||||
IntOp $R4 $R4 + 1
|
||||
Goto -4
|
||||
; done;
|
||||
StrCpy $R1 $R2 "" $R4
|
||||
Pop $R5
|
||||
Pop $R4
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
Exch $R1
|
||||
!macroend
|
||||
|
||||
Function GetProgramName
|
||||
!insertmacro GetParameterValue "/P=" "SecondLife"
|
||||
FunctionEnd
|
||||
|
||||
Function un.GetProgramName
|
||||
!insertmacro GetParameterValue "/P=" "SecondLife"
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (From the NSIS documentation, JC)
|
||||
; GetWindowsVersion
|
||||
;
|
||||
; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
|
||||
; Updated by Joost Verburg
|
||||
;
|
||||
; Returns on top of stack
|
||||
;
|
||||
; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003)
|
||||
; or
|
||||
; '' (Unknown Windows Version)
|
||||
;
|
||||
; Usage:
|
||||
; Call GetWindowsVersion
|
||||
; Pop $R0
|
||||
; ; at this point $R0 is "NT 4.0" or whatnot
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
Function GetWindowsVersion
|
||||
|
||||
Push $R0
|
||||
Push $R1
|
||||
|
||||
ReadRegStr $R0 HKLM \
|
||||
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
|
||||
|
||||
IfErrors 0 lbl_winnt
|
||||
|
||||
; we are not NT
|
||||
ReadRegStr $R0 HKLM \
|
||||
"SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber
|
||||
|
||||
StrCpy $R1 $R0 1
|
||||
StrCmp $R1 '4' 0 lbl_error
|
||||
|
||||
StrCpy $R1 $R0 3
|
||||
|
||||
StrCmp $R1 '4.0' lbl_win32_95
|
||||
StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98
|
||||
|
||||
lbl_win32_95:
|
||||
StrCpy $R0 '95'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_win32_98:
|
||||
StrCpy $R0 '98'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_win32_ME:
|
||||
StrCpy $R0 'ME'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_winnt:
|
||||
|
||||
StrCpy $R1 $R0 1
|
||||
|
||||
StrCmp $R1 '3' lbl_winnt_x
|
||||
StrCmp $R1 '4' lbl_winnt_x
|
||||
|
||||
StrCpy $R1 $R0 3
|
||||
|
||||
StrCmp $R1 '5.0' lbl_winnt_2000
|
||||
StrCmp $R1 '5.1' lbl_winnt_XP
|
||||
StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error
|
||||
|
||||
lbl_winnt_x:
|
||||
StrCpy $R0 "NT $R0" 6
|
||||
Goto lbl_done
|
||||
|
||||
lbl_winnt_2000:
|
||||
Strcpy $R0 '2000'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_winnt_XP:
|
||||
Strcpy $R0 'XP'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_winnt_2003:
|
||||
Strcpy $R0 '2003'
|
||||
Goto lbl_done
|
||||
|
||||
lbl_error:
|
||||
Strcpy $R0 ''
|
||||
lbl_done:
|
||||
|
||||
Pop $R1
|
||||
Exch $R0
|
||||
|
||||
FunctionEnd
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
#!/usr/bin/python
|
||||
# @file viewer_manifest.py
|
||||
# @author Ryan Williams
|
||||
# @brief Description of all installer viewer files, and methods for packaging
|
||||
# them into installers for all supported platforms.
|
||||
#
|
||||
# Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
|
||||
# $License$
|
||||
import sys
|
||||
import os.path
|
||||
import re
|
||||
import tarfile
|
||||
viewer_dir = os.path.dirname(__file__)
|
||||
# add llmanifest library to our path so you don't have to muck with PYTHONPATH
|
||||
sys.path.append(os.path.join(viewer_dir, '../lib/python/indra'))
|
||||
from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
|
||||
|
||||
class ViewerManifest(LLManifest):
|
||||
def construct(self):
|
||||
super(ViewerManifest, self).construct()
|
||||
self.exclude("*.svn*")
|
||||
self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
|
||||
|
||||
if self.prefix(src="app_settings"):
|
||||
self.exclude("logcontrol.xml")
|
||||
self.exclude("logcontrol-dev.xml")
|
||||
self.path("*.pem")
|
||||
self.path("*.ini")
|
||||
self.path("*.xml")
|
||||
self.path("*.vp")
|
||||
self.path("*.db2")
|
||||
|
||||
# include the entire shaders directory recursively
|
||||
self.path("shaders")
|
||||
self.end_prefix("app_settings")
|
||||
|
||||
if self.prefix(src="character"):
|
||||
self.path("*.llm")
|
||||
self.path("*.xml")
|
||||
self.path("*.tga")
|
||||
self.end_prefix("character")
|
||||
|
||||
|
||||
# Include our fonts
|
||||
if self.prefix(src="fonts"):
|
||||
self.path("*.ttf")
|
||||
self.path("*.txt")
|
||||
self.end_prefix("fonts")
|
||||
|
||||
# XUI
|
||||
if self.prefix(src="skins"):
|
||||
self.path("paths.xml")
|
||||
self.path("xui/*/*.xml")
|
||||
self.path('words.*.txt')
|
||||
|
||||
# Local HTML files (e.g. loading screen)
|
||||
if self.prefix("html/*"):
|
||||
self.path("*.html")
|
||||
self.path("*.gif")
|
||||
self.path("*.jpg")
|
||||
self.path("*.css")
|
||||
self.end_prefix("html/*")
|
||||
self.end_prefix("skins")
|
||||
|
||||
self.path("featuretable.txt")
|
||||
self.path("releasenotes.txt")
|
||||
self.path("lsl_guide.html")
|
||||
self.path("gpu_table.txt")
|
||||
|
||||
def flags_list(self):
|
||||
""" Convenience function that returns the command-line flags for the grid"""
|
||||
if(self.args['grid'] == ''):
|
||||
return ""
|
||||
elif(self.args['grid'] == 'firstlook'):
|
||||
return '-settings settings_firstlook.xml'
|
||||
else:
|
||||
return ("-settings settings_beta.xml --%(grid)s -helperuri http://preview-%(grid)s.secondlife.com/helpers/" % {'grid':self.args['grid']})
|
||||
|
||||
def login_url(self):
|
||||
""" Convenience function that returns the appropriate login url for the grid"""
|
||||
if(self.args.get('login_url')):
|
||||
return self.args['login_url']
|
||||
else:
|
||||
if(self.args['grid'] == ''):
|
||||
return 'http://secondlife.com/app/login/'
|
||||
elif(self.args['grid'] == 'firstlook'):
|
||||
return 'http://secondlife.com/app/login/firstlook/'
|
||||
else:
|
||||
return 'http://secondlife.com/app/login/beta/'
|
||||
|
||||
def replace_login_url(self):
|
||||
# set the login page to point to a url appropriate for the type of client
|
||||
self.replace_in("skins/xui/en-us/panel_login.xml", searchdict={'http://secondlife.com/app/login/':self.login_url()})
|
||||
|
||||
def create_unpacked(self):
|
||||
unpacked_file_name = "unpacked_%(plat)s_%(vers)s.tar" % {
|
||||
'plat':self.args['platform'],
|
||||
'vers':'_'.join(self.args['version'])}
|
||||
print "Creating unpacked file:", unpacked_file_name
|
||||
# could add a gz here but that doubles the time it takes to do this step
|
||||
tf = tarfile.open(self.src_path_of(unpacked_file_name), 'w:')
|
||||
# add the entire installation package, at the very top level
|
||||
tf.add(self.get_dst_prefix(), "")
|
||||
tf.close()
|
||||
|
||||
class WindowsManifest(ViewerManifest):
|
||||
def final_exe(self):
|
||||
# *NOTE: these are the only two executable names that the crash reporter recognizes
|
||||
if self.args['grid'] == '':
|
||||
return "SecondLife.exe"
|
||||
else:
|
||||
return "SecondLifePreview.exe"
|
||||
# return "SecondLifePreview%s.exe" % (self.args['grid'], )
|
||||
|
||||
def construct(self):
|
||||
super(WindowsManifest, self).construct()
|
||||
# the final exe is complicated because we're not sure where it's coming from,
|
||||
# nor do we have a fixed name for the executable
|
||||
self.path(self.find_existing_file('ReleaseForDownload/Secondlife.exe', 'Secondlife.exe', 'ReleaseNoOpt/newview_noopt.exe'), dst=self.final_exe())
|
||||
# need to get the kdu dll from any of the build directories as well
|
||||
self.path(self.find_existing_file('ReleaseForDownload/llkdu.dll', 'llkdu.dll', '../../libraries/i686-win32/lib_release/llkdu.dll'), dst='llkdu.dll')
|
||||
self.path(src="licenses-win32.txt", dst="licenses.txt")
|
||||
|
||||
# For use in crash reporting (generates minidumps)
|
||||
self.path("dbghelp.dll")
|
||||
|
||||
# For using FMOD for sound... DJS
|
||||
self.path("fmod.dll")
|
||||
|
||||
# Mozilla appears to force a dependency on these files so we need to ship it (CP)
|
||||
self.path("msvcr71.dll")
|
||||
self.path("msvcp71.dll")
|
||||
|
||||
# Mozilla runtime DLLs (CP)
|
||||
if self.prefix(src="../../libraries/i686-win32/lib_release", dst=""):
|
||||
self.path("gksvggdiplus.dll")
|
||||
self.path("js3250.dll")
|
||||
self.path("nspr4.dll")
|
||||
self.path("nss3.dll")
|
||||
self.path("nssckbi.dll")
|
||||
self.path("plc4.dll")
|
||||
self.path("plds4.dll")
|
||||
self.path("smime3.dll")
|
||||
self.path("softokn3.dll")
|
||||
self.path("ssl3.dll")
|
||||
self.path("xpcom.dll")
|
||||
self.path("xul.dll")
|
||||
self.end_prefix()
|
||||
|
||||
# Mozilla runtime misc files (CP)
|
||||
if self.prefix(src="app_settings/mozilla"):
|
||||
self.path("chrome/*.*")
|
||||
self.path("components/*.*")
|
||||
self.path("greprefs/*.*")
|
||||
self.path("plugins/*.*")
|
||||
self.path("res/*.*")
|
||||
self.path("res/*/*")
|
||||
self.end_prefix()
|
||||
|
||||
# pull in the crash logger and updater from other projects
|
||||
self.path(src="../win_crash_logger/win_crash_logger.exe", dst="win_crash_logger.exe")
|
||||
self.path(src="../win_updater/updater.exe", dst="updater.exe")
|
||||
self.replace_login_url()
|
||||
|
||||
def nsi_file_commands(self, install=True):
|
||||
def wpath(path):
|
||||
if(path.endswith('/') or path.endswith(os.path.sep)):
|
||||
path = path[:-1]
|
||||
path = path.replace('/', '\\')
|
||||
return path
|
||||
|
||||
result = ""
|
||||
dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])]
|
||||
# sort deepest hierarchy first
|
||||
dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
|
||||
dest_files.reverse()
|
||||
out_path = None
|
||||
for pkg_file in dest_files:
|
||||
rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
|
||||
installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
|
||||
pkg_file = wpath(os.path.normpath(pkg_file))
|
||||
if installed_dir != out_path:
|
||||
if(install):
|
||||
out_path = installed_dir
|
||||
result += 'SetOutPath ' + out_path + '\n'
|
||||
if(install):
|
||||
result += 'File ' + pkg_file + '\n'
|
||||
else:
|
||||
result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
|
||||
# at the end of a delete, just rmdir all the directories
|
||||
if(not install):
|
||||
deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
|
||||
# find all ancestors so that we don't skip any dirs that happened to have no non-dir children
|
||||
deleted_dirs = []
|
||||
for d in deleted_file_dirs:
|
||||
deleted_dirs.extend(path_ancestors(d))
|
||||
# sort deepest hierarchy first
|
||||
deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
|
||||
deleted_dirs.reverse()
|
||||
prev = None
|
||||
for d in deleted_dirs:
|
||||
if d != prev: # skip duplicates
|
||||
result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n'
|
||||
prev = d
|
||||
|
||||
return result
|
||||
|
||||
def package_finish(self):
|
||||
self.create_unpacked()
|
||||
version_vars_template = """
|
||||
!define INSTEXE "%(final_exe)s"
|
||||
!define VERSION "%(version_short)s"
|
||||
!define VERSION_LONG "%(version)s"
|
||||
!define VERSION_DASHES "%(version_dashes)s"
|
||||
"""
|
||||
if(self.args['grid'] == ''):
|
||||
installer_file = "Second Life %(version_dashes)s Setup.exe"
|
||||
grid_vars_template = """
|
||||
OutFile "%(outfile)s"
|
||||
!define INSTFLAGS "%(flags)s"
|
||||
!define INSTNAME "SecondLife"
|
||||
!define SHORTCUT "Second Life"
|
||||
!define URLNAME "secondlife"
|
||||
Caption "Second Life ${VERSION}"
|
||||
"""
|
||||
else:
|
||||
installer_file = "Second Life %(version_dashes)s (%(grid_caps)s) Setup.exe"
|
||||
grid_vars_template = """
|
||||
OutFile "%(outfile)s"
|
||||
!define INSTFLAGS "%(flags)s"
|
||||
!define INSTNAME "SecondLife%(grid_caps)s"
|
||||
!define SHORTCUT "Second Life (%(grid_caps)s)"
|
||||
!define URLNAME "secondlife%(grid)s"
|
||||
!define UNINSTALL_SETTINGS 1
|
||||
Caption "Second Life %(grid)s ${VERSION}"
|
||||
"""
|
||||
if(self.args.has_key('installer_name')):
|
||||
installer_file = self.args['installer_name']
|
||||
else:
|
||||
installer_file = installer_file % {'version_dashes' : '-'.join(self.args['version']),
|
||||
'grid_caps' : self.args['grid'].upper()}
|
||||
tempfile = "../secondlife_setup.nsi"
|
||||
# the following is an odd sort of double-string replacement
|
||||
self.replace_in("installers/windows/installer_template.nsi", tempfile, {
|
||||
"%%VERSION%%":version_vars_template%{'version_short' : '.'.join(self.args['version'][:-1]),
|
||||
'version' : '.'.join(self.args['version']),
|
||||
'version_dashes' : '-'.join(self.args['version']),
|
||||
'final_exe' : self.final_exe()},
|
||||
"%%GRID_VARS%%":grid_vars_template%{'grid':self.args['grid'],
|
||||
'grid_caps':self.args['grid'].upper(),
|
||||
'outfile':installer_file,
|
||||
'flags':self.flags_list()},
|
||||
"%%INSTALL_FILES%%":self.nsi_file_commands(True),
|
||||
"%%DELETE_FILES%%":self.nsi_file_commands(False)})
|
||||
|
||||
NSIS_path = 'C:\\Program Files\\NSIS\\makensis.exe'
|
||||
self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile))
|
||||
# self.remove(self.dst_path_of(tempfile))
|
||||
self.created_path(installer_file)
|
||||
|
||||
|
||||
class DarwinManifest(ViewerManifest):
|
||||
def construct(self):
|
||||
# copy over the build result (this is a no-op if run within the xcode script)
|
||||
self.path("build/" + self.args['configuration'] + "/Second Life.app", dst="")
|
||||
|
||||
if self.prefix(src="", dst="Contents"): # everything goes in Contents
|
||||
# Expand the tar file containing the assorted mozilla bits into
|
||||
# <bundle>/Contents/MacOS/
|
||||
self.contents_of_tar('mozilla-universal-darwin.tgz', 'MacOS')
|
||||
# self.run_command('tar -zx -C "%(macos)s" -f "%(tarfile)s"' %
|
||||
# {'macos':self.ensure_dst_dir("MacOS"),
|
||||
# 'tarfile':self.src_path_of("mozilla-universal-darwin.tgz")})
|
||||
|
||||
# replace the default theme with our custom theme (so scrollbars work).
|
||||
if self.prefix(src="mozilla-theme", dst="MacOS/chrome"):
|
||||
self.path("classic.jar")
|
||||
self.path("classic.manifest")
|
||||
self.end_prefix("MacOS/chrome")
|
||||
|
||||
# most everything goes in the Resources directory
|
||||
if self.prefix(src="", dst="Resources"):
|
||||
super(DarwinManifest, self).construct()
|
||||
|
||||
# the trial directory seems to be not used [rdw]
|
||||
self.path('trial')
|
||||
|
||||
if self.prefix("cursors_mac"):
|
||||
self.path("*.tif")
|
||||
self.end_prefix("cursors_mac")
|
||||
|
||||
self.path("licenses-mac.txt", dst="licenses.txt")
|
||||
self.path("featuretable_mac.txt")
|
||||
self.path("secondlife.icns")
|
||||
|
||||
# llkdu dynamic library
|
||||
self.path("../../libraries/universal-darwin/lib_release/libllkdu.dylib", "libllkdu.dylib")
|
||||
|
||||
# command line arguments for connecting to the proper grid
|
||||
self.put_in_file(self.flags_list(), 'arguments.txt')
|
||||
|
||||
# set the proper login url
|
||||
self.replace_login_url()
|
||||
|
||||
self.end_prefix("Resources")
|
||||
|
||||
self.end_prefix("Contents")
|
||||
|
||||
|
||||
def package_finish(self):
|
||||
# NOTE: the -S argument to strip causes it to keep enough info for
|
||||
# annotated backtraces (i.e. function names in the crash log). 'strip' with no
|
||||
# arguments yields a slightly smaller binary but makes crash logs mostly useless.
|
||||
# This may be desirable for the final release. Or not.
|
||||
self.run_command('strip -S "%(viewer_binary)s"' %
|
||||
{ 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
|
||||
|
||||
self.create_unpacked()
|
||||
|
||||
imagename="SecondLife_" + '_'.join(self.args['version'])
|
||||
if(self.args['grid'] != ''):
|
||||
imagename = imagename + '_' + self.args['grid']
|
||||
|
||||
sparsename = imagename + ".sparseimage"
|
||||
finalname = imagename + ".dmg"
|
||||
# make sure we don't have stale files laying about
|
||||
self.remove(sparsename, finalname)
|
||||
|
||||
self.run_command('hdiutil create "%(sparse)s" -volname "Second Life" -fs HFS+ -type SPARSE -megabytes 200' % {'sparse':sparsename})
|
||||
|
||||
# mount the image and get the name of the mount point and device node
|
||||
hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
|
||||
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
|
||||
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
|
||||
|
||||
# Copy everything in to the mounted .dmg
|
||||
for s,d in {self.get_dst_prefix():("Second Life " + self.args['grid']).strip()+ ".app",
|
||||
"lsl_guide.html":"Linden Scripting Language Guide.html",
|
||||
"releasenotes.txt":"Release Notes.txt",
|
||||
"installers/darwin/mac_image_hidden":".hidden",
|
||||
"installers/darwin/mac_image_background.tga":"background.tga",
|
||||
"installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
|
||||
print "Copying to dmg", s, d
|
||||
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
|
||||
|
||||
# Unmount the image
|
||||
self.run_command('hdiutil detach "' + devfile + '"')
|
||||
|
||||
print "Converting temp disk image to final disk image"
|
||||
self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
|
||||
# get rid of the temp file
|
||||
self.remove(sparsename)
|
||||
|
||||
class LinuxManifest(ViewerManifest):
|
||||
def construct(self):
|
||||
super(LinuxManifest, self).construct()
|
||||
self.path("licenses-linux.txt","licenses.txt")
|
||||
self.path("res/ll_icon.ico","secondlife.ico")
|
||||
if self.prefix("linux_tools", ""):
|
||||
self.path("client-readme.txt","README-linux.txt")
|
||||
self.path("wrapper.sh","secondlife")
|
||||
self.path("unicode.ttf","unicode.ttf")
|
||||
self.end_prefix("linux_tools")
|
||||
|
||||
# Create an appropriate gridargs.dat for this package, denoting required grid.
|
||||
self.put_in_file(self.flags_list(), 'gridargs.dat')
|
||||
# set proper login url
|
||||
self.replace_login_url()
|
||||
|
||||
def package_finish(self):
|
||||
if(self.args.has_key('installer_name')):
|
||||
installer_name = self.args['installer_name']
|
||||
else:
|
||||
installer_name = '_'.join('SecondLife_', self.args.get('arch'), *self.args['version'])
|
||||
if grid != '':
|
||||
installer_name += "_" + grid.upper()
|
||||
|
||||
# stripping all the libs removes a few megabytes from the end-user package
|
||||
for s,d in self.file_list:
|
||||
if re.search("lib/lib.+\.so.*", d):
|
||||
self.run_command('strip -S %s' % d)
|
||||
self.create_unpacked()
|
||||
# temporarily move directory tree so that it has the right name in the tarfile
|
||||
self.run_command("mv %(dst)s %(inst)s" % {'dst':self.get_dst_prefix(),'inst':self.src_path_of(installer_name)})
|
||||
# --numeric-owner hides the username of the builder for security etc.
|
||||
self.run_command('tar -C %(dir)s --numeric-owner -cjf %(inst_path)s.tar.bz2 %(inst_name)s' % {'dir':self.get_src_prefix(), 'inst_name': installer_name, 'inst_path':self.src_path_of(installer_name)})
|
||||
self.run_command("mv %(inst)s %(dst)s" % {'dst':self.get_dst_prefix(),'inst':self.src_path_of(installer_name)})
|
||||
|
||||
class Linux_i686Manifest(LinuxManifest):
|
||||
def construct(self):
|
||||
super(Linux_i686Manifest, self).construct()
|
||||
self.path("secondlife-i686-bin-stripped","bin/do-not-directly-run-secondlife-bin")
|
||||
self.path("../linux_crash_logger/linux-crash-logger-i686-bin-stripped","linux-crash-logger.bin")
|
||||
self.path("linux_tools/launch_url.sh","launch_url.sh")
|
||||
if self.prefix("res-sdl"):
|
||||
self.path("*")
|
||||
# recurse
|
||||
self.end_prefix("res-sdl")
|
||||
|
||||
self.path("app_settings/mozilla-runtime-linux-i686", "app_settings/mozilla")
|
||||
|
||||
if self.prefix("../../libraries/i686-linux/lib_release_client", "lib"):
|
||||
self.path("libkdu_v42R.so")
|
||||
self.path("libfmod-3.75.so")
|
||||
self.path("libapr-1.so.0")
|
||||
self.path("libaprutil-1.so.0")
|
||||
self.path("libdb-4.2.so")
|
||||
self.path("libogg.so.0")
|
||||
self.path("libvorbis.so.0")
|
||||
self.path("libvorbisfile.so.0")
|
||||
self.path("libvorbisenc.so.0")
|
||||
self.path("libcurl.so.3")
|
||||
self.path("libcrypto.so.0.9.7")
|
||||
self.path("libssl.so.0.9.7")
|
||||
self.path("libexpat.so.1")
|
||||
self.path("libstdc++.so.6")
|
||||
self.path("libelfio.so")
|
||||
self.path("libuuid.so", "libuuid.so.1")
|
||||
self.path("libSDL-1.2.so.0")
|
||||
self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason
|
||||
self.end_prefix("lib")
|
||||
|
||||
|
||||
class Linux_x86_64Manifest(LinuxManifest):
|
||||
def construct(self):
|
||||
super(Linux_x86_64Manifest, self).construct()
|
||||
self.path("secondlife-x86_64-bin-stripped","bin/secondlife-bin")
|
||||
# TODO: I get the sense that this isn't fully fleshed out
|
||||
if self.prefix("../../libraries/x86_64-linux/lib_release_client", "lib"):
|
||||
self.path("libkdu_v42R.so")
|
||||
self.path("libxmlrpc.so.0")
|
||||
# self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason
|
||||
self.end_prefix("lib")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(srctree=viewer_dir, dsttree=os.path.join(viewer_dir, "packaged"))
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/python
|
||||
# @file test_llmanifest.py
|
||||
# @author Ryan Williams
|
||||
# @brief Test cases for LLManifest library.
|
||||
#
|
||||
# Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
|
||||
# $License$
|
||||
|
||||
from indra import llmanifest
|
||||
import os.path
|
||||
import os
|
||||
import unittest
|
||||
|
||||
class DemoManifest(llmanifest.LLManifest):
|
||||
def construct(self):
|
||||
super(DemoManifest, self).construct()
|
||||
if self.prefix("dir_1"):
|
||||
self.path("test_a")
|
||||
self.path(src="test_b", dst="test_dst_b")
|
||||
self.path("*.test")
|
||||
self.path("*.tex", "*.jpg")
|
||||
if self.prefix("nested", dst=""):
|
||||
self.path("deep")
|
||||
self.end_prefix()
|
||||
self.end_prefix("dir_1")
|
||||
|
||||
|
||||
class Demo_ArchManifest(llmanifest.LLManifest):
|
||||
pass
|
||||
|
||||
class TestLLManifest(unittest.TestCase):
|
||||
mode='static'
|
||||
def setUp(self):
|
||||
self.m = llmanifest.LLManifest("src", "dst", {'grid':'default', 'platform':'darwin', 'version':(1,2,3,4)})
|
||||
|
||||
def testproperwindowspath(self):
|
||||
self.assertEqual(llmanifest.proper_windows_path("C:\Program Files", "cygwin"),"/cygdrive/c/Program Files")
|
||||
self.assertEqual(llmanifest.proper_windows_path("C:\Program Files", "windows"), "C:\Program Files")
|
||||
self.assertEqual(llmanifest.proper_windows_path("/cygdrive/c/Program Files/NSIS", "windows"), "C:\Program Files\NSIS")
|
||||
self.assertEqual(llmanifest.proper_windows_path("/cygdrive/c/Program Files/NSIS", "cygwin"), "/cygdrive/c/Program Files/NSIS")
|
||||
|
||||
def testpathancestors(self):
|
||||
self.assertEqual(["dir"], [p for p in llmanifest.path_ancestors("dir")])
|
||||
self.assertEqual(["dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub")])
|
||||
self.assertEqual(["dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub/")])
|
||||
self.assertEqual(["dir/sub/two", "dir/sub", "dir"], [p for p in llmanifest.path_ancestors("dir/sub/two")])
|
||||
|
||||
|
||||
def testforplatform(self):
|
||||
self.assertEqual(llmanifest.LLManifest.for_platform('demo'), DemoManifest)
|
||||
def tmp_test():
|
||||
return llmanifest.LLManifest.for_platform('extant')
|
||||
self.assertRaises(KeyError, tmp_test)
|
||||
ExtantManifest = llmanifest.LLManifestRegistry('ExtantManifest', (llmanifest.LLManifest,), {})
|
||||
self.assertEqual(llmanifest.LLManifest.for_platform('extant'), ExtantManifest)
|
||||
self.assertEqual(llmanifest.LLManifest.for_platform('demo', 'Arch'), Demo_ArchManifest)
|
||||
|
||||
|
||||
def testprefix(self):
|
||||
self.assertEqual(self.m.get_src_prefix(), "src")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst")
|
||||
self.m.prefix("level1")
|
||||
self.assertEqual(self.m.get_src_prefix(), "src/level1")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst/level1")
|
||||
self.m.end_prefix()
|
||||
self.m.prefix(src="src", dst="dst")
|
||||
self.assertEqual(self.m.get_src_prefix(), "src/src")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst/dst")
|
||||
self.m.end_prefix()
|
||||
|
||||
def testendprefix(self):
|
||||
self.assertEqual(self.m.get_src_prefix(), "src")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst")
|
||||
self.m.prefix("levela")
|
||||
self.m.end_prefix()
|
||||
self.assertEqual(self.m.get_src_prefix(), "src")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst")
|
||||
self.m.prefix("level1")
|
||||
self.m.end_prefix("level1")
|
||||
self.assertEqual(self.m.get_src_prefix(), "src")
|
||||
self.assertEqual(self.m.get_dst_prefix(), "dst")
|
||||
self.m.prefix("level1")
|
||||
def tmp_test():
|
||||
self.m.end_prefix("mismatch")
|
||||
self.assertRaises(ValueError, tmp_test)
|
||||
|
||||
def testruncommand(self):
|
||||
self.assertEqual("Hello\n", self.m.run_command("echo Hello"))
|
||||
def tmp_test():
|
||||
self.m.run_command("fff_garbage")
|
||||
self.assertRaises(RuntimeError, tmp_test)
|
||||
|
||||
def testpathof(self):
|
||||
self.assertEqual(self.m.src_path_of("a"), "src/a")
|
||||
self.assertEqual(self.m.dst_path_of("a"), "dst/a")
|
||||
self.m.prefix("tmp")
|
||||
self.assertEqual(self.m.src_path_of("b/c"), "src/tmp/b/c")
|
||||
self.assertEqual(self.m.dst_path_of("b/c"), "dst/tmp/b/c")
|
||||
|
||||
def testcmakedirs(self):
|
||||
self.m.cmakedirs("test_dir_DELETE/nested/dir")
|
||||
self.assert_(os.path.exists("test_dir_DELETE/nested/dir"))
|
||||
self.assert_(os.path.isdir("test_dir_DELETE"))
|
||||
self.assert_(os.path.isdir("test_dir_DELETE/nested"))
|
||||
self.assert_(os.path.isdir("test_dir_DELETE/nested/dir"))
|
||||
os.removedirs("test_dir_DELETE/nested/dir")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue