mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Implemented runtime using NWjs to open pgAdmin4 in a standalone window
instead of the system tray and web browser. Used NWjs to get rid of QT and C++. Fixes #5967 Use cheroot as the default production server for pgAdmin4. Fixes #5017
This commit is contained in:
2
pkg/mac/.gitignore
vendored
2
pkg/mac/.gitignore
vendored
@@ -1,4 +1,2 @@
|
||||
# Global excludes across all subdirectories
|
||||
codesign.conf
|
||||
debug.pgadmin.Info.plist
|
||||
pgadmin.Info.plist
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>__SHORT_VERSION__</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>__FULL_VERSION__</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>__FRAMEWORK_NAME__</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.pgadmin.__FRAMEWORK_NAME__</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>__SHORT_VERSION__</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>__FULL_VERSION__</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>__FRAMEWORK_NAME__</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.qt-project.Qt.__FRAMEWORK_NAME__</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
73
pkg/mac/Info.plist.in
Normal file
73
pkg/mac/Info.plist.in
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>18G103</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>app.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>%APPID%</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>%APPVER%</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4280.88</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>10.15</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1131</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11C505</string>
|
||||
<key>GPUEjectPolicy</key>
|
||||
<string>wait</string>
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
<key>MallocNanoZone</key>
|
||||
<string>0</string>
|
||||
<key>SYSTEM_VERSION_COMPAT</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
<key>LSFileQuarantineEnabled</key>
|
||||
<true/>
|
||||
<key>LSHasLocalizedDisplayName</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10.0</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<true/>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>BrowserCrApplication</string>
|
||||
<key>NSRequiresAquaSystemAppearance</key>
|
||||
<false/>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>NSUserActivityTypeBrowsingWeb</string>
|
||||
</array>
|
||||
<key>NSUserNotificationAlertStyle</key>
|
||||
<string>none</string>
|
||||
<key>OSAScriptingDefinition</key>
|
||||
<string>scripting.sdef</string>
|
||||
<key>SCMRevision</key>
|
||||
<string>62f83a7521ae1f32e563795732dff0c9da1b660d-refs/heads/master@{#812354}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1 +0,0 @@
|
||||
APPL????
|
||||
@@ -1,44 +1,31 @@
|
||||
Building pgAdmin4.dmg on Mac OS X
|
||||
=================================
|
||||
Building pgAdmin4.dmg on macOS
|
||||
==============================
|
||||
|
||||
Required Packages (Either build the sources or get them from macports or
|
||||
similar):
|
||||
|
||||
1. Python installation
|
||||
- Python 3.4+ or above from https://www.python.org/
|
||||
1. Yarn & NodeJS
|
||||
|
||||
2. QT installation
|
||||
- Qt 5 from http://www.qt.io/
|
||||
|
||||
3. PostgreSQL installation
|
||||
- PostgreSQL 9.5 or above from http://www.postgresql.org/
|
||||
2. PostgreSQL installation
|
||||
- PostgreSQL 12 or above from http://www.postgresql.org/
|
||||
|
||||
Building:
|
||||
|
||||
1. If a value different from the default of /usr/local/python is required, set
|
||||
the PGADMIN_PYTHON_DIR environment variable to the Python root installation
|
||||
directory, e.g.
|
||||
1. To bundle a different version of Python from the default of 3.9.0, set the
|
||||
PGADMIN_PYTHON_VERSION environment variable, e.g:
|
||||
|
||||
export PGADMIN_PYTHON_DIR=/opt/local
|
||||
export PGADMIN_PYTHON_VERSION=3.8.5
|
||||
|
||||
2. If a value different from the default of ~/Qt/5.13.2/clang_64, is required,
|
||||
set the PGADMIN_QT_DIR environment variable to the QT root installation
|
||||
directory, e.g.
|
||||
|
||||
export PGADMIN_QT_DIR=~/Qt/5.14.2/clang_64
|
||||
|
||||
3. If a value different from the default of /usr/local/pgsql is required, set
|
||||
the PGADMIN_POSTGRES_DIR environment variable to the PostgreSQL installation
|
||||
directory, e.g.
|
||||
2. If a path different from the default of /usr/local/pgsql for the PostgreSQL
|
||||
installation has been used, set the PGADMIN_POSTGRES_DIR environment variable
|
||||
appropriately, e.g:
|
||||
|
||||
export PGADMIN_POSTGRES_DIR=/opt/local/pgsql
|
||||
|
||||
4. Copy framework.conf.in to framework.conf, and edit the values accordingly.
|
||||
|
||||
5. If you want to codesign the appbundle, copy codesign.conf.in to
|
||||
3. If you want to codesign the appbundle, copy codesign.conf.in to
|
||||
codesign.conf and set the values accordingly.
|
||||
|
||||
6. To build, go to pgAdmin4 source root directory and execute "make appbundle".
|
||||
4. To build, go to pgAdmin4 source root directory and execute "make appbundle".
|
||||
This will create the python virtual environment and install all the required
|
||||
python modules mentioned in the requirements file using pip, build the
|
||||
runtime code and finally create the app bundle and the DMG in ./dist
|
||||
|
||||
@@ -13,58 +13,160 @@ _setup_env() {
|
||||
|
||||
_cleanup() {
|
||||
echo Cleaning up the old environment and app bundle...
|
||||
rm -rf ${SOURCE_DIR}/runtime/*.app
|
||||
rm -rf ${BUILD_ROOT}
|
||||
rm -rf "${BUILD_ROOT}"
|
||||
rm -rf "${TEMP_DIR}"
|
||||
rm -f ${DIST_ROOT}/*.dmg
|
||||
}
|
||||
|
||||
_create_venv() {
|
||||
_build_runtime() {
|
||||
echo "Assembling the runtime environment..."
|
||||
test -d "${BUILD_ROOT}" || mkdir "${BUILD_ROOT}"
|
||||
|
||||
# Copy in the template application
|
||||
cd "${BUILD_ROOT}"
|
||||
yarn --cwd "${BUILD_ROOT}" add nw
|
||||
cp -R "${BUILD_ROOT}/node_modules/nw/nwjs/nwjs.app" "${BUILD_ROOT}/"
|
||||
mv "${BUILD_ROOT}/nwjs.app" "${BUNDLE_DIR}"
|
||||
|
||||
# Copy in the runtime code
|
||||
mkdir "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp -R "${SOURCE_DIR}/runtime/assets" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp -R "${SOURCE_DIR}/runtime/src" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp "${SOURCE_DIR}/runtime/package.json" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
|
||||
# Install the runtime node_modules, then replace the package.json
|
||||
yarn --cwd "${BUNDLE_DIR}/Contents/Resources/app.nw/" install --production=true
|
||||
}
|
||||
|
||||
_create_python_env() {
|
||||
echo "Creating the Python environment..."
|
||||
PATH=${PGADMIN_POSTGRES_DIR}/bin:${PATH}
|
||||
LD_LIBRARY_PATH=${PGADMIN_POSTGRES_DIR}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
test -d ${BUILD_ROOT} || mkdir ${BUILD_ROOT}
|
||||
cd ${BUILD_ROOT}
|
||||
git clone https://github.com/gregneagle/relocatable-python.git "${BUILD_ROOT}/relocatable_python"
|
||||
PATH=$PATH:/usr/local/pgsql/bin "${BUILD_ROOT}/relocatable_python/make_relocatable_python_framework.py" --upgrade-pip --python-version ${PGADMIN_PYTHON_VERSION} --pip-requirements "${SOURCE_DIR}/requirements.txt" --destination "${BUNDLE_DIR}/Contents/Frameworks/"
|
||||
|
||||
${PYTHON_EXE} -m venv --copies venv
|
||||
|
||||
source venv/bin/activate
|
||||
pip install --no-cache-dir --no-binary psycopg2 -r ${SOURCE_DIR}/requirements.txt
|
||||
|
||||
# Figure the source path for use when completing the venv
|
||||
SOURCE_PYMODULES_PATH=$(dirname $("${PYTHON_EXE}" -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||
|
||||
# Figure the target path for use when completing the venv
|
||||
# Use "python" here as we want the venv path
|
||||
TARGET_PYMODULES_PATH=$(dirname $(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||
|
||||
# Copy in the additional system python modules
|
||||
cp -R ${SOURCE_PYMODULES_PATH}/* "${TARGET_PYMODULES_PATH}/"
|
||||
|
||||
# Link the python<version> directory to python so that the private environment path is found by the application.
|
||||
ln -s "$(basename ${TARGET_PYMODULES_PATH})" "${TARGET_PYMODULES_PATH}/../python"
|
||||
|
||||
# Remove tests
|
||||
find venv -name "test" -type d -print0 | xargs -0 rm -rf
|
||||
find venv -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||
}
|
||||
|
||||
_build_runtime() {
|
||||
cd ${SOURCE_DIR}/runtime
|
||||
if [ -f Makefile ]; then
|
||||
make clean
|
||||
fi
|
||||
${QMAKE}
|
||||
make
|
||||
cp -r pgAdmin4.app "${BUNDLE_DIR}"
|
||||
# Remove some things we don't need
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework"
|
||||
find . -name test -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tkinter -type d -print0 | xargs -0 rm -rf
|
||||
find . -name turtle.py -type f -print0 | xargs -0 rm -rf
|
||||
find . -name turtledemo -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tcl* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tk* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tdbc* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name itcl* -type d -print0 | xargs -0 rm -rf
|
||||
rm -f Versions/Current/lib/Tk.*
|
||||
rm -f Versions/Current/lib/libtcl*.dylib
|
||||
rm -f Versions/Current/lib/libtk*.dylib
|
||||
rm -f Versions/Current/lib/tcl*.sh
|
||||
rm -f Versions/Current/lib/tk*.sh
|
||||
rm -rf Versions/Current/share
|
||||
}
|
||||
|
||||
_build_docs() {
|
||||
cd ${SOURCE_DIR}/docs/en_US
|
||||
echo "Building the docs..."
|
||||
# Create a temporary venv for the doc build, so we don't contaminate the one
|
||||
# that we're going to ship.
|
||||
"${BUNDLE_DIR}/Contents/Frameworks/Python.framework/Versions/Current/bin/python3" -m venv "${BUILD_ROOT}/venv"
|
||||
source "${BUILD_ROOT}/venv/bin/activate"
|
||||
pip3 install --upgrade pip
|
||||
pip3 install -r "${SOURCE_DIR}/requirements.txt"
|
||||
pip3 install sphinx
|
||||
|
||||
cd "${SOURCE_DIR}"
|
||||
make docs
|
||||
|
||||
cd "${SOURCE_DIR}/docs/en_US"
|
||||
test -d "${BUNDLE_DIR}/Contents/Resources/docs/en_US" || mkdir -p "${BUNDLE_DIR}/Contents/Resources/docs/en_US"
|
||||
cp -r _build/html "${BUNDLE_DIR}/Contents/Resources/docs/en_US/"
|
||||
|
||||
# Remove some things we don't need
|
||||
rm -rf "${BUNDLE_DIR}/Contents/Resources/docs/en_US/html/_sources"
|
||||
rm -f "${BUNDLE_DIR}/Contents/Resources/docs/en_US/html/_static"/*.png
|
||||
}
|
||||
|
||||
_fixup_imports() {
|
||||
local TODO TODO_OLD FW_RELPATH LIB LIB_BN
|
||||
|
||||
echo "Fixing imports on the core appbundle..."
|
||||
pushd "$1" > /dev/null
|
||||
|
||||
# Find all the files that may need tweaks
|
||||
TODO=$(file `find . -perm +0111 -type f` | \
|
||||
grep -v "Frameworks/Python.framework" | \
|
||||
grep -v "Frameworks/nwjs" | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
awk -F ':| ' '{ORS=" "; print $1}' | \
|
||||
uniq)
|
||||
|
||||
# Add anything in the site-packages Python directory
|
||||
TODO+=$(file `find ./Contents/Frameworks/Python.framework/Versions/Current/lib/python*/site-packages -perm +0111 -type f` | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
awk -F ':| ' '{ORS=" "; print $1}' | \
|
||||
uniq)
|
||||
|
||||
echo "Found executables: ${TODO}"
|
||||
while test "${TODO}" != ""; do
|
||||
TODO_OLD=${TODO} ;
|
||||
TODO="" ;
|
||||
for TODO_OBJ in ${TODO_OLD}; do
|
||||
echo "Post-processing: ${TODO_OBJ}"
|
||||
|
||||
# Figure out the relative path from ${TODO_OBJ} to Contents/Frameworks
|
||||
FW_RELPATH=$(echo "${TODO_OBJ}" | \
|
||||
sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | \
|
||||
sed -n 's|[^/][^/]*/|../|gp' \
|
||||
)"Contents/Frameworks"
|
||||
|
||||
# Find all libraries ${TODO_OBJ} depends on, but skip system libraries
|
||||
for LIB in $(
|
||||
otool -L ${TODO_OBJ} | \
|
||||
sed -n 's|^.*[[:space:]]\([^[:space:]]*\.dylib\).*$|\1|p' | \
|
||||
egrep -v '^(/usr/lib)|(/System)|@executable_path' \
|
||||
); do
|
||||
# Copy in any required dependencies
|
||||
LIB_BN="$(basename "${LIB}")" ;
|
||||
if ! test -f "Contents/Frameworks/${LIB_BN}"; then
|
||||
TARGET_FILE=""
|
||||
TARGET_PATH=""
|
||||
echo "Adding symlink: ${LIB_BN} (because of: ${TODO_OBJ})"
|
||||
cp -R "${LIB}" "Contents/Frameworks/${LIB_BN}"
|
||||
if ! test -L "Contents/Frameworks/${LIB_BN}"; then
|
||||
chmod 755 "Contents/Frameworks/${LIB_BN}"
|
||||
else
|
||||
TARGET_FILE=$(readlink "${LIB}")
|
||||
TARGET_PATH=$(dirname "${LIB}")/${TARGET_FILE}
|
||||
echo "Adding symlink target: ${TARGET_PATH}"
|
||||
cp "${TARGET_PATH}" "Contents/Frameworks/${TARGET_FILE}"
|
||||
chmod 755 "Contents/Frameworks/${TARGET_FILE}"
|
||||
fi
|
||||
echo "Rewriting ID in Contents/Frameworks/${LIB_BN} to ${LIB_BN}"
|
||||
install_name_tool \
|
||||
-id "${LIB_BN}" \
|
||||
"Contents/Frameworks/${LIB_BN}" || exit 1
|
||||
TODO="${TODO} ./Contents/Frameworks/${LIB_BN}"
|
||||
fi
|
||||
# Rewrite the dependency paths
|
||||
echo "Rewriting library ${LIB} to @loader_path/${FW_RELPATH}/${LIB_BN} in ${TODO_OBJ}"
|
||||
install_name_tool -change \
|
||||
"${LIB}" \
|
||||
"@loader_path/${FW_RELPATH}/${LIB_BN}" \
|
||||
"${TODO_OBJ}" || exit 1
|
||||
install_name_tool -change \
|
||||
"${TARGET_PATH}" \
|
||||
"@loader_path/${FW_RELPATH}/${TARGET_FILE}" \
|
||||
"${TODO_OBJ}" || exit 1
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
echo "Imports updated on the core appbundle."
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
_complete_bundle() {
|
||||
echo "Completing the appbundle..."
|
||||
cd ${SCRIPT_DIR}
|
||||
|
||||
# Copy the binary utilities into place
|
||||
@@ -73,129 +175,35 @@ _complete_bundle() {
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dumpall" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_restore" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/psql" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
|
||||
# Replace the place holders with the current version
|
||||
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
|
||||
|
||||
# copy Python private environment to app bundle
|
||||
cp -PR ${BUILD_ROOT}/venv "${BUNDLE_DIR}/Contents/Resources/"
|
||||
# Update the plist
|
||||
cp Info.plist.in "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPNAME%/${APP_NAME}/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPVER%/${APP_LONG_VERSION}/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPID%/org.pgadmin.pgadmin4/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
for FILE in "${BUNDLE_DIR}"/Contents/Resources/*.lproj/InfoPlist.strings; do
|
||||
sed -i '' 's/CFBundleGetInfoString =.*/CFBundleGetInfoString = "Copyright (C) 2013 - 2021, The pgAdmin Development Team";/g' "${FILE}"
|
||||
sed -i '' 's/NSHumanReadableCopyright =.*/NSHumanReadableCopyright = "Copyright (C) 2013 - 2021, The pgAdmin Development Team";/g' "${FILE}"
|
||||
echo CFBundleDisplayName = \"${APP_NAME}\"\; >> "${FILE}"
|
||||
done
|
||||
|
||||
# Remove any TCL-related files that may cause us problems
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name "_tkinter*" -print0 | xargs -0 rm -f
|
||||
# PkgInfo
|
||||
echo APPLPGA4 > "${BUNDLE_DIR}/Contents/PkgInfo"
|
||||
|
||||
test -d "${BUNDLE_DIR}/Contents/Resources" || mkdir -p "${BUNDLE_DIR}/Contents/Resources"
|
||||
# Create qt.conf so that app knows where the Plugins are present
|
||||
cat >> "${BUNDLE_DIR}/Contents/Resources/qt.conf" << EOF
|
||||
[Paths]
|
||||
Plugins = PlugIns
|
||||
EOF
|
||||
# Icon
|
||||
cp pgAdmin4.icns "${BUNDLE_DIR}/Contents/Resources/app.icns"
|
||||
|
||||
test -d "${BUNDLE_DIR}/Contents/Frameworks" || mkdir -p "${BUNDLE_DIR}/Contents/Frameworks"
|
||||
test -d "${BUNDLE_DIR}/Contents/PlugIns/platforms" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||
test -d "${BUNDLE_DIR}/Contents/PlugIns/imageformats" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||
cp -f ${PGADMIN_QT_DIR}/plugins/platforms/libqcocoa.dylib "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||
cp -f ${PGADMIN_QT_DIR}/plugins/imageformats/libqsvg.dylib "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||
cp -f ${PGADMIN_POSTGRES_DIR}/lib/libpq.5.dylib "${BUNDLE_DIR}/Contents/Frameworks"
|
||||
# Rename the executable
|
||||
mv "${BUNDLE_DIR}/Contents/MacOS/nwjs" "${BUNDLE_DIR}/Contents/MacOS/${APP_NAME}"
|
||||
|
||||
local todo todo_old fw_relpath lib lib_bn
|
||||
# Rename the app in package.json so the menu looks as it should
|
||||
sed -i '' "s/\"name\": \"pgadmin4\"/\"name\": \"${APP_NAME}\"/g" "${BUNDLE_DIR}/Contents/Resources/app.nw/package.json"
|
||||
|
||||
pushd "${BUNDLE_DIR}" > /dev/null
|
||||
# Import the dependencies, and rewrite any library references
|
||||
_fixup_imports "${BUNDLE_DIR}"
|
||||
|
||||
# We skip nested apps here - those are treated specially
|
||||
todo=$(file `find ./ -perm +0111 ! -type d ! -path "*.app/*" ! -name "*.app"` | grep -E "Mach-O 64-bit" | awk -F ':| ' '{ORS=" "; print $1}')
|
||||
|
||||
echo "Found executables: ${todo}"
|
||||
while test "${todo}" != ""; do
|
||||
todo_old=${todo} ;
|
||||
todo="" ;
|
||||
for todo_obj in ${todo_old}; do
|
||||
echo "Post-processing: ${todo_obj}"
|
||||
|
||||
# Figure out the relative path from todo_obj to Contents/Frameworks
|
||||
fw_relpath=$(echo "${todo_obj}" | sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | sed -n 's|[^/][^/]*/|../|gp')"Contents/Frameworks"
|
||||
fw_relpath_old=${fw_relpath}
|
||||
|
||||
# Find all libraries $todo_obj depends on, but skip system libraries
|
||||
for lib in $(otool -L ${todo_obj} | grep "Qt\|dylib\|Frameworks\|PlugIns" | grep -v ":" | sed 's/(.*//' | egrep -v '(/usr/lib)|(/System)|@executable_path@'); do
|
||||
if echo ${lib} | grep "PlugIns\|libqcocoa" > /dev/null; then
|
||||
lib_loc="Contents/PlugIns/platforms"
|
||||
elif echo ${lib} | grep "PlugIns\|libqsvg" > /dev/null; then
|
||||
lib_loc="Contents/PlugIns/imageformats"
|
||||
elif echo ${lib} | grep "Qt" > /dev/null; then
|
||||
qtfw_path="$(dirname ${lib} | sed 's|.*\(Qt.*framework\)|\1|')"
|
||||
lib_loc="Contents/Frameworks/${qtfw_path}"
|
||||
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||
lib_loc="$(dirname ${todo_obj})"
|
||||
qtfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||
fi
|
||||
elif echo ${lib} | grep "Python" > /dev/null; then
|
||||
pyfw_path="$(dirname ${lib} | sed 's|.*\(Python.*framework\)|\1|')"
|
||||
lib_loc="Contents/Frameworks/${pyfw_path}"
|
||||
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||
lib_loc="$(dirname ${todo_obj})"
|
||||
pyfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||
fi
|
||||
else
|
||||
lib_loc="Contents/Frameworks"
|
||||
fi
|
||||
lib_bn="$(basename "${lib}")" ;
|
||||
if ! test -f "${lib_loc}/${lib_bn}"; then
|
||||
target_file=""
|
||||
target_path=""
|
||||
echo "Adding symlink: ${lib_bn} (because of: ${todo_obj})"
|
||||
|
||||
# Copy the QT and Python framework
|
||||
if echo ${lib} | grep Qt > /dev/null ; then
|
||||
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||
echo Copying -R ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} to ${lib_loc}/
|
||||
cp ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} ${lib_loc}/
|
||||
elif echo ${lib} | grep Python > /dev/null ; then
|
||||
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||
else
|
||||
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||
fi
|
||||
if ! test -L "${lib_loc}/${lib_bn}"; then
|
||||
chmod 755 "${lib_loc}/${lib_bn}"
|
||||
else
|
||||
target_file=$(readlink "${lib}")
|
||||
target_path=$(dirname "${lib}")/${target_file}
|
||||
|
||||
echo "Adding symlink target: ${target_path}"
|
||||
cp "${target_path}" "${lib_loc}/${target_file}"
|
||||
chmod 755 "${lib_loc}/${target_file}"
|
||||
fi
|
||||
echo "Rewriting ID in ${lib_loc}/${lib_bn} to ${lib_bn}"
|
||||
install_name_tool -id "${lib_bn}" "${lib_loc}/${lib_bn}"
|
||||
|
||||
todo="${todo} ./${lib_loc}/${lib_bn}"
|
||||
fi
|
||||
if echo ${lib} | grep Qt > /dev/null ; then
|
||||
fw_relpath="${fw_relpath}/${qtfw_path}"
|
||||
fi
|
||||
if echo ${lib} | grep Python > /dev/null ; then
|
||||
fw_relpath="${fw_relpath}/${pyfw_path}"
|
||||
fi
|
||||
chmod +w ${todo_obj}
|
||||
echo "Rewriting library ${lib} to @loader_path/${fw_relpath}/${lib_bn} in ${todo_obj}"
|
||||
|
||||
install_name_tool -change "${lib}" "@loader_path/${fw_relpath}/${lib_bn}" "${todo_obj}"
|
||||
install_name_tool -change "${target_path}" "@loader_path/${fw_relpath}/${target_file}" "${todo_obj}"
|
||||
|
||||
fw_relpath="${fw_relpath_old}"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# Fix the rpaths for psycopg module
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libpq.5.dylib @loader_path/../../../../../../Frameworks/libpq.5.dylib
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libssl.1.0.0.dylib @loader_path/../../../../../../Frameworks/libssl.1.0.0.dylib
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libcrypto.1.0.0.dylib @loader_path/../../../../../../Frameworks/libcrypto.1.0.0.dylib
|
||||
|
||||
echo "App completed: ${BUNDLE_DIR}"
|
||||
popd > /dev/null
|
||||
|
||||
pushd ${SOURCE_DIR}/web > /dev/null
|
||||
# Build node modules
|
||||
pushd "${SOURCE_DIR}/web" > /dev/null
|
||||
yarn install
|
||||
yarn run bundle
|
||||
|
||||
@@ -203,7 +211,7 @@ EOF
|
||||
popd > /dev/null
|
||||
|
||||
# copy the web directory to the bundle as it is required by runtime
|
||||
cp -r ${SOURCE_DIR}/web "${BUNDLE_DIR}/Contents/Resources/"
|
||||
cp -r "${SOURCE_DIR}/web" "${BUNDLE_DIR}/Contents/Resources/"
|
||||
cd "${BUNDLE_DIR}/Contents/Resources/web"
|
||||
rm -f pgadmin4.db config_local.*
|
||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||
@@ -226,66 +234,6 @@ EOF
|
||||
find "${BUNDLE_DIR}" -name "*.pyc" -print0 | xargs -0 rm -f
|
||||
}
|
||||
|
||||
_framework_config() {
|
||||
# Get the config
|
||||
source ${SCRIPT_DIR}/framework.conf
|
||||
|
||||
echo Reorganising the framework structure...
|
||||
|
||||
# Create "Current" and "Current/Resources" inside each of the framework dirs
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create framework 'Current' soft link
|
||||
VERSION_NUMBER=`ls -1`
|
||||
ln -s ${VERSION_NUMBER} Current
|
||||
|
||||
# Create "Resources" subdirectory
|
||||
if [ ! -d Current/Resources ]; then
|
||||
mkdir Current/Resources
|
||||
fi
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
|
||||
# Stuff for Qt framework files only
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create soft link to the framework binary
|
||||
ln -s Versions/Current/Qt*
|
||||
|
||||
# Create soft link to the framework Resources dir
|
||||
ln -s Versions/Current/Resources
|
||||
|
||||
# Create the Info.plist files
|
||||
MYNAME=`ls -1 Qt*`
|
||||
if [ -f Resources/Info.plist ]; then
|
||||
chmod +w Resources/Info.plist
|
||||
fi
|
||||
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
|
||||
# Same thing, but specific to the Python framework dir
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create soft link to the framework binary
|
||||
ln -s Versions/Current/Py*
|
||||
|
||||
# Create soft link to the framework Resources dir
|
||||
ln -s Versions/Current/Resources
|
||||
|
||||
# Create the Info.plist file
|
||||
MYNAME=`ls -1 Py*`
|
||||
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
}
|
||||
|
||||
_codesign_binaries() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
return
|
||||
@@ -300,17 +248,22 @@ _codesign_binaries() {
|
||||
echo "Developer Bundle Identifier not found in codesign.conf" >&2
|
||||
fi
|
||||
|
||||
# Create the entitlements file
|
||||
cp "${SCRIPT_DIR}/entitlements.plist.in" "${BUILD_ROOT}/entitlements.plist"
|
||||
TEAM_ID=$(echo ${DEVELOPER_ID} | awk -F"[()]" '{print $2}')
|
||||
sed -i '' "s/%TEAMID%/${TEAM_ID}/g" "${BUILD_ROOT}/entitlements.plist"
|
||||
|
||||
echo Signing ${BUNDLE_DIR} binaries...
|
||||
IFS=$'\n'
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle" | awk -F":| \\\(" '{print $1}' | uniq)
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | grep -v "(for architecture" | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle" | awk -F":" '{print $1}' | uniq)
|
||||
do
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime --entitlements "${BUILD_ROOT}/entitlements.plist" -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
done
|
||||
|
||||
echo Signing ${BUNDLE_DIR} libraries...
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -name "*.dylib*")
|
||||
do
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime --entitlements "${BUILD_ROOT}/entitlements.plist" -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -321,44 +274,32 @@ _codesign_bundle() {
|
||||
|
||||
# Sign the .app
|
||||
echo Signing ${BUNDLE_DIR}...
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE_DIR}"
|
||||
|
||||
# Verify it worked
|
||||
echo Verifying the signature...
|
||||
codesign --verify --verbose --deep --force "${BUNDLE_DIR}"
|
||||
echo ${BUNDLE_DIR} successfully signed.
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime --entitlements "${BUILD_ROOT}/entitlements.plist" -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE_DIR}"
|
||||
}
|
||||
|
||||
_create_dmg() {
|
||||
# move to the directory where we want to create the DMG
|
||||
test -d ${DIST_ROOT} || mkdir ${DIST_ROOT}
|
||||
cd ${DIST_ROOT}
|
||||
|
||||
DMG_LICENCE=./../pkg/mac/licence.rtf
|
||||
DMG_VOLUME_NAME=${APP_NAME}
|
||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||
echo "Checking out create-dmg..."
|
||||
git clone https://github.com/create-dmg/create-dmg.git "${BUILD_ROOT}/create-dmg"
|
||||
|
||||
DMG_DIR=./${DMG_IMAGE}.src
|
||||
|
||||
if test -e "${DMG_DIR}"; then
|
||||
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cleaning up"
|
||||
rm -f "${DMG_IMAGE}"
|
||||
mkdir "${DMG_DIR}"
|
||||
|
||||
echo "Copying data into temporary directory"
|
||||
cp -R "${BUNDLE_DIR}" "${DMG_DIR}"
|
||||
|
||||
echo "Creating image"
|
||||
hdiutil create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}"
|
||||
rm -rf "${DMG_DIR}"
|
||||
|
||||
echo Attaching License to image...
|
||||
python ${SCRIPT_DIR}/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
|
||||
"${BUILD_ROOT}/create-dmg/create-dmg" \
|
||||
--volname "${APP_NAME}" \
|
||||
--volicon "${SCRIPT_DIR}/dmg-icon.icns" \
|
||||
--eula "${SCRIPT_DIR}/licence.rtf" \
|
||||
--background "${SCRIPT_DIR}/dmg-background.png" \
|
||||
--app-drop-link 600 220 \
|
||||
--icon "${APP_NAME}.app" 200 220 \
|
||||
--window-pos 200 120 \
|
||||
--window-size 800 400 \
|
||||
--hide-extension "${APP_NAME}.app" \
|
||||
--add-file .DS_Store "${SCRIPT_DIR}/dmg.DS_Store" 5 5 \
|
||||
--format UDBZ \
|
||||
--skip-jenkins \
|
||||
--no-internet-enable \
|
||||
"${DIST_ROOT}/$(echo ${APP_NAME} | sed 's/ //g' | awk '{print tolower($0)}')-${APP_LONG_VERSION}.dmg" \
|
||||
"${BUNDLE_DIR}"
|
||||
}
|
||||
|
||||
_codesign_dmg() {
|
||||
@@ -366,21 +307,7 @@ _codesign_dmg() {
|
||||
return
|
||||
fi
|
||||
|
||||
DMG_VOLUME_NAME=${APP_NAME}
|
||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
DMG_IMAGE=${DIST_ROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||
|
||||
if ! test -f "${DMG_IMAGE}" ; then
|
||||
echo "${DMG_IMAGE} is no disk image!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sign the .app
|
||||
echo Signing ${DMG_IMAGE}...
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
|
||||
|
||||
# Verify it worked
|
||||
echo Verifying the signature...
|
||||
codesign --verify --verbose --force "${DMG_IMAGE}"
|
||||
echo ${DMG_IMAGE} successfully signed.
|
||||
}
|
||||
echo Signing disk image...
|
||||
codesign --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DIST_ROOT}/$(echo ${APP_NAME} | sed 's/ //g' | awk '{print tolower($0)}')-${APP_LONG_VERSION}.dmg"
|
||||
}
|
||||
|
||||
@@ -12,21 +12,14 @@ trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit co
|
||||
SCRIPT_DIR=$(cd `dirname $0` && pwd)
|
||||
SOURCE_DIR=$(realpath ${SCRIPT_DIR}/../..)
|
||||
BUILD_ROOT=$(realpath ${SCRIPT_DIR}/../..)/mac-build
|
||||
TEMP_DIR=$(realpath ${SCRIPT_DIR}/../..)/mac-temp
|
||||
DIST_ROOT=$(realpath ${SCRIPT_DIR}/../..)/dist
|
||||
|
||||
if [ ! -f ${SCRIPT_DIR}/framework.conf ]; then
|
||||
echo
|
||||
echo "Error: pkg/mac/framework.conf not found!"
|
||||
echo "Copy pkg/mac/framework.conf.in to pkg/mac/framework.conf and edit as required for the current system."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CODESIGN=1
|
||||
if [ ! -f ${SCRIPT_DIR}/codesign.conf ]; then
|
||||
echo
|
||||
echo "******************************************************************"
|
||||
echo "* ${SCRIPT_DIR}/codesign.conf not found. NOT signing the binaries."
|
||||
echo "* pkg/mac/codesign.conf not found. NOT signing the binaries."
|
||||
echo "******************************************************************"
|
||||
echo
|
||||
CODESIGN=0
|
||||
@@ -35,50 +28,24 @@ else
|
||||
source ${SCRIPT_DIR}/codesign.conf
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_PYTHON_DIR}" == "x" ]; then
|
||||
echo "PGADMIN_PYTHON_DIR not set. Setting it to the default: /usr/local/python"
|
||||
export PGADMIN_PYTHON_DIR=/usr/local/python
|
||||
fi
|
||||
PYTHON_EXE=${PGADMIN_PYTHON_DIR}/bin/python3
|
||||
|
||||
# Check if Python is working and calculate PYTHON_VERSION
|
||||
if ${PYTHON_EXE} -V > /dev/null 2>&1; then
|
||||
PYTHON_VERSION=`${PYTHON_EXE} -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
|
||||
else
|
||||
echo "Error: Python installation missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${PYTHON_VERSION}" -gt "38" ] && [ "${PYTHON_VERSION}" -lt "34" ]; then
|
||||
echo "Python version not supported."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_QT_DIR}" == "x" ]; then
|
||||
echo "PGADMIN_QT_DIR not set. Setting it to the default: ~/Qt/5.13.2/clang_64"
|
||||
export PGADMIN_QT_DIR=~/Qt/5.13.2/clang_64
|
||||
fi
|
||||
|
||||
QMAKE=${PGADMIN_QT_DIR}/bin/qmake
|
||||
if ! ${QMAKE} --version > /dev/null 2>&1; then
|
||||
echo "Error: qmake not found. QT installation is not present or incomplete."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
|
||||
echo "PGADMIN_POSTGRES_DIR not set. Setting it to the default: /usr/local/pgsql"
|
||||
export PGADMIN_POSTGRES_DIR=/usr/local/pgsql
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_PYTHON_VERSION}" == "x" ]; then
|
||||
echo "PGADMIN_PYTHON_VERSION not set. Setting it to the default: 3.9.0"
|
||||
export PGADMIN_PYTHON_VERSION=3.9.0
|
||||
fi
|
||||
|
||||
source ${SCRIPT_DIR}/build-functions.sh
|
||||
|
||||
_setup_env
|
||||
_cleanup
|
||||
_create_venv
|
||||
_build_runtime
|
||||
_create_python_env
|
||||
_build_docs
|
||||
_complete_bundle
|
||||
_framework_config
|
||||
_codesign_binaries
|
||||
_codesign_bundle
|
||||
_create_dmg
|
||||
|
||||
BIN
pkg/mac/dmg-background.png
Normal file
BIN
pkg/mac/dmg-background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 701 KiB |
BIN
pkg/mac/dmg-icon.icns
Normal file
BIN
pkg/mac/dmg-icon.icns
Normal file
Binary file not shown.
@@ -1,166 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
"""
|
||||
This script adds a license file to a DMG. Requires Xcode and a plain ascii text
|
||||
license file.
|
||||
Obviously only runs on a Mac.
|
||||
|
||||
Copyright (C) 2011-2013 Jared Hobbs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import optparse
|
||||
|
||||
|
||||
class Path(str):
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
os.unlink(self)
|
||||
|
||||
|
||||
def mktemp(dir=None, suffix=''):
|
||||
(fd, filename) = tempfile.mkstemp(dir=dir, suffix=suffix)
|
||||
os.close(fd)
|
||||
return Path(filename)
|
||||
|
||||
|
||||
def main(options, args):
|
||||
dmg_file, license_file = args
|
||||
with mktemp('.') as tmp_file:
|
||||
with open(tmp_file, 'w') as f:
|
||||
f.write("""data 'TMPL' (128, "LPic") {
|
||||
$"1344 6566 6175 6C74 204C 616E 6775 6167"
|
||||
$"6520 4944 4457 5244 0543 6F75 6E74 4F43"
|
||||
$"4E54 042A 2A2A 2A4C 5354 430B 7379 7320"
|
||||
$"6C61 6E67 2049 4444 5752 441E 6C6F 6361"
|
||||
$"6C20 7265 7320 4944 2028 6F66 6673 6574"
|
||||
$"2066 726F 6D20 3530 3030 4457 5244 1032"
|
||||
$"2D62 7974 6520 6C61 6E67 7561 6765 3F44"
|
||||
$"5752 4404 2A2A 2A2A 4C53 5445"
|
||||
};
|
||||
|
||||
data 'LPic' (5000) {
|
||||
$"0000 0002 0000 0000 0000 0000 0004 0000"
|
||||
};
|
||||
|
||||
data 'STR#' (5000, "English buttons") {
|
||||
$"0006 0D45 6E67 6C69 7368 2074 6573 7431"
|
||||
$"0541 6772 6565 0844 6973 6167 7265 6505"
|
||||
$"5072 696E 7407 5361 7665 2E2E 2E7A 4966"
|
||||
$"2079 6F75 2061 6772 6565 2077 6974 6820"
|
||||
$"7468 6520 7465 726D 7320 6F66 2074 6869"
|
||||
$"7320 6C69 6365 6E73 652C 2063 6C69 636B"
|
||||
$"2022 4167 7265 6522 2074 6F20 6163 6365"
|
||||
$"7373 2074 6865 2073 6F66 7477 6172 652E"
|
||||
$"2020 4966 2079 6F75 2064 6F20 6E6F 7420"
|
||||
$"6167 7265 652C 2070 7265 7373 2022 4469"
|
||||
$"7361 6772 6565 2E22"
|
||||
};
|
||||
|
||||
data 'STR#' (5002, "English") {
|
||||
$"0006 0745 6E67 6C69 7368 0541 6772 6565"
|
||||
$"0844 6973 6167 7265 6505 5072 696E 7407"
|
||||
$"5361 7665 2E2E 2E7B 4966 2079 6F75 2061"
|
||||
$"6772 6565 2077 6974 6820 7468 6520 7465"
|
||||
$"726D 7320 6F66 2074 6869 7320 6C69 6365"
|
||||
$"6E73 652C 2070 7265 7373 2022 4167 7265"
|
||||
$"6522 2074 6F20 696E 7374 616C 6C20 7468"
|
||||
$"6520 736F 6674 7761 7265 2E20 2049 6620"
|
||||
$"796F 7520 646F 206E 6F74 2061 6772 6565"
|
||||
$"2C20 7072 6573 7320 2244 6973 6167 7265"
|
||||
$"6522 2E"
|
||||
};\n\n""")
|
||||
with open(license_file, 'r') as lines:
|
||||
kind = 'RTF ' if license_file.lower().endswith('.rtf') \
|
||||
else 'TEXT'
|
||||
f.write('data \'%s\' (5000, "English") {\n' % kind)
|
||||
|
||||
def escape(s):
|
||||
return s.strip().replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
for line in lines:
|
||||
if len(line) < 1000:
|
||||
f.write(' "' + escape(line) + '\\n"\n')
|
||||
else:
|
||||
for liner in line.split('.'):
|
||||
f.write(' "' + escape(liner) + '. \\n"\n')
|
||||
f.write('};\n\n')
|
||||
f.write("""data 'styl' (5000, "English") {
|
||||
$"0003 0000 0000 000C 0009 0014 0000 0000"
|
||||
$"0000 0000 0000 0000 0027 000C 0009 0014"
|
||||
$"0100 0000 0000 0000 0000 0000 002A 000C"
|
||||
$"0009 0014 0000 0000 0000 0000 0000"
|
||||
};\n""")
|
||||
os.system('hdiutil unflatten -quiet "%s"' % dmg_file)
|
||||
ret = os.system('%s -a %s -o "%s"' %
|
||||
(options.rez, tmp_file, dmg_file))
|
||||
os.system('hdiutil flatten -quiet "%s"' % dmg_file)
|
||||
if options.compression is not None:
|
||||
os.system('cp %s %s.temp.dmg' % (dmg_file, dmg_file))
|
||||
os.remove(dmg_file)
|
||||
if options.compression == "bz2":
|
||||
os.system('hdiutil convert %s.temp.dmg -format UDBZ -o %s' %
|
||||
(dmg_file, dmg_file))
|
||||
elif options.compression == "gz":
|
||||
os.system('hdiutil convert %s.temp.dmg -format ' % dmg_file +
|
||||
'UDZO -imagekey zlib-devel=9 -o %s' % dmg_file)
|
||||
os.remove('%s.temp.dmg' % dmg_file)
|
||||
if ret == 0:
|
||||
print("Successfully added license to '%s'" % dmg_file)
|
||||
else:
|
||||
print("Failed to add license to '%s'" % dmg_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser()
|
||||
parser.set_usage("""%prog <dmgFile> <licenseFile> [OPTIONS]
|
||||
This program adds a software license agreement to a DMG file.
|
||||
It requires Xcode and either a plain ascii text <licenseFile>
|
||||
or a <licenseFile.rtf> with the RTF contents.
|
||||
|
||||
See --help for more details.""")
|
||||
parser.add_option(
|
||||
'--rez',
|
||||
'-r',
|
||||
action='store',
|
||||
default='/Applications/Xcode.app/Contents/Developer/Tools/Rez',
|
||||
help='The path to the Rez tool. Defaults to %default'
|
||||
)
|
||||
parser.add_option(
|
||||
'--compression',
|
||||
'-c',
|
||||
action='store',
|
||||
choices=['bz2', 'gz'],
|
||||
default=None,
|
||||
help='Optionally compress dmg using specified compression type. '
|
||||
'Choices are bz2 and gz.'
|
||||
)
|
||||
options, args = parser.parse_args()
|
||||
cond = len(args) != 2
|
||||
if not os.path.exists(options.rez):
|
||||
print('Failed to find Rez at "%s"!\n' % options.rez)
|
||||
cond = True
|
||||
if cond:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
main(options, args)
|
||||
BIN
pkg/mac/dmg.DS_Store
Normal file
BIN
pkg/mac/dmg.DS_Store
Normal file
Binary file not shown.
12
pkg/mac/entitlements.plist.in
Normal file
12
pkg/mac/entitlements.plist.in
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<string>%TEAMID%.org.pgadmin.pgadmin4</string>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copy this file to framework.conf, and edit the values below to reflect your
|
||||
# environment (versions of Python/Qt used)
|
||||
|
||||
PYTHON_SHORT_VERSION=3.8
|
||||
PYTHON_FULL_VERSION=3.8.2
|
||||
|
||||
QT_SHORT_VERSION=5.14
|
||||
QT_FULL_VERSION=5.14.2
|
||||
|
||||
|
||||
BIN
pkg/mac/pgAdmin4.icns
Normal file
BIN
pkg/mac/pgAdmin4.icns
Normal file
Binary file not shown.
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>pgAdmin4</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>pgAdmin4 PGADMIN_LONG_VERSION</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>pgAdmin4.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.postgresql.pgadmin</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>PGADMIN_SHORT_VERSION</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>PGADMIN_LONG_VERSION</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user