pgadmin4/Make.bat

377 lines
16 KiB
Batchfile

@ECHO off
SETLOCAL
SET WD=%CD%
SET "BUILDROOT=%WD%\win-build"
SET "TMPDIR=%WD%\win-temp"
SET "DISTROOT=%WD%\dist"
SET CMDOPTIONS=""
IF "%1" == "clean" SET CMDOPTIONS="VALID"
IF "%1" == "" SET CMDOPTIONS="VALID"
IF NOT %CMDOPTIONS%=="VALID" (
GOTO USAGE
)
IF "%1" == "clean" (
CALL :CLEAN
EXIT /B %ERRORLEVEL%
)
REM Main build sequence
CALL :SET_ENVIRONMENT
CALL :VALIDATE_ENVIRONMENT || EXIT /B 1
CALL :CLEAN || EXIT /B 1
CALL :CREATE_VIRTUAL_ENV || EXIT /B 1
CALL :CREATE_PYTHON_ENV || EXIT /B 1
CALL :CREATE_RUNTIME_ENV || EXIT /B 1
CALL :CREATE_INSTALLER || EXIT /B 1
CALL :SIGN_INSTALLER || EXIT /B 1
EXIT /B %ERRORLEVEL%
REM Main build sequence Ends
:CLEAN
ECHO Removing build directory...
IF EXIST "%BUILDROOT%" RD "%BUILDROOT%" /S /Q > nul || EXIT /B 1
ECHO Removing tmp directory...
IF EXIST "%TMPDIR%" RD "%TMPDIR%" /S /Q > nul || EXIT /B 1
ECHO Removing installer build directory...
IF EXIST "%WD%\pkg\win32\Output" rd "%WD%\pkg\win32\Output" /S /Q > nul || EXIT /B 1
ECHO Removing installer configuration script...
IF EXIST DEL /q "%WD%\pkg\win32\installer.iss" > nul || EXIT /B 1
EXIT /B 0
:SET_ENVIRONMENT
ECHO Configuring the environment...
IF "%PGADMIN_PYTHON_DIR%" == "" SET "PGADMIN_PYTHON_DIR=C:\Python38"
IF "%PGADMIN_KRB5_DIR%" == "" SET "PGADMIN_KRB5_DIR=C:\Program Files\MIT\Kerberos"
IF "%PGADMIN_POSTGRES_DIR%" == "" SET "PGADMIN_POSTGRES_DIR=C:\Program Files (x86)\PostgreSQL\12"
IF "%PGADMIN_INNOTOOL_DIR%" == "" SET "PGADMIN_INNOTOOL_DIR=C:\Program Files (x86)\Inno Setup 6"
IF "%PGADMIN_VCREDIST_DIR%" == "" SET "PGADMIN_VCREDIST_DIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012"
IF "%PGADMIN_SIGNTOOL_DIR%" == "" SET "PGADMIN_SIGNTOOL_DIR=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64"
REM Set REDIST_NAME (the filename)
set "VCREDIST_FILE=vcredist_x64.exe"
REM Set additional variables we need
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_MAJOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_MINOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_VERSION_SUFFIX=%%a
REM remove single quote from the string
SET APP_VERSION_SUFFIX=%APP_VERSION_SUFFIX:'=%
SET APP_NAME=""
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
SET APP_VERSION=%APP_MAJOR%.%APP_MINOR%
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%APP_VERSION_SUFFIX%-x64.exe
IF "%APP_VERSION_SUFFIX%" == "" SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-x64.exe
REM get Python version for the runtime build ex. 3.9.2 will be 39
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
FOR /f "tokens=2 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MINOR=%%G
FOR /f "tokens=3 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_REVISION=%%G
EXIT /B 0
:VALIDATE_ENVIRONMENT
ECHO ****************************************************************
ECHO * Build summary
ECHO ****************************************************************
ECHO Build path: %BUILDROOT%
ECHO Output directory: %DISTROOT%
ECHO Installer name: %INSTALLERNAME%
ECHO.
ECHO Python directory: %PGADMIN_PYTHON_DIR%
ECHO Python version: %PYTHON_MAJOR%.%PYTHON_MINOR%.%PYTHON_REVISION%
ECHO.
ECHO KRB5 directory: %PGADMIN_KRB5_DIR%
ECHO PostgreSQL directory: %PGADMIN_POSTGRES_DIR%
ECHO.
ECHO VC++ redist directory: %PGADMIN_VCREDIST_DIR%
ECHO VC++ redist file: %VCREDIST_FILE%
ECHO InnoTool directory: %PGADMIN_INNOTOOL_DIR%
ECHO signtool directory: %PGADMIN_SIGNTOOL_DIR%
ECHO.
ECHO App version: %APP_VERSION%
ECHO App version suffix: %APP_VERSION_SUFFIX%
ECHO App short name: %APP_SHORTNAME%
ECHO App name: %APP_NAME%
ECHO ****************************************************************
ECHO Checking the environment...
IF NOT EXIST "%PGADMIN_INNOTOOL_DIR%" (
ECHO !PGADMIN_INNOTOOL_DIR! does not exist
ECHO Please install InnoTool and set the PGADMIN_INNOTOOL_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PGADMIN_VCREDIST_DIR%" (
ECHO !PGADMIN_VCREDIST_DIR! does not exist
ECHO Please install Microsoft Visual studio and set the PGADMIN_VCREDIST_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PGADMIN_KRB5_DIR%" (
ECHO !PGADMIN_KRB5_DIR! does not exist.
ECHO Please install MIT Kerberos for Windows and set the PGADMIN_KRB5_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PGADMIN_PYTHON_DIR%" (
ECHO !PGADMIN_PYTHON_DIR! does not exist.
ECHO Please install Python and set the PGADMIN_PYTHON_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PGADMIN_POSTGRES_DIR%" (
ECHO !PGADMIN_POSTGRES_DIR! does not exist.
ECHO Please install PostgreSQL and set the PGADMIN_POSTGRES_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PGADMIN_PYTHON_DIR%\Scripts\virtualenv.exe" (
ECHO !PGADMIN_PYTHON_DIR!\Scripts\virtualenv.exe does not exist.
ECHO Please install the virtualenv package in Python.
EXIT /B 1
)
SET "PATH=%PGADMIN_POSTGRES_DIR%\bin;%PATH%"
EXIT /B 0
:CREATE_VIRTUAL_ENV
ECHO Creating virtual environment...
IF NOT EXIST "%TMPDIR%" MKDIR "%TMPDIR%"
CD "%TMPDIR%"
REM Note that we must use virtualenv.exe here, as the venv module doesn't allow python.exe to relocate.
"%PGADMIN_PYTHON_DIR%\Scripts\virtualenv.exe" venv
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\DLLs" "%TMPDIR%\venv\DLLs" > nul || EXIT /B 1
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\Lib" "%TMPDIR%\venv\Lib" > nul || EXIT /B 1
ECHO Activating virtual environment - %TMPDIR%\venv...
CALL "%TMPDIR%\venv\Scripts\activate" || EXIT /B 1
ECHO Installing dependencies...
CALL python -m pip install --upgrade pip || EXIT /B 1
CALL pip install --only-binary=cryptography -r "%WD%\requirements.txt" || EXIT /B 1
CD %WD%
EXIT /B 0
:CREATE_PYTHON_ENV
ECHO Staging Python...
MKDIR "%BUILDROOT%\python\Lib" || EXIT /B 1
ECHO Downloading embedded Python...
REM Get the python embeddable and extract it to %BUILDROOT%\python
CD "%TMPDIR%
%PGADMIN_PYTHON_DIR%\python -c "import sys; from urllib.request import urlretrieve; urlretrieve('https://www.python.org/ftp/python/' + sys.version.split(' ')[0] + '/python-' + sys.version.split(' ')[0] + '-embed-amd64.zip', 'python-embedded.zip')" || EXIT /B 1
%PGADMIN_PYTHON_DIR%\python -c "import zipfile; z = zipfile.ZipFile('python-embedded.zip', 'r'); z.extractall('../win-build/python/')" || EXIT /B 1
ECHO Copying site-packages...
XCOPY /S /I /E /H /Y "%TMPDIR%\venv\Lib\site-packages" "%BUILDROOT%\python\Lib\site-packages" > nul || EXIT /B 1
REM NOTE: There is intentionally no space after "site" in the line below, to prevent Python barfing if there's one in the file
ECHO import site>> "%BUILDROOT%\python\python%PYTHON_MAJOR%%PYTHON_MINOR%._pth"
ECHO Staging Kerberos components...
COPY "%PGADMIN_KRB5_DIR%\bin\kinit.exe" "%BUILDROOT%\python" > nul || EXIT /B 1
COPY "%PGADMIN_KRB5_DIR%\bin\krb5_64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
COPY "%PGADMIN_KRB5_DIR%\bin\comerr64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
COPY "%PGADMIN_KRB5_DIR%\bin\k5sprt64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
COPY "%PGADMIN_KRB5_DIR%\bin\gssapi64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
ECHO Cleaning up unnecessary .pyc and .pyo files...
FOR /R "%BUILDROOT%\python" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
ECHO Removing tests...
FOR /R "%BUILDROOT%\python\Lib" %%f in (test tests) do RD /Q /S "%%f" 1> nul 2>&1
EXIT /B 0
:CREATE_RUNTIME_ENV
IF NOT EXIST "%BUILDROOT%" MKDIR "%BUILDROOT%"
MKDIR "%BUILDROOT%\runtime"
ECHO Removing webpack caches...
RD /Q /S "%WD%\web\pgadmin\static\js\generated\.cache" 1> nul 2>&1
ECHO Copying web directory...
ROBOCOPY /S "%WD%\web" "%BUILDROOT%\web" > nul
CALL :CHECK_ROBOCOPY_ERROR
ECHO Installing javascript dependencies...
CD "%BUILDROOT%\web"
CALL yarn install || EXIT /B 1
ECHO Bundling javascript...
CALL yarn run bundle || EXIT /B 1
ECHO Cleaning up unnecessary .pyc and .pyo files...
FOR /R "%BUILDROOT%\web" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
ECHO Removing tests, Python caches and node modules...
FOR /R "%BUILDROOT%\web" %%f in (tests feature_tests __pycache__ node_modules) do RD /Q /S "%%f" 1> nul 2>&1
ECHO Removing the test framework...
RD /Q /S "%BUILDROOT%\web\regression" 1> nul 2>&1
ECHO Removing tools...
RD /Q /S "%BUILDROOT%\web\tools" 1> nul 2>&1
ECHO Removing any existing configurations...
DEL /q "%BUILDROOT%\web\pgadmin4.db" 1> nul 2>&1
DEL /q "%BUILDROOT%\web\config_local.py" 1> nul 2>&1
ECHO Staging license files...
COPY "%WD%\LICENSE" "%BUILDROOT%\" > nul || EXIT /B 1
COPY "%WD%\DEPENDENCIES" "%BUILDROOT%\" > nul || EXIT /B 1
ECHO Creating config_distro.py
ECHO SERVER_MODE = False > "%BUILDROOT%\web\config_distro.py"
ECHO HELP_PATH = '../../../docs/en_US/html/' >> "%BUILDROOT%\web\config_distro.py"
ECHO DEFAULT_BINARY_PATHS = { >> "%BUILDROOT%\web\config_distro.py"
ECHO 'pg': '$DIR/../runtime', >> "%BUILDROOT%\web\config_distro.py"
ECHO 'ppas': '' >> "%BUILDROOT%\web\config_distro.py"
ECHO } >> "%BUILDROOT%\web\config_distro.py"
ECHO Building docs...
CALL pip install sphinx || EXIT /B 1
MKDIR "%BUILDROOT%\docs\en_US\html"
CD "%WD%\docs\en_US"
CALL "%TMPDIR%\venv\Scripts\python.exe" build_code_snippet.py || EXIT /B 1
CALL "%TMPDIR%\venv\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%BUILDROOT%\docs\en_US\html" || EXIT /B 1
REM Remove unnecessary doc files
DEL /q "%BUILDROOT%\docs\en_US\html\_static\*.png" 1> nul 2>&1
RD /Q /S "%BUILDROOT%\docs\en_US\html\_sources" 1> nul 2>&1
ECHO Staging runtime components...
XCOPY /S /I /E /H /Y "%WD%\runtime\assets" "%BUILDROOT%\runtime\assets" > nul || EXIT /B 1
XCOPY /S /I /E /H /Y "%WD%\runtime\src" "%BUILDROOT%\runtime\src" > nul || EXIT /B 1
COPY "%WD%\runtime\package.json" "%BUILDROOT%\runtime\" > nul || EXIT /B 1
CD "%BUILDROOT%\runtime\"
CALL yarn install --production=true || EXIT /B 1
ECHO Downloading NWjs to %TMPDIR%...
REM Get a fresh copy of nwjs.
REM NOTE: The nw download servers seem to be very unreliable, so at the moment we're using wget which retries
REM YARN
REM CALL yarn --cwd "%TMPDIR%" add nw || EXIT /B
REM YARN END
REM WGET
REM Comment out the below for loop as the latest version (0.62.0) having
REM some problem, so for the time being hardcoded the version to 0.61.0
REM FOR /f "tokens=2 delims='" %%i IN ('yarn info nw ^| findstr "latest: "') DO SET "NW_VERSION=%%i"
REM :GET_NW
REM wget https://dl.nwjs.io/v%NW_VERSION%/nwjs-v%NW_VERSION%-win-x64.zip -O "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64.zip"
REM IF %ERRORLEVEL% NEQ 0 GOTO GET_NW
SET "NW_VERSION=0.61.0"
wget https://dl.nwjs.io/v%NW_VERSION%/nwjs-v%NW_VERSION%-win-x64.zip -O "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64.zip"
tar -C "%TMPDIR%" -xvf "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64.zip" || EXIT /B 1
REM WGET END
REM YARN
REM XCOPY /S /I /E /H /Y "%TMPDIR%\node_modules\nw\nwjs\*" "%BUILDROOT%\runtime" > nul || EXIT /B 1
REM YARN END
REM WGET
XCOPY /S /I /E /H /Y "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64\*" "%BUILDROOT%\runtime" > nul || EXIT /B 1
REM WGET END
MOVE "%BUILDROOT%\runtime\nw.exe" "%BUILDROOT%\runtime\pgAdmin4.exe"
ECHO Replacing executable icon...
CALL yarn --cwd "%TMPDIR%" add winresourcer || EXIT /B
"%TMPDIR%\node_modules\winresourcer\bin\Resourcer.exe" -op:upd -src:"%BUILDROOT%\runtime\pgAdmin4.exe" -type:Icongroup -name:IDR_MAINFRAME -file:"%WD%\pkg\win32\Resources\pgAdmin4.ico"
ECHO Staging PostgreSQL components...
COPY "%PGADMIN_POSTGRES_DIR%\bin\libpq.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" "%BUILDROOT%\runtime" > nul
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" "%BUILDROOT%\runtime" > nul
COPY "%PGADMIN_POSTGRES_DIR%\bin\zlib.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_dump.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_dumpall.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1L%
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_restore.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\psql.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
ECHO Staging VC++ runtime...
MKDIR "%BUILDROOT%\installer" || EXIT /B 1
COPY "%PGADMIN_VCREDIST_DIR%\%VCREDIST_FILE%" "%BUILDROOT%\installer" > nul || EXIT /B 1
CD %WD%
EXIT /B 0
:CREATE_INSTALLER
ECHO Preparing for creation of windows installer...
IF NOT EXIST "%DISTROOT%" MKDIR "%DISTROOT%"
ECHO Copying icon file...
COPY "%WD%\pkg\win32\Resources\pgAdmin4.ico" "%BUILDROOT%" > nul || EXIT /B 1
CD "%WD%\pkg\win32"
ECHO Processing installer configuration script...
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_FULLVERSION -r """%APP_VERSION%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_VERSION -r """v%APP_MAJOR%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%PGADMIN_VCREDIST_DIRNAME%\%VCREDIST_FILE%"""
ECHO Cleaning up...
DEL /s "%WD%\pkg\win32\installer.iss.in_stage*" > nul
ECHO Creating windows installer using INNO tool...
CALL "%PGADMIN_INNOTOOL_DIR%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss" || EXIT /B 1
ECHO Renaming installer...
MOVE "%WD%\pkg\win32\Output\pgadmin4-setup.exe" "%DISTROOT%\%INSTALLERNAME%" > nul || EXIT /B 1
ECHO Location - %DISTROOT%\%INSTALLERNAME%
ECHO Installer generated successfully.
CD %WD%
EXIT /B 0
:SIGN_INSTALLER
ECHO Attempting to sign the installer...
CALL "%PGADMIN_SIGNTOOL_DIR%\signtool.exe" sign /tr http://timestamp.digicert.com "%DISTROOT%\%INSTALLERNAME%"
IF %ERRORLEVEL% NEQ 0 (
ECHO.
ECHO ************************************************************
ECHO * Failed to sign the installer
ECHO ************************************************************
PAUSE
)
EXIT /B 0
:USAGE
ECHO Invalid command line options.
ECHO Usage: "Make.bat [clean]"
ECHO.
EXIT /B 1
:CHECK_ROBOCOPY_ERROR
IF %ERRORLEVEL% GEQ 8 EXIT /B %ERRORLEVEL%
EXIT /B 0