mirror of
https://github.com/zotero/zotero.git
synced 2026-10-07 02:58:09 +00:00
Developer ID-signed Safari web extensions load only in Safari 18.4 and later -- older Safari blocks them at the code-signing layer -- so macOS 11 and 12 users, whose Safari versions top out at 16.6 and 17.6, lost the connector with the web extension conversion. Embed the prebuilt legacy App Extension ($SAFARI_APP_EXTENSION, set by the deploy scripts) at Contents/PlugIns/ZoteroSafariExtension.appex with the historical bundle identifier, and move the web extension to Contents/PlugIns/ZoteroSafariWebExtension.appex with a new .SafariWebExtension identifier. The web extension's SFSafariAppExtensionBundleIdentifiersToReplace key causes Safari versions that can load it to hide the App Extension and migrate its enabled state, while older Safari shows only the App Extension. Also remove the removed-files entries for the App Extension's resources, which would otherwise delete them on update. https://forums.zotero.org/discussion/132925/
1185 lines
43 KiB
Bash
Executable file
1185 lines
43 KiB
Bash
Executable file
#!/bin/bash -e
|
|
|
|
# Copyright (c) 2011 Zotero
|
|
# Center for History and New Media
|
|
# George Mason University, Fairfax, Virginia, USA
|
|
# http://zotero.org
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
CALLDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
. "$CALLDIR/config.sh"
|
|
. "$CALLDIR/scripts/utils.sh"
|
|
|
|
if [ "`uname`" = "Darwin" ]; then
|
|
MAC_NATIVE=1
|
|
else
|
|
MAC_NATIVE=0
|
|
fi
|
|
if [ "`uname -o 2> /dev/null`" = "Cygwin" ]; then
|
|
WIN_NATIVE=1
|
|
else
|
|
WIN_NATIVE=0
|
|
fi
|
|
|
|
function usage {
|
|
cat >&2 <<DONE
|
|
Usage: $0 [-d DIR] [-f FILE] -p PLATFORMS [-a ARCH] [-c CHANNEL] [options]
|
|
|
|
Options
|
|
-d DIR build directory to build from (from build_xpi; cannot be used with -f)
|
|
-f FILE ZIP file to build from (cannot be used with -d)
|
|
-t add devtools
|
|
-p PLATFORMS build for platforms PLATFORMS (m=Mac, w=Windows, l=Linux)
|
|
-a ARCH architecture to build (arm64, x64, i686, win32)
|
|
* Ignored for Mac (always universal)
|
|
* If omitted on Windows/Linux, all standard archs are built
|
|
-c CHANNEL use update channel CHANNEL
|
|
-e enforce signing
|
|
-s don't package; only build binaries in staging/ directory
|
|
-q quick build (skip compression and other optional steps for faster restarts during development)
|
|
DONE
|
|
exit 1
|
|
}
|
|
|
|
BUILD_DIR=`mktemp -d`
|
|
function cleanup {
|
|
rm -rf $BUILD_DIR
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
function abspath {
|
|
echo $(cd $(dirname $1); pwd)/$(basename $1);
|
|
}
|
|
|
|
function check_lfs_file {
|
|
if [ "$(head --bytes 5 "$1")" = "versi" ]; then
|
|
echo "$1 not checked out -- install Git LFS and run 'git lfs pull'" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
SOURCE_DIR=""
|
|
ZIP_FILE=""
|
|
BUILD_MAC=0
|
|
BUILD_WIN=0
|
|
BUILD_LINUX=0
|
|
PACKAGE=1
|
|
DEVTOOLS=0
|
|
quick_build=0
|
|
arch=""
|
|
while getopts "d:f:p:a:c:tseq" opt; do
|
|
case $opt in
|
|
d)
|
|
SOURCE_DIR="$OPTARG"
|
|
;;
|
|
f)
|
|
ZIP_FILE="$OPTARG"
|
|
;;
|
|
p)
|
|
for (( i=0; i<${#OPTARG}; i++ )); do
|
|
case ${OPTARG:i:1} in
|
|
m) BUILD_MAC=1 ;;
|
|
w) BUILD_WIN=1 ;;
|
|
l) BUILD_LINUX=1 ;;
|
|
*)
|
|
echo "$0: Invalid platform option ${OPTARG:i:1}" >&2
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
a)
|
|
arch="$OPTARG"
|
|
;;
|
|
c)
|
|
UPDATE_CHANNEL="$OPTARG"
|
|
;;
|
|
t)
|
|
DEVTOOLS=1
|
|
;;
|
|
e)
|
|
SIGN=1
|
|
;;
|
|
s)
|
|
PACKAGE=0
|
|
;;
|
|
q)
|
|
quick_build=1
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|
|
shift $((OPTIND-1)); OPTIND=1
|
|
done
|
|
|
|
xul_hash_file() {
|
|
local _platform=$1
|
|
local _arch=$2
|
|
|
|
case $_platform in
|
|
m)
|
|
echo "hash-mac";;
|
|
|
|
w)
|
|
[[ $_arch == x64 ]] && _arch="win-x64"
|
|
[[ $_arch == arm64 ]] && _arch="win-arm64"
|
|
echo "hash-${_arch}";;
|
|
|
|
l)
|
|
[[ $_arch == x64 ]] && _arch="x86_64"
|
|
echo "hash-linux-${_arch}";;
|
|
|
|
*)
|
|
echo "Invalid platform '$_platform'" >&2
|
|
exit 1
|
|
esac
|
|
}
|
|
|
|
function check_xulrunner_hash {
|
|
local _platform=$1
|
|
local _arch=$2
|
|
|
|
local platform_hash_file=$(xul_hash_file "$_platform" "${_arch:-universal}")
|
|
|
|
# TEMP: If previous Windows hash file without architecture is present, force a refresh,
|
|
# because the Firefox folder might have been changed without the new hash file being
|
|
# updated, resulting in a broken build (e.g, fx140 using fx128). We'll want to keep this
|
|
# as long as we're switching back to <=fx128. This isn't an issue on macOS because there's
|
|
# no architecture and isn't an issue on Linux because the runtime folder names changed.
|
|
if [[ $_platform = 'w' ]] && [[ -e "$CALLDIR/xulrunner/hash-win" ]]; then
|
|
echo "Found old hash-win -- forcing redownload"
|
|
rm "$CALLDIR"/xulrunner/hash-win*
|
|
fi
|
|
|
|
if [ ! -e "$CALLDIR/xulrunner/$platform_hash_file" ]; then
|
|
echo "$platform_hash_file not found -- downloading"
|
|
echo
|
|
$CALLDIR/scripts/fetch_xulrunner -p $_platform ${_arch:+-a $_arch}
|
|
else
|
|
recalculated_xulrunner_hash=$("$CALLDIR/scripts/xulrunner_hash" -p $_platform ${_arch:+-a $_arch})
|
|
current_xulrunner_hash=$(< "$CALLDIR/xulrunner/$platform_hash_file")
|
|
if [ "$current_xulrunner_hash" != "$recalculated_xulrunner_hash" ]; then
|
|
echo "xulrunner hashes don't match -- redownloading"
|
|
echo
|
|
"$CALLDIR/scripts/fetch_xulrunner" -p $_platform ${_arch:+-a $_arch}
|
|
current_xulrunner_hash=$(< "$CALLDIR/xulrunner/$platform_hash_file")
|
|
if [ "$current_xulrunner_hash" != "$recalculated_xulrunner_hash" ]; then
|
|
echo "xulrunner hashes don't match after running fetch_xulrunner!"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Derive platform flags from host if none provided
|
|
if [[ $BUILD_MAC == 0 ]] && [[ $BUILD_WIN == 0 ]] && [[ $BUILD_LINUX == 0 ]]; then
|
|
case "$(uname -s)" in
|
|
Darwin) BUILD_MAC=1 ;;
|
|
Linux) BUILD_LINUX=1 ;;
|
|
CYGWIN*|MINGW*) BUILD_WIN=1 ;;
|
|
esac
|
|
fi
|
|
|
|
# Check xulrunner hashes for requested builds
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
check_xulrunner_hash m
|
|
fi
|
|
if [ $BUILD_WIN == 1 ]; then
|
|
if [[ -n $arch ]]; then
|
|
check_xulrunner_hash w $(get_canonical_arch w $arch)
|
|
else
|
|
for _a in win-x64 win-arm64 win32; do
|
|
check_xulrunner_hash w "$_a"
|
|
done
|
|
fi
|
|
fi
|
|
if [ $BUILD_LINUX == 1 ]; then
|
|
if [[ -n $arch ]]; then
|
|
check_xulrunner_hash l $(get_canonical_arch l $arch)
|
|
else
|
|
for _a in x64 arm64 i686; do
|
|
check_xulrunner_hash l "$_a"
|
|
done
|
|
fi
|
|
fi
|
|
|
|
|
|
|
|
# Require source dir or ZIP file
|
|
if [[ -z "$SOURCE_DIR" ]] && [[ -z "$ZIP_FILE" ]]; then
|
|
usage
|
|
elif [[ -n "$SOURCE_DIR" ]] && [[ -n "$ZIP_FILE" ]]; then
|
|
usage
|
|
fi
|
|
|
|
# Require at least one platform
|
|
if [[ $BUILD_MAC == 0 ]] && [[ $BUILD_WIN == 0 ]] && [[ $BUILD_LINUX == 0 ]]; then
|
|
usage
|
|
fi
|
|
|
|
if [[ -z "${ZOTERO_TEST:-}" ]] || [[ $ZOTERO_TEST == "0" ]]; then
|
|
include_tests=0
|
|
else
|
|
include_tests=1
|
|
fi
|
|
|
|
# Bundle devtools with dev builds
|
|
if [ "$UPDATE_CHANNEL" == "beta" ] || [ "$UPDATE_CHANNEL" == "dev" ] || [ "$UPDATE_CHANNEL" == "test" ]; then
|
|
DEVTOOLS=1
|
|
fi
|
|
if [ -z "$UPDATE_CHANNEL" ]; then UPDATE_CHANNEL="default"; fi
|
|
BUILD_ID=`date +%Y%m%d%H%M%S`
|
|
|
|
# Paths to Gecko runtimes
|
|
MAC_RUNTIME_PATH="$CALLDIR/xulrunner/Firefox.app"
|
|
WIN_RUNTIME_PATH_PREFIX="$CALLDIR/xulrunner/firefox-"
|
|
LINUX_RUNTIME_PATH_PREFIX="$CALLDIR/xulrunner/firefox-linux-"
|
|
|
|
base_dir="$BUILD_DIR/base"
|
|
app_dir="$BUILD_DIR/base/app"
|
|
omni_dir="$BUILD_DIR/base/app/omni"
|
|
|
|
shopt -s extglob
|
|
mkdir -p "$app_dir"
|
|
rm -rf "$STAGE_DIR"
|
|
mkdir "$STAGE_DIR"
|
|
rm -rf "$DIST_DIR"
|
|
mkdir "$DIST_DIR"
|
|
|
|
# Save build id, which is needed for updates manifest
|
|
echo $BUILD_ID > "$DIST_DIR/build_id"
|
|
|
|
cd "$app_dir"
|
|
|
|
# Copy 'browser' files from Firefox
|
|
#
|
|
# omni.ja is left uncompressed within the Firefox application files by fetch_xulrunner
|
|
#
|
|
# TEMP: Also extract .hyf hyphenation files from the outer (still compressed) omni.ja
|
|
# This works around https://bugzilla.mozilla.org/show_bug.cgi?id=1772900
|
|
set +e
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
cp -Rp "$MAC_RUNTIME_PATH"/Contents/Resources/browser/omni "$app_dir"
|
|
unzip -qj "$MAC_RUNTIME_PATH"/Contents/Resources/omni.ja "hyphenation/*" -d "$app_dir"/hyphenation/
|
|
|
|
elif [[ $BUILD_WIN == 1 ]]; then
|
|
# These are non-arch-specific files, so just find a runtime we fetched:
|
|
# - If the caller specified -a, that arch is guaranteed present.
|
|
# - Otherwise prefer win-x64 → win-arm64 → win32, falling back to the first
|
|
# directory that exists under xulrunner/.
|
|
if [[ -n $arch ]]; then
|
|
omni_arch=$(get_canonical_arch w $arch)
|
|
else
|
|
for cand in win-x64 win-arm64 win32; do
|
|
[[ -d "${WIN_RUNTIME_PATH_PREFIX}${cand}" ]] && { omni_arch="$cand"; break; }
|
|
done
|
|
fi
|
|
cp -Rp "${WIN_RUNTIME_PATH_PREFIX}${omni_arch}"/browser/omni "$app_dir"
|
|
unzip -qj "${WIN_RUNTIME_PATH_PREFIX}${omni_arch}"/omni.ja "hyphenation/*" \
|
|
-d "$app_dir"/hyphenation/
|
|
|
|
elif [[ $BUILD_LINUX == 1 ]]; then
|
|
# Same as above
|
|
if [[ -n $arch ]]; then
|
|
omni_arch=$(get_canonical_arch l $arch)
|
|
else
|
|
for cand in x86_64 arm64 i686; do
|
|
[[ -d "${LINUX_RUNTIME_PATH_PREFIX}${cand}" ]] && { omni_arch="$cand"; break; }
|
|
done
|
|
fi
|
|
cp -Rp "${LINUX_RUNTIME_PATH_PREFIX}${omni_arch}"/browser/omni "$app_dir"
|
|
unzip -qj "${LINUX_RUNTIME_PATH_PREFIX}${omni_arch}"/omni.ja "hyphenation/*" \
|
|
-d "$app_dir"/hyphenation/
|
|
fi
|
|
set -e
|
|
cd $omni_dir
|
|
|
|
# Remove Firefox files that we don't need
|
|
rm actors/AboutLogins{Parent,Child}.sys.mjs
|
|
rm actors/AboutMessagePreview{Parent,Child}.sys.mjs
|
|
rm actors/AboutNewTab{Parent,Child}.sys.mjs
|
|
rm actors/AboutPocket{Parent,Child}.sys.mjs
|
|
rm actors/AboutPrivateBrowsing{Parent,Child}.sys.mjs
|
|
rm actors/AboutProtections{Parent,Child}.sys.mjs
|
|
rm actors/AboutReader{Parent,Child}.sys.mjs
|
|
rm actors/AboutTabCrashed{Parent,Child}.sys.mjs
|
|
rm actors/AboutWelcome{Parent,Child}.sys.mjs
|
|
rm actors/ASRouter{Parent,Child}.sys.mjs
|
|
rm actors/BackupUI{Parent,Child}.sys.mjs
|
|
rm actors/BlockedSite{Parent,Child}.sys.mjs
|
|
rm actors/BrowserProcessChild.sys.mjs
|
|
rm actors/BrowserTabChild.sys.mjs
|
|
rm actors/ClickHandler{Parent,Child}.sys.mjs
|
|
rm actors/ContentSearch{Parent,Child}.sys.mjs
|
|
rm actors/DecoderDoctor{Parent,Child}.sys.mjs
|
|
rm actors/DOMFullscreen{Parent,Child}.sys.mjs
|
|
rm actors/EncryptedMedia{Parent,Child}.sys.mjs
|
|
rm actors/FormValidation{Parent,Child}.sys.mjs
|
|
rm actors/LinkHandler{Parent,Child}.sys.mjs
|
|
rm actors/MigrationWizard{Parent,Child}.sys.mjs
|
|
rm actors/PageData{Parent,Child}.sys.mjs # Not our PageData actor
|
|
rm actors/PageInfoChild.sys.mjs
|
|
rm actors/PageStyle{Parent,Child}.sys.mjs
|
|
rm actors/Plugin{Parent,Child}.sys.mjs # GMP plugins, which we remove
|
|
rm actors/PointerLock{Parent,Child}.sys.mjs
|
|
#rm actors/RFPHelper{Parent,Child}.sys.mjs
|
|
rm actors/ScreenshotsComponentChild.sys.mjs
|
|
#rm actors/SearchSERPTelemetry{Parent,Child}.sys.mjs
|
|
#rm actors/ShoppingSidebar{Parent,Child}.sys.mjs
|
|
rm actors/SpeechDispatcher{Parent,Child}.sys.mjs
|
|
rm actors/WebRTC{Parent,Child}.sys.mjs
|
|
|
|
# Keep some essential files from chrome/browser/
|
|
mkdir chrome/browser-fx
|
|
browser_keep=(
|
|
content/browser/license.html
|
|
# For web-ext
|
|
content/browser/parent/ext-browser.js
|
|
# For spellchecking
|
|
content/browser/built_in_addons.json
|
|
)
|
|
if [ $BUILD_WIN == 1 ]; then
|
|
# Windows window controls
|
|
browser_keep+=(skin/classic/browser/window-controls)
|
|
fi
|
|
for file in "${browser_keep[@]}"; do
|
|
mkdir -p "$(dirname "chrome/browser-fx/$file")"
|
|
mv "chrome/browser/$file" "chrome/browser-fx/$file"
|
|
done
|
|
# Delete everything else
|
|
rm -r chrome/browser
|
|
# Move essential files back
|
|
mv chrome/browser-fx chrome/browser
|
|
|
|
#rm modules/SearchSERPTelemetry.sys.mjs
|
|
|
|
# Move some Firefox files that would be overwritten out of the way
|
|
mv chrome.manifest chrome.manifest-fx
|
|
mv defaults defaults-fx
|
|
|
|
# Extract Zotero files
|
|
if [ -n "$ZIP_FILE" ]; then
|
|
ZIP_FILE="`abspath $ZIP_FILE`"
|
|
echo "Building from $ZIP_FILE"
|
|
unzip -q $ZIP_FILE -d "$omni_dir"
|
|
else
|
|
rsync_params=""
|
|
if [ $include_tests -eq 0 ]; then
|
|
rsync_params="--exclude /test"
|
|
fi
|
|
rsync -a $rsync_params "$SOURCE_DIR/" ./
|
|
fi
|
|
|
|
mv defaults defaults-z
|
|
mv defaults-fx defaults
|
|
prefs_file=defaults/preferences/zotero.js
|
|
|
|
# Transfer Firefox prefs, omitting some with undesirable overrides from the base prefs
|
|
#
|
|
# - network.captive-portal-service.enabled
|
|
# Disable the captive portal check against Mozilla servers
|
|
# - extensions.systemAddon.update.url
|
|
grep -E -v '(network.captive-portal-service.enabled|extensions.systemAddon.update.url)' defaults/preferences/firefox.js > $prefs_file
|
|
rm defaults/preferences/firefox.js
|
|
|
|
# Combine app and "extension" Zotero prefs
|
|
echo "" >> $prefs_file
|
|
echo "#" >> $prefs_file
|
|
echo "# Zotero app prefs" >> $prefs_file
|
|
echo "#" >> $prefs_file
|
|
echo "" >> $prefs_file
|
|
cat "$CALLDIR/assets/prefs.js" >> $prefs_file
|
|
echo "" >> $prefs_file
|
|
echo "# Zotero extension prefs" >> $prefs_file
|
|
echo "" >> $prefs_file
|
|
cat defaults-z/preferences/zotero.js >> $prefs_file
|
|
|
|
rm -rf defaults-z
|
|
|
|
# Platform-specific prefs
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
perl -pi -e 's/pref\("browser\.preferences\.instantApply", false\);/pref\("browser\.preferences\.instantApply", true);/' $prefs_file
|
|
perl -pi -e 's/%GECKO_VERSION%/'"$GECKO_VERSION_MAC"'/g' $prefs_file
|
|
# Fix horizontal mousewheel scrolling (this is set to 4 in the Fx60 .app greprefs.js, but
|
|
# defaults to 1 in later versions of Firefox, and needs to be 1 to work on macOS)
|
|
echo 'pref("mousewheel.with_shift.action", 1);' >> $prefs_file
|
|
elif [ $BUILD_WIN == 1 ]; then
|
|
perl -pi -e 's/%GECKO_VERSION%/'"$GECKO_VERSION_WIN"'/g' $prefs_file
|
|
elif [ $BUILD_LINUX == 1 ]; then
|
|
# Modify platform-specific prefs
|
|
perl -pi -e 's/pref\("browser\.preferences\.instantApply", false\);/pref\("browser\.preferences\.instantApply", true);/' $prefs_file
|
|
perl -pi -e 's/%GECKO_VERSION%/'"$GECKO_VERSION_LINUX"'/g' $prefs_file
|
|
# Auto-scroll is disabled by default on Linux
|
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=1747208
|
|
perl -pi -e 's/pref\("general\.autoScroll", false\);/pref\("general.autoScroll", true);/' $prefs_file
|
|
fi
|
|
|
|
# Clear list of built-in add-ons, but leave the en-US dictionary
|
|
echo '{"dictionaries": {"en-US": "dictionaries/en-US.dic"}, "system": []}' > chrome/browser/content/browser/built_in_addons.json
|
|
|
|
# chrome.manifest
|
|
mv chrome.manifest zotero.manifest
|
|
mv chrome.manifest-fx chrome.manifest
|
|
# TEMP
|
|
#echo "manifest zotero.manifest" >> "$base_dir/chrome.manifest"
|
|
cat zotero.manifest >> chrome.manifest
|
|
rm zotero.manifest
|
|
|
|
# Update channel
|
|
perl -pi -e 's/pref\("app\.update\.channel", "[^"]*"\);/pref\("app\.update\.channel", "'"$UPDATE_CHANNEL"'");/' $prefs_file
|
|
echo -n "Channel: "
|
|
grep app.update.channel $prefs_file
|
|
echo
|
|
|
|
# Add devtools prefs
|
|
if [ $DEVTOOLS -eq 1 ]; then
|
|
echo >> $prefs_file
|
|
echo "// Dev Tools" >> $prefs_file
|
|
echo 'pref("devtools.debugger.remote-enabled", true);' >> $prefs_file
|
|
if [ $UPDATE_CHANNEL != "beta" ]; then
|
|
echo 'pref("devtools.debugger.prompt-connection", false);' >> $prefs_file
|
|
fi
|
|
|
|
# Use 'zotero' instead of 'zotero-bin' when passing -jsdebugger flag on Linux, since we need
|
|
# that to pass application.ini
|
|
replace_line 'let command = Services.dirsvc.get\("XREExeF", Ci.nsIFile\).path;' \
|
|
'let command = Services.dirsvc.get("XREExeF", Ci.nsIFile).path; command = command.replace("zotero-bin", "zotero");' \
|
|
chrome/devtools/modules/devtools/client/framework/browser-toolbox/Launcher.sys.mjs
|
|
|
|
# Fix source display breaking when switching windows in the Browser Toolbox.
|
|
# When the user switches which chrome window is being inspected (via the frame
|
|
# picker), the thread actor's _onWindowReady handler clears all debuggees and
|
|
# source actors, then re-adds debuggees. But it never calls addAllSources() to
|
|
# re-emit the existing scripts — it only does that for BFCache navigations.
|
|
# Since the scripts already exist (they're not new), onNewScript won't fire,
|
|
# so the debugger's source list stays empty. Fix: also call addAllSources()
|
|
# after frame switching, just like BFCache.
|
|
replace_line '_onWindowReady\(\{ isTopLevel, isBFCache \}\)' \
|
|
'_onWindowReady({ isTopLevel, isBFCache, isFrameSwitching })' \
|
|
chrome/devtools/modules/devtools/server/actors/thread.js
|
|
replace_line 'if \(isBFCache\) {' \
|
|
'if (isBFCache || isFrameSwitching) {' \
|
|
chrome/devtools/modules/devtools/server/actors/thread.js
|
|
|
|
# Suppress "Failed to get the active browserId" error when profile recording starts
|
|
replace_line 'console\.error\(' \
|
|
'if (false) console.error(' \
|
|
chrome/devtools/modules/devtools/shared/performance-new/recording-utils.sys.mjs
|
|
|
|
# Stub out profile favicon lookup since we don't have PlacesUtils
|
|
replace_line 'return getPageFavicons\(pageUrls\);' \
|
|
'return pageUrls ? pageUrls.map(() => null) : [];' \
|
|
chrome/devtools/modules/devtools/client/performance-new/shared/background.sys.mjs
|
|
|
|
# Use our profilerViewer.xhtml to display profiles.
|
|
# We can't use basicViewer because that loads Zotero scripts, and profiling
|
|
# runs in the Browser Toolbox child process, where a second Zotero instance
|
|
# would collide with the locked database.
|
|
replace_line 'const contentBrowser = await new Promise\(resolveOnContentBrowserCreated =>' \
|
|
'if (typeof win.openWebLinkIn !== "function") {
|
|
const ww = Cc["\@mozilla.org\/embedcomp\/window-watcher;1"].getService(
|
|
Ci.nsIWindowWatcher
|
|
);
|
|
const arg = { uri: urlToLoad };
|
|
arg.wrappedJSObject = arg;
|
|
const viewerWin = ww.openWindow(
|
|
null,
|
|
"chrome:\/\/zotero\/content\/standalone\/profilerViewer.xhtml",
|
|
null,
|
|
"chrome,dialog=no,resizable,centerscreen,scrollbars",
|
|
arg
|
|
);
|
|
return await new Promise(resolve => {
|
|
viewerWin.addEventListener("load", () => {
|
|
resolve(viewerWin.document.getElementById("content"));
|
|
}, { once: true });
|
|
});
|
|
}
|
|
const contentBrowser = await new Promise(resolveOnContentBrowserCreated =>' \
|
|
chrome/devtools/modules/devtools/client/performance-new/shared/browser.js
|
|
fi
|
|
|
|
# 5.0.96.3 / 5.0.97-beta.37+ddc7be75c
|
|
VERSION=`cat version`
|
|
# 5.0.96 / 5.0.97
|
|
VERSION_NUMERIC=`perl -ne 'print and last if s/^(\d+\.\d+(\.\d+)?).*/\1/;' version`
|
|
if [ -z "$VERSION" ]; then
|
|
echo "Version number not found in version file"
|
|
exit 1
|
|
fi
|
|
rm version
|
|
|
|
echo
|
|
echo "Version: $VERSION"
|
|
|
|
# Delete Mozilla signing info if present
|
|
rm -rf META-INF
|
|
|
|
# Copy branding
|
|
cp -R "$CALLDIR"/assets/branding/locale/brand.{dtd,properties} chrome/en-US/locale/branding/
|
|
|
|
# Copy browser localization .ftl files
|
|
for locale in `ls chrome/locale/`; do
|
|
mkdir -p localization/$locale/branding
|
|
cp "$CALLDIR/assets/branding/locale/brand.ftl" localization/$locale/branding/brand.ftl
|
|
|
|
mkdir -p localization/$locale/toolkit/global
|
|
cp chrome/locale/$locale/zotero/mozilla/arrowscrollbox.ftl localization/$locale/toolkit/global
|
|
cp chrome/locale/$locale/zotero/mozilla/textActions.ftl localization/$locale/toolkit/global
|
|
cp chrome/locale/$locale/zotero/mozilla/wizard.ftl localization/$locale/toolkit/global
|
|
|
|
mkdir -p localization/$locale/browser
|
|
cp chrome/locale/$locale/zotero/mozilla/browserSets.ftl localization/$locale/browser
|
|
cp chrome/locale/$locale/zotero/mozilla/menubar.ftl localization/$locale/browser
|
|
|
|
mkdir -p localization/$locale/devtools/client
|
|
cp chrome/locale/$locale/zotero/mozilla/toolbox.ftl localization/$locale/devtools/client
|
|
|
|
# TEMP: Until we've created zotero.ftl in all locales
|
|
touch chrome/locale/$locale/zotero/zotero.ftl
|
|
cp chrome/locale/$locale/zotero/*.ftl localization/$locale/
|
|
done
|
|
|
|
# Add to chrome manifest
|
|
echo "" >> chrome.manifest
|
|
cat "$CALLDIR/assets/chrome.manifest" >> chrome.manifest
|
|
|
|
replace_line 'handle: function bch_handle\(cmdLine\) {' 'handle: function bch_handle(cmdLine) {
|
|
\/\/ TEST_OPTIONS_PLACEHOLDER
|
|
' modules/BrowserContentHandler.sys.mjs
|
|
export CALLDIR && perl -pi -e 'BEGIN { local $/; open $fh, "$ENV{CALLDIR}/assets/commandLineHandler.js"; $replacement = <$fh>; close $fh; } s/\/\/ TEST_OPTIONS_PLACEHOLDER/$replacement/' modules/BrowserContentHandler.sys.mjs
|
|
|
|
# Don't try to initialize Places, since we've removed its files
|
|
#replace_line 'this._placesInitialized = true;' 'if (true) return; this._placesInitialized = true;' components/places/PlacesBrowserStartup.sys.mjs
|
|
|
|
# Move test files to root directory
|
|
if [ $include_tests -eq 1 ]; then
|
|
cat test/chrome.manifest >> chrome.manifest
|
|
rm test/chrome.manifest
|
|
cp -R test/tests "$base_dir/tests"
|
|
fi
|
|
|
|
# Copy platform-specific assets
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
rsync -a "$CALLDIR/assets/mac/" ./
|
|
elif [ $BUILD_WIN == 1 ]; then
|
|
rsync -a "$CALLDIR/assets/win/" ./
|
|
elif [ $BUILD_LINUX == 1 ]; then
|
|
rsync -a "$CALLDIR/assets/unix/" ./
|
|
fi
|
|
|
|
# Add word processor plug-ins
|
|
echo >> chrome.manifest
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
pluginDir="$CALLDIR/modules/zotero-word-for-mac-integration"
|
|
mkdir -p "integration/word-for-mac"
|
|
cp -RH "$pluginDir/components" \
|
|
"$pluginDir/resource" \
|
|
"$pluginDir/chrome.manifest" \
|
|
"integration/word-for-mac"
|
|
echo -n "Word for Mac plugin version: "
|
|
cat "integration/word-for-mac/resource/version.txt"
|
|
echo
|
|
echo >> $prefs_file
|
|
cat "$CALLDIR/modules/zotero-word-for-mac-integration/defaults/preferences/zoteroMacWordIntegration.js" >> $prefs_file
|
|
echo >> $prefs_file
|
|
|
|
echo "manifest integration/word-for-mac/chrome.manifest" >> chrome.manifest
|
|
|
|
elif [ $BUILD_WIN == 1 ]; then
|
|
pluginDir="$CALLDIR/modules/zotero-word-for-windows-integration"
|
|
mkdir -p "integration/word-for-windows"
|
|
cp -RH "$pluginDir/components" \
|
|
"$pluginDir/resource" \
|
|
"$pluginDir/chrome.manifest" \
|
|
"integration/word-for-windows"
|
|
echo -n "Word for Windows plugin version: "
|
|
cat "integration/word-for-windows/resource/version.txt"
|
|
echo
|
|
echo >> $prefs_file
|
|
cat "$CALLDIR/modules/zotero-word-for-windows-integration/defaults/preferences/zoteroWinWordIntegration.js" >> $prefs_file
|
|
echo >> $prefs_file
|
|
|
|
echo "manifest integration/word-for-windows/chrome.manifest" >> chrome.manifest
|
|
fi
|
|
# Libreoffice plugin for all platforms
|
|
pluginDir="$CALLDIR/modules/zotero-libreoffice-integration"
|
|
mkdir -p "integration/libreoffice"
|
|
cp -RH "$pluginDir/chrome" \
|
|
"$pluginDir/components" \
|
|
"$pluginDir/resource" \
|
|
"$pluginDir/chrome.manifest" \
|
|
"integration/libreoffice"
|
|
echo -n "LibreOffice plugin version: "
|
|
cat "integration/libreoffice/resource/version.txt"
|
|
echo
|
|
echo >> $prefs_file
|
|
cat "$CALLDIR/modules/zotero-libreoffice-integration/defaults/preferences/zoteroLibreOfficeIntegration.js" >> $prefs_file
|
|
echo >> $prefs_file
|
|
|
|
echo "manifest integration/libreoffice/chrome.manifest" >> chrome.manifest
|
|
|
|
# Delete files that shouldn't be distributed
|
|
find chrome -name .DS_Store -exec rm -f {} \;
|
|
|
|
# Zip browser and Zotero files into omni.ja
|
|
if [ $quick_build -eq 1 ]; then
|
|
# If quick build, don't compress or optimize
|
|
zip -qrXD omni.ja *
|
|
else
|
|
zip -qr9XD omni.ja *
|
|
python3 "$CALLDIR/scripts/optimizejars.py" --optimize ./ ./ ./
|
|
fi
|
|
|
|
mv omni.ja ..
|
|
cd "$CALLDIR"
|
|
rm -rf "$omni_dir"
|
|
|
|
# Copy updater.ini
|
|
cp "$CALLDIR/assets/updater.ini" "$base_dir"
|
|
|
|
# Adjust chrome.manifest
|
|
#perl -pi -e 's^(chrome|resource)/^jar:zotero.jar\!/$1/^g' "$BUILD_DIR/zotero/chrome.manifest"
|
|
|
|
# Copy application.ini and modify
|
|
cp "$CALLDIR/assets/application.ini" "$app_dir/application.ini"
|
|
perl -pi -e "s/\{\{VERSION}}/$VERSION/" "$app_dir/application.ini"
|
|
perl -pi -e "s/\{\{BUILDID}}/$BUILD_ID/" "$app_dir/application.ini"
|
|
|
|
# Remove unnecessary files
|
|
find "$BUILD_DIR" -name .DS_Store -exec rm -f {} \;
|
|
|
|
# Mac
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
echo 'Building Zotero.app'
|
|
|
|
# Set up directory structure
|
|
APPDIR="$STAGE_DIR/Zotero.app"
|
|
rm -rf "$APPDIR"
|
|
mkdir "$APPDIR"
|
|
chmod 755 "$APPDIR"
|
|
cp -r "$CALLDIR/mac/Contents" "$APPDIR"
|
|
CONTENTSDIR="$APPDIR/Contents"
|
|
|
|
# Merge relevant assets from Firefox
|
|
mkdir "$CONTENTSDIR/MacOS"
|
|
cp -r "$MAC_RUNTIME_PATH/Contents/MacOS/"!(firefox|firefox-bin|crashreporter.app|minidump-analyzer|nmhproxy|pingsender|updater.app) "$CONTENTSDIR/MacOS"
|
|
cp -r "$MAC_RUNTIME_PATH/Contents/Resources/"!(application.ini|browser|defaults|precomplete|removed-files|updater.ini|update-settings.ini|webapprt*|*.icns|*.lproj) "$CONTENTSDIR/Resources"
|
|
|
|
# Add our custom ChannelPrefs.framework and change channel if not a source build
|
|
mkdir "$CONTENTSDIR/Frameworks"
|
|
tar xvf "$CALLDIR/mac/ChannelPrefs.framework.tar.xz" -C "$CONTENTSDIR/Frameworks"
|
|
if [ "$UPDATE_CHANNEL" != "source" ]; then
|
|
"$CALLDIR/mac/set-channel-prefs-channel" "$CONTENTSDIR/Frameworks/ChannelPrefs.framework/ChannelPrefs" source $UPDATE_CHANNEL
|
|
fi
|
|
|
|
# Use our own launcher
|
|
check_lfs_file "$CALLDIR/mac/zotero.xz"
|
|
xz -d --stdout "$CALLDIR/mac/zotero.xz" > "$CONTENTSDIR/MacOS/zotero"
|
|
chmod 755 "$CONTENTSDIR/MacOS/zotero"
|
|
|
|
# TEMP: Custom version of XUL with some backported Mozilla bug fixes
|
|
if [ -n "$custom_components_hash_mac" ]; then
|
|
cp "$MAC_RUNTIME_PATH/../MacOS/XUL" "$CONTENTSDIR/MacOS/"
|
|
fi
|
|
|
|
# Use our own updater, because Mozilla's requires updates signed by Mozilla
|
|
cd "$CONTENTSDIR/MacOS"
|
|
check_lfs_file "$CALLDIR/mac/updater.tar.xz"
|
|
tar xf "$CALLDIR/mac/updater.tar.xz"
|
|
|
|
# Modify Info.plist
|
|
perl -pi -e "s/\{\{VERSION\}\}/$VERSION/" "$CONTENTSDIR/Info.plist"
|
|
perl -pi -e "s/\{\{VERSION_NUMERIC\}\}/$VERSION_NUMERIC/" "$CONTENTSDIR/Info.plist"
|
|
if [ $UPDATE_CHANNEL == "beta" ] || [ $UPDATE_CHANNEL == "dev" ] || [ $UPDATE_CHANNEL == "source" ]; then
|
|
perl -pi -e "s/org\.zotero\.zotero/org.zotero.zotero-$UPDATE_CHANNEL/" "$CONTENTSDIR/Info.plist"
|
|
fi
|
|
perl -pi -e "s/\{\{VERSION\}\}/$VERSION/" "$CONTENTSDIR/Info.plist"
|
|
# Needed for "monkeypatch" Windows builds:
|
|
# http://www.nntp.perl.org/group/perl.perl5.porters/2010/08/msg162834.html
|
|
rm -f "$CONTENTSDIR/Info.plist.bak"
|
|
|
|
echo
|
|
grep -B 1 org.zotero.zotero "$CONTENTSDIR/Info.plist"
|
|
echo
|
|
grep -A 1 CFBundleShortVersionString "$CONTENTSDIR/Info.plist"
|
|
echo
|
|
grep -A 1 CFBundleVersion "$CONTENTSDIR/Info.plist"
|
|
echo
|
|
|
|
# Copy app files
|
|
rsync -a "$base_dir/" "$CONTENTSDIR/Resources/"
|
|
|
|
# Add word processor plug-ins
|
|
mkdir "$CONTENTSDIR/Resources/integration"
|
|
cp -RH "$CALLDIR/modules/zotero-libreoffice-integration/install" "$CONTENTSDIR/Resources/integration/libreoffice"
|
|
cp -RH "$CALLDIR/modules/zotero-word-for-mac-integration/install" "$CONTENTSDIR/Resources/integration/word-for-mac"
|
|
|
|
# Delete extraneous files
|
|
find "$CONTENTSDIR" -depth -type d -name .git -exec rm -rf {} \;
|
|
find "$CONTENTSDIR" \( -name .DS_Store -or -name update.rdf \) -exec rm -f {} \;
|
|
|
|
# Add Safari extensions -- this depends on signing but needs to be done before generating
|
|
# the precomplete file
|
|
#
|
|
# $SAFARI_APPEX is a stub appex built from the safari-web-extension wrapper project. The web
|
|
# extension itself comes from $SAFARI_EXT_RESOURCES (a zotero-connectors build/safari
|
|
# directory), which replaces the stub's placeholder resources here before signing.
|
|
#
|
|
# $SAFARI_APP_EXTENSION is an optional prebuilt legacy Safari App Extension, embedded
|
|
# alongside the web extension for Safari versions that can't load Developer ID web
|
|
# extensions (supported in Safari 18.4 and later). On Safari versions that can load the
|
|
# web extension, the SFSafariAppExtensionBundleIdentifiersToReplace key causes it to
|
|
# replace the App Extension.
|
|
if [[ $SIGN == 1 ]] && [[ -n "$SAFARI_APPEX" ]] && [[ -d "$SAFARI_APPEX" ]]; then
|
|
if [[ -z "${SAFARI_EXT_RESOURCES:-}" ]] || [[ ! -f "$SAFARI_EXT_RESOURCES/manifest.json" ]]; then
|
|
echo "SAFARI_EXT_RESOURCES doesn't contain a web extension -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
bundle_identifier=$(/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$APPDIR/Contents/Info.plist")
|
|
mkdir "$APPDIR/Contents/PlugIns"
|
|
|
|
webext_appex="$APPDIR/Contents/PlugIns/ZoteroSafariWebExtension.appex"
|
|
cp -R "$SAFARI_APPEX" "$webext_appex"
|
|
appex_resources="$webext_appex/Contents/Resources"
|
|
rm -rf "$appex_resources"
|
|
mkdir "$appex_resources"
|
|
cp -R "$SAFARI_EXT_RESOURCES/." "$appex_resources/"
|
|
|
|
# Show the connector version in Safari
|
|
connector_version=$(python3 -c "import json, sys; print(json.load(open(sys.argv[1]))['version'])" "$appex_resources/manifest.json")
|
|
if [[ $connector_version == *999* ]] && [ "$UPDATE_CHANNEL" != "test" ]; then
|
|
echo "Placeholder connector version $connector_version not allowed for '$UPDATE_CHANNEL' channel -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $connector_version" \
|
|
"$webext_appex/Contents/Info.plist"
|
|
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $connector_version" \
|
|
"$webext_appex/Contents/Info.plist"
|
|
|
|
# Give the appex the same bundle identifier prefix as the parent app
|
|
/usr/libexec/PlistBuddy -c "Set CFBundleIdentifier $bundle_identifier.SafariWebExtension" \
|
|
"$webext_appex/Contents/Info.plist"
|
|
|
|
# Replace the legacy App Extension on Safari versions that can load the web extension
|
|
/usr/libexec/PlistBuddy -c "Add :NSExtension:SFSafariAppExtensionBundleIdentifiersToReplace array" \
|
|
"$webext_appex/Contents/Info.plist"
|
|
/usr/libexec/PlistBuddy -c "Add :NSExtension:SFSafariAppExtensionBundleIdentifiersToReplace:0 string $bundle_identifier.SafariExtension" \
|
|
"$webext_appex/Contents/Info.plist"
|
|
|
|
# Add legacy Safari App Extension
|
|
if [[ -n "${SAFARI_APP_EXTENSION:-}" ]]; then
|
|
if [[ ! -d "$SAFARI_APP_EXTENSION" ]]; then
|
|
echo "SAFARI_APP_EXTENSION not found at $SAFARI_APP_EXTENSION -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
appext_appex="$APPDIR/Contents/PlugIns/ZoteroSafariExtension.appex"
|
|
cp -R "$SAFARI_APP_EXTENSION" "$appext_appex"
|
|
rm -rf "$appext_appex/Contents/Resources/safari/test"
|
|
/usr/libexec/PlistBuddy -c "Set CFBundleIdentifier $bundle_identifier.SafariExtension" \
|
|
"$appext_appex/Contents/Info.plist"
|
|
fi
|
|
fi
|
|
|
|
# Copy over removed-files and make a precomplete file
|
|
pushd "$CONTENTSDIR/Resources/"
|
|
cp "$CALLDIR/update-packaging/removed-files_mac" removed-files
|
|
python3 "$CALLDIR/scripts/createprecomplete.py"
|
|
if [ ! -s precomplete ]; then
|
|
echo "precomplete file not created -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
popd
|
|
|
|
# Sign
|
|
if [ $SIGN == 1 ]; then
|
|
# Unlock keychain if a password is provided (necessary for building from a shell)
|
|
if [ -n "$KEYCHAIN_PASSWORD" ]; then
|
|
security -v unlock-keychain -p "$KEYCHAIN_PASSWORD" ~/Library/Keychains/$KEYCHAIN.keychain-db
|
|
fi
|
|
# Clear extended attributes, which can cause codesign to fail
|
|
/usr/bin/xattr -cr "$APPDIR"
|
|
|
|
# Sign libraries and updater without entitlements
|
|
/usr/bin/codesign --force --options runtime --sign "$DEVELOPER_ID" \
|
|
"$APPDIR/Contents/MacOS/XUL" \
|
|
"$APPDIR/Contents/MacOS/updater.app/Contents/Frameworks/UpdateSettings.framework" \
|
|
"$APPDIR/Contents/MacOS/updater.app" \
|
|
"$APPDIR/Contents/Frameworks/ChannelPrefs.framework"
|
|
find "$APPDIR/Contents" -name '*.dylib' -print0 | xargs -0 /usr/bin/codesign --force --options runtime --sign "$DEVELOPER_ID"
|
|
|
|
# Sign bundled apps and main app bundle
|
|
entitlements_file="$CALLDIR/mac/entitlements.xml"
|
|
find "$APPDIR/Contents" -name '*.app' -not -name "updater.app" -print0 | xargs -0 /usr/bin/codesign --force --options runtime --entitlements "$entitlements_file" --sign "$DEVELOPER_ID"
|
|
|
|
# Sign .jnilib (Java native shared library) within LibreOffice extension, since notarization
|
|
# started failing without this. The .jnilib is within a .jar within the .oxt, so we have to
|
|
# extract both, sign the libraries, and then update each ZIP.
|
|
#
|
|
# TODO: Remove this block once the plugin ships a jna.jar without the macOS native
|
|
# libraries, which are never loaded (JNA is used only on Windows)
|
|
pushd "$BUILD_DIR"
|
|
mkdir libreoffice-repack
|
|
cd libreoffice-repack
|
|
unzip -q "$APPDIR/Contents/Resources/integration/libreoffice/Zotero_LibreOffice_Integration.oxt" external_jars/jna.jar
|
|
unzip -q external_jars/jna.jar 'com/sun/jna/darwin*/libjnidispatch.jnilib'
|
|
/usr/bin/codesign --force --options runtime --sign "$DEVELOPER_ID" com/sun/jna/darwin*/libjnidispatch.jnilib
|
|
zip -u external_jars/jna.jar com/sun/jna/darwin*/libjnidispatch.jnilib
|
|
zip -u "$APPDIR/Contents/Resources/integration/libreoffice/Zotero_LibreOffice_Integration.oxt" external_jars/jna.jar
|
|
cd ..
|
|
rm -rf libreoffice-repack
|
|
popd
|
|
|
|
# Sign Safari extensions
|
|
#
|
|
# Even though they're signed by Xcode, we sign them again to make sure they match the parent app signature
|
|
for appex in "$APPDIR"/Contents/PlugIns/*.appex; do
|
|
if [ ! -d "$appex" ]; then
|
|
continue
|
|
fi
|
|
echo
|
|
# Extract entitlements, which differ from parent app
|
|
/usr/bin/codesign -d --entitlements "$BUILD_DIR/safari-entitlements.plist" --xml "$appex"
|
|
|
|
find "$appex/Contents" -name '*.dylib' -exec /usr/bin/codesign --force --options runtime --entitlements "$entitlements_file" --sign "$DEVELOPER_ID" {} \;
|
|
/usr/bin/codesign --force --options runtime --entitlements "$BUILD_DIR/safari-entitlements.plist" --sign "$DEVELOPER_ID" "$appex"
|
|
done
|
|
|
|
# Sign final app package
|
|
echo
|
|
/usr/bin/codesign --force --options runtime --entitlements "$entitlements_file" --sign "$DEVELOPER_ID" "$APPDIR"
|
|
|
|
# Verify app
|
|
/usr/bin/codesign --verify -vvvv "$APPDIR"
|
|
# Verify Safari extensions
|
|
for appex in "$APPDIR"/Contents/PlugIns/*.appex; do
|
|
if [ ! -d "$appex" ]; then
|
|
continue
|
|
fi
|
|
echo
|
|
/usr/bin/codesign --verify -vvvv "$appex"
|
|
done
|
|
fi
|
|
|
|
# Build and notarize disk image
|
|
if [ $PACKAGE == 1 ]; then
|
|
if [ $MAC_NATIVE == 1 ]; then
|
|
echo "Creating Mac installer"
|
|
dmg="$DIST_DIR/Zotero-$VERSION.dmg"
|
|
"$CALLDIR/mac/pkg-dmg" --source "$STAGE_DIR/Zotero.app" \
|
|
--target "$dmg" \
|
|
--sourcefile --volname Zotero --copy "$CALLDIR/mac/DSStore:/.DS_Store" \
|
|
--symlink /Applications:"/Drag Here to Install" > /dev/null
|
|
|
|
if [ "$UPDATE_CHANNEL" != "test" ]; then
|
|
# Upload disk image to Apple
|
|
"$CALLDIR/scripts/notarize_mac_app" "$dmg"
|
|
echo
|
|
|
|
# Staple notarization info to disk image
|
|
"$CALLDIR/scripts/notarization_stapler" "$dmg"
|
|
|
|
echo "Notarization complete"
|
|
else
|
|
echo "Test build -- skipping notarization"
|
|
fi
|
|
echo
|
|
else
|
|
echo 'Not building on Mac; creating Mac distribution as a zip file'
|
|
rm -f "$DIST_DIR/Zotero_mac.zip"
|
|
cd "$STAGE_DIR" && zip -rqX "$DIST_DIR/Zotero-${VERSION}_mac.zip" Zotero.app
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Windows
|
|
if [ $BUILD_WIN == 1 ]; then
|
|
echo "Building Windows common"
|
|
|
|
COMMON_APPDIR="$STAGE_DIR/Zotero_common"
|
|
mkdir "$COMMON_APPDIR"
|
|
|
|
# Package non-arch-specific components
|
|
if [ $PACKAGE -eq 1 ]; then
|
|
# Copy installer files
|
|
cp -r "$CALLDIR/win/installer" "$BUILD_DIR/win_installer"
|
|
|
|
perl -pi -e "s/\{\{VERSION}}/$VERSION/" "$BUILD_DIR/win_installer/defines.nsi"
|
|
mkdir "$COMMON_APPDIR/uninstall"
|
|
|
|
# Compress 7zSD.sfx
|
|
upx --best -o "`cygpath -w \"$BUILD_DIR/7zSD.sfx\"`" \
|
|
"`cygpath -w \"$CALLDIR/win/installer/7zstub/firefox/7zSD.sfx\"`" > /dev/null
|
|
|
|
fi
|
|
|
|
if [[ -n $arch ]]; then
|
|
archs=("$(get_canonical_arch w $arch)");
|
|
else
|
|
archs=(win-x64 win-arm64 win32);
|
|
fi
|
|
for arch in "${archs[@]}"; do
|
|
echo "Building Zotero_$arch"
|
|
|
|
runtime_path="${WIN_RUNTIME_PATH_PREFIX}$arch"
|
|
|
|
# Set up directory
|
|
APPDIR="$STAGE_DIR/Zotero_$arch"
|
|
mkdir "$APPDIR"
|
|
|
|
# Copy relevant assets from Firefox
|
|
#
|
|
# 'i686' is a huge directory containing x86 versions of xul.dll and other files in
|
|
# Firefox ARM64 builds for use with the EME DRM plugins
|
|
cp -R "$runtime_path"/!(application.ini|browser|crashreporter*|default-browser-agent.exe|defaultagent*|defaults|devtools-files|firefox*|i686|maintenanceservice*|minidump-analyzer.exe|pingsender.exe|private_browsing*|precomplete|removed-files|uninstall|update*) "$APPDIR"
|
|
|
|
# Copy zotero.exe, which is built directly from Firefox source and then modified by
|
|
# ResourceHacker to add icons
|
|
check_lfs_file "$CALLDIR/win/zotero.exe.tar.xz"
|
|
tar xf "$CALLDIR/win/zotero.exe.tar.xz" --to-stdout zotero_$arch.exe > "$APPDIR/zotero.exe"
|
|
|
|
# Use our own updater, because Mozilla's requires updates signed by Mozilla
|
|
check_lfs_file "$CALLDIR/win/updater.exe.tar.xz"
|
|
tar xf "$CALLDIR/win/updater.exe.tar.xz" --to-stdout updater-$arch.exe > "$APPDIR/updater.exe"
|
|
|
|
# Update .exe version numbers (only possible on Windows)
|
|
if [ $WIN_NATIVE == 1 ]; then
|
|
# FileVersion is limited to four integers, so it won't be properly updated for non-release
|
|
# builds (e.g., we'll show 5.0.97.0 for 5.0.97-beta.37). ProductVersion will be the full
|
|
# version string.
|
|
rcedit "`cygpath -w \"$APPDIR/zotero.exe\"`" \
|
|
--set-file-version "$VERSION_NUMERIC" \
|
|
--set-product-version "$VERSION"
|
|
rcedit "`cygpath -w \"$APPDIR/updater.exe\"`" \
|
|
--set-file-version "$VERSION_NUMERIC" \
|
|
--set-product-version "$VERSION"
|
|
fi
|
|
|
|
# Copy app files
|
|
rsync -a "$base_dir/" "$APPDIR/"
|
|
#mv "$APPDIR/app/application.ini" "$APPDIR/"
|
|
|
|
# Copy in common files
|
|
rsync -a "$COMMON_APPDIR/" "$APPDIR/"
|
|
|
|
cat "$CALLDIR/win/installer/updater_append.ini" >> "$APPDIR/updater.ini"
|
|
|
|
# Add devtools
|
|
#if [ $DEVTOOLS -eq 1 ]; then
|
|
# # Create devtools.jar
|
|
# cd "$BUILD_DIR"
|
|
# mkdir -p devtools/locale
|
|
# cp -r "$runtime_path"/devtools-files/chrome/devtools/* devtools/
|
|
# cp -r "$runtime_path"/devtools-files/chrome/locale/* devtools/locale/
|
|
# cd devtools
|
|
# zip -r -q ../devtools.jar *
|
|
# cd ..
|
|
# rm -rf devtools
|
|
# mv devtools.jar "$APPDIR"
|
|
#
|
|
# cp "$runtime_path/devtools-files/components/interfaces.xpt" "$APPDIR/components/"
|
|
#fi
|
|
|
|
# Add word processor plug-ins
|
|
mkdir -p "$APPDIR/integration"
|
|
cp -RH "$CALLDIR/modules/zotero-libreoffice-integration/install" "$APPDIR/integration/libreoffice"
|
|
cp -RH "$CALLDIR/modules/zotero-word-for-windows-integration/install" "$APPDIR/integration/word-for-windows"
|
|
if [ $arch = 'win32' ]; then
|
|
rm "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_x64.dll"
|
|
rm "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_ARM64.dll"
|
|
elif [ $arch = 'win-x64' ]; then
|
|
mv "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_x64.dll" \
|
|
"$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration.dll"
|
|
rm "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_ARM64.dll"
|
|
elif [ $arch = 'win-arm64' ]; then
|
|
mv "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_ARM64.dll" \
|
|
"$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration.dll"
|
|
rm "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration_x64.dll"
|
|
fi
|
|
|
|
# Delete extraneous files
|
|
find "$APPDIR" -depth -type d -name .git -exec rm -rf {} \;
|
|
find "$APPDIR" \( -name .DS_Store -or -name '.git*' -or -name '.travis.yml' -or -name update.rdf -or -name '*.bak' \) -exec rm -f {} \;
|
|
find "$APPDIR" \( -name '*.exe' -or -name '*.dll' \) -exec chmod 755 {} \;
|
|
|
|
if [[ $PACKAGE -eq 1 ]] && [[ $SIGN -eq 1 ]]; then
|
|
"$CALLDIR/win/codesign" "$APPDIR/zotero.exe" "$SIGNATURE_DESC"
|
|
sleep $SIGNTOOL_DELAY
|
|
"$CALLDIR/win/codesign" "$APPDIR/updater.exe" "$SIGNATURE_DESC Updater"
|
|
sleep $SIGNTOOL_DELAY
|
|
# Re-sign modified xul.dll
|
|
"$CALLDIR/win/codesign" "$APPDIR/xul.dll" "$SIGNATURE_DESC"
|
|
sleep $SIGNTOOL_DELAY
|
|
"$CALLDIR/win/codesign" "$APPDIR/integration/word-for-windows/libzoteroWinWordIntegration.dll" "$SIGNATURE_DESC Word Plugin"
|
|
fi
|
|
|
|
# Copy over removed-files and make a precomplete file
|
|
pushd "$APPDIR"
|
|
cp "$CALLDIR/update-packaging/removed-files_$arch" removed-files
|
|
python3 "$CALLDIR/scripts/createprecomplete.py"
|
|
if [ ! -s precomplete ]; then
|
|
echo "precomplete file not created -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
popd
|
|
|
|
if [ $PACKAGE -eq 1 ]; then
|
|
if [ $WIN_NATIVE -eq 1 ]; then
|
|
echo "Creating Windows installer"
|
|
# Build uninstaller
|
|
if [ "$arch" = "win32" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /V1 "`cygpath -w \"$BUILD_DIR/win_installer/uninstaller.nsi\"`"
|
|
elif [ "$arch" = "win-x64" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /DHAVE_64BIT_BUILD /V1 "`cygpath -w \"$BUILD_DIR/win_installer/uninstaller.nsi\"`"
|
|
elif [ "$arch" = "win-arm64" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /DHAVE_64BIT_BUILD /D_ARM64_ /V1 "`cygpath -w \"$BUILD_DIR/win_installer/uninstaller.nsi\"`"
|
|
fi
|
|
|
|
mv "$BUILD_DIR/win_installer/helper.exe" "$APPDIR/uninstall"
|
|
|
|
if [ $SIGN -eq 1 ]; then
|
|
"$CALLDIR/win/codesign" "$APPDIR/uninstall/helper.exe" "$SIGNATURE_DESC Uninstaller"
|
|
sleep $SIGNTOOL_DELAY
|
|
fi
|
|
|
|
if [ "$arch" = "win32" ]; then
|
|
INSTALLER_PATH="$DIST_DIR/Zotero-${VERSION}_win32_setup.exe"
|
|
elif [ "$arch" = "win-x64" ]; then
|
|
INSTALLER_PATH="$DIST_DIR/Zotero-${VERSION}_x64_setup.exe"
|
|
elif [ "$arch" = "win-arm64" ]; then
|
|
INSTALLER_PATH="$DIST_DIR/Zotero-${VERSION}_arm64_setup.exe"
|
|
fi
|
|
|
|
# Stage installer
|
|
INSTALLER_STAGE_DIR="$BUILD_DIR/win_installer/staging"
|
|
rm -rf "$INSTALLER_STAGE_DIR"
|
|
mkdir "$INSTALLER_STAGE_DIR"
|
|
cp -r "$APPDIR" "$INSTALLER_STAGE_DIR/core"
|
|
|
|
# Build and sign setup.exe
|
|
if [ "$arch" = "win32" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /V1 "`cygpath -w \"$BUILD_DIR/win_installer/installer.nsi\"`"
|
|
elif [ "$arch" = "win-x64" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /DHAVE_64BIT_BUILD /V1 "`cygpath -w \"$BUILD_DIR/win_installer/installer.nsi\"`"
|
|
elif [ "$arch" = "win-arm64" ]; then
|
|
"`cygpath -u \"${NSIS_DIR}makensis.exe\"`" /DHAVE_64BIT_BUILD /D_ARM64_ /V1 "`cygpath -w \"$BUILD_DIR/win_installer/installer.nsi\"`"
|
|
fi
|
|
|
|
mv "$BUILD_DIR/win_installer/setup.exe" "$INSTALLER_STAGE_DIR"
|
|
|
|
if [ $SIGN == 1 ]; then
|
|
"$CALLDIR/win/codesign" "$INSTALLER_STAGE_DIR/setup.exe" "$SIGNATURE_DESC Setup"
|
|
sleep $SIGNTOOL_DELAY
|
|
fi
|
|
|
|
# Compress application
|
|
cd "$INSTALLER_STAGE_DIR" && 7z a -r -t7z "`cygpath -w \"$BUILD_DIR/app_$arch.7z\"`" \
|
|
-mx -m0=BCJ2 -m1=LZMA:d24 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3 > /dev/null
|
|
|
|
# Combine 7zSD.sfx and app.tag into setup.exe
|
|
cat "$BUILD_DIR/7zSD.sfx" "$CALLDIR/win/installer/app.tag" \
|
|
"$BUILD_DIR/app_$arch.7z" > "$INSTALLER_PATH"
|
|
|
|
# Sign installer .exe
|
|
if [ $SIGN == 1 ]; then
|
|
"$CALLDIR/win/codesign" "$INSTALLER_PATH" "$SIGNATURE_DESC Installer"
|
|
fi
|
|
|
|
chmod 755 "$INSTALLER_PATH"
|
|
else
|
|
echo 'Not building on Windows; only building zip file'
|
|
fi
|
|
cd "$STAGE_DIR"
|
|
zip -rqX "$DIST_DIR/Zotero-${VERSION}_$arch.zip" Zotero_$arch
|
|
fi
|
|
done
|
|
|
|
rm -rf "$COMMON_APPDIR"
|
|
fi
|
|
|
|
# Linux
|
|
if [ $BUILD_LINUX == 1 ]; then
|
|
if [[ -n $arch ]]; then
|
|
archs=("$(get_canonical_arch l $arch)")
|
|
else
|
|
archs=(x64 arm64 i686)
|
|
fi
|
|
for arch in "${archs[@]}"; do
|
|
[[ $arch == x64 ]] && arch="x86_64"
|
|
|
|
runtime_path="${LINUX_RUNTIME_PATH_PREFIX}${arch}"
|
|
|
|
# Set up directory
|
|
echo 'Building Zotero_linux-'$arch
|
|
APPDIR="$STAGE_DIR/Zotero_linux-$arch"
|
|
rm -rf "$APPDIR"
|
|
mkdir "$APPDIR"
|
|
|
|
# Merge relevant assets from Firefox
|
|
cp -r "$runtime_path/"!(application.ini|browser|defaults|devtools-files|crashreporter|crashreporter.ini|firefox|pingsender|precomplete|removed-files|run-mozilla.sh|update-settings.ini|updater|updater.ini) "$APPDIR"
|
|
|
|
# Use our own launcher that calls the original Firefox executable with -app
|
|
mv "$APPDIR"/firefox-bin "$APPDIR"/zotero-bin
|
|
cp "$CALLDIR/linux/zotero" "$APPDIR"/zotero
|
|
|
|
# Copy Ubuntu launcher files
|
|
cp "$CALLDIR/linux/zotero.desktop" "$APPDIR"
|
|
cp "$CALLDIR/linux/set_launcher_icon" "$APPDIR"
|
|
|
|
# Use our own updater, because Mozilla's requires updates signed by Mozilla
|
|
check_lfs_file "$CALLDIR/linux/updater.tar.xz"
|
|
tar xf "$CALLDIR/linux/updater.tar.xz" --to-stdout updater-$arch > "$APPDIR/updater"
|
|
chmod 755 "$APPDIR/updater"
|
|
|
|
# Copy app files
|
|
rsync -a "$base_dir/" "$APPDIR/"
|
|
|
|
# Add word processor plug-ins
|
|
mkdir "$APPDIR/integration"
|
|
cp -RH "$CALLDIR/modules/zotero-libreoffice-integration/install" "$APPDIR/integration/libreoffice"
|
|
|
|
# Firefox includes an 'icons' folder with updater.png, but some Linux distro builds omit it
|
|
mkdir -p "$APPDIR/icons"
|
|
# Copy icons
|
|
cp "$CALLDIR/linux/icons/icon32.png" "$APPDIR/icons/"
|
|
cp "$CALLDIR/linux/icons/icon64.png" "$APPDIR/icons/"
|
|
cp "$CALLDIR/linux/icons/icon128.png" "$APPDIR/icons/"
|
|
cp "$CALLDIR/linux/icons/symbolic.svg" "$APPDIR/icons/"
|
|
|
|
# Delete extraneous files
|
|
find "$APPDIR" -depth -type d -name .git -exec rm -rf {} \;
|
|
find "$APPDIR" \( -name .DS_Store -or -name update.rdf \) -exec rm -f {} \;
|
|
|
|
# Copy over removed-files and make a precomplete file
|
|
pushd "$APPDIR"
|
|
cp "$CALLDIR/update-packaging/removed-files_linux-$arch" removed-files
|
|
python3 "$CALLDIR/scripts/createprecomplete.py"
|
|
if [ ! -s precomplete ]; then
|
|
echo "precomplete file not created -- aborting" 2>&1
|
|
exit 1
|
|
fi
|
|
popd
|
|
|
|
if [ $PACKAGE == 1 ]; then
|
|
# Create tar
|
|
rm -f "$DIST_DIR/Zotero-${VERSION}_linux-$arch.tar.xz"
|
|
cd "$STAGE_DIR"
|
|
tar -cJf "$DIST_DIR/Zotero-${VERSION}_linux-$arch.tar.xz" "Zotero_linux-$arch"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
rm -rf $BUILD_DIR
|