Adding nix firefox extension support

This commit is contained in:
Luis Hebendanz 2020-06-28 15:55:07 +02:00 committed by Jörg Thalheim
parent 1cd16d50b4
commit eedee46f2f
No known key found for this signature in database
GPG key ID: 003F2096411B5F92

View file

@ -1,4 +1,6 @@
{ stdenv, lib, makeDesktopItem, makeWrapper, lndir, config
{ stdenv, lib, makeDesktopItem, makeWrapper, lndir, config,
replace, fetchurl, zip, unzip, jq
## various stuff that can be plugged in
, flashplayer, hal-flash
@ -31,6 +33,12 @@ let
, forceWayland ? false
, useGlvnd ? true
, cfg ? config.${browserName} or {}
## Following options are needed for extra prefs & policies
, extraPrefs ? ""
, extraPolicies ? {}
, firefoxLibName ? "firefox"
, extraExtensions ? [ ]
}:
assert forceWayland -> (browser ? gtk3); # Can only use the wayland backend if gtk3 is being used
@ -81,6 +89,88 @@ let
++ pkcs11Modules;
gtk_modules = [ libcanberra-gtk2 ];
#########################
# #
# EXTRA PREF CHANGES #
# #
#########################
policiesJson = builtins.toFile "policies.json"
(builtins.toJSON enterprisePolicies);
extensions = builtins.map (a:
if ! (builtins.hasAttr "name" a) || ! (builtins.isString a.name) then
throw "Firefox addon needs a name attribute"
else if ! (builtins.hasAttr "url" a) || ! (builtins.isString a.url) then
throw "Addon ${a.pname} needs an url"
else if ! (builtins.hasAttr "sha256" a) || ! (builtins.isString a.sha256) then
throw "Addon ${a.pname} needs an sha256 checksum"
else stdenv.mkDerivation rec {
pname = a.name;
version = "1.0";
src = fetchurl {
url = a.url;
sha256 = a.sha256;
};
phases = [ "buildPhase" ];
extid = "${a.sha256}@${a.name}";
buildInputs = [ zip unzip jq ];
buildPhase = ''
UUID="${extid}"
mkdir -p "$out/$UUID"
unzip -q ${src} -d "$out/$UUID"
NEW_MANIFEST=$(jq '. + {"applications": { "gecko": { "id": "${extid}" }}, "browser_specific_settings":{"gecko":{"id": "${extid}"}}}' "$out/$UUID/manifest.json")
echo "$NEW_MANIFEST" > "$out/$UUID/manifest.json"
cd "$out/$UUID"
zip -r -q -FS "$out/$UUID.xpi" *
rm -r "$out/$UUID"
'';
}
) extraExtensions;
enterprisePolicies =
{
policies = {
DisableAppUpdate = true;
} //
{
ExtensionSettings = {
"*" = {
blocked_install_message = "You can't have manual extension mixed with nix extensions";
installation_mode = "blocked";
};
} // lib.foldr (e: ret:
ret // {
"${e.extid}" = {
installation_mode = "allowed";
};
}
) {} extensions;
}
// extraPolicies;
};
mozillaCfg = builtins.toFile "mozilla.cfg" ''
// First line must be a comment
// Disables addon signature checking
// to be able to install addons that do not have an extid
// Security is maintained because only user whitelisted addons
// with a checksum can be installed
lockPref("xpinstall.signatures.required", false);
${extraPrefs}
'';
#############################
# #
# END EXTRA PREF CHANGES #
# #
#############################
in stdenv.mkDerivation {
inherit pname version;
@ -106,6 +196,7 @@ let
nativeBuildInputs = [ makeWrapper lndir ];
buildInputs = lib.optional (browser ? gtk3) browser.gtk3;
buildCommand = lib.optionalString stdenv.isDarwin ''
mkdir -p $out/Applications
cp -R --no-preserve=mode,ownership ${browser}/Applications/${browserName}.app $out/Applications
@ -117,7 +208,66 @@ let
exit 1
fi
makeWrapper "$(readlink -v --canonicalize-existing "${browser}${browser.execdir or "/bin"}/${browserName}")" \
#########################
# #
# EXTRA PREF CHANGES #
# #
#########################
# Link the runtime. The executable itself has to be copied,
# because it will resolve paths relative to its true location.
# Any symbolic links have to be replicated as well.
cd "${browser}"
find . -type d -exec mkdir -p "$out"/{} \;
find . -type f \( -not -name "${browserName}" \) -exec ln -sT "${browser}"/{} "$out"/{} \;
find . -type f -name "${browserName}" -print0 | while read -d $'\0' f; do
cp -P --no-preserve=mode,ownership "${browser}/$f" "$out/$f"
chmod a+rwx "$out/$f"
done
# fix links and absolute references
cd "${browser}"
find . -type l -print0 | while read -d $'\0' l; do
target="$(readlink "$l" | ${replace}/bin/replace-literal -es -- "${browser}" "$out")"
ln -sfT "$target" "$out/$l"
done
# This will not patch binaries, only "text" files.
# Its there for the wrapper mostly.
cd "$out"
${replace}/bin/replace-literal -esfR -- "${browser}" "$out"
# create the wrapper
executablePrefix="$out${browser.execdir or "/bin"}"
executablePath="$executablePrefix/${browserName}"
if [ ! -x "$executablePath" ]
then
echo "cannot find executable file \`${browser}${browser.execdir or "/bin"}/${browserName}'"
exit 1
fi
if [ ! -L "$executablePath" ]
then
# Careful here, the file at executablePath may already be
# a wrapper. That is why we postfix it with -old instead
# of -wrapped.
oldExe="$executablePrefix"/".${browserName}"-old
mv "$executablePath" "$oldExe"
else
oldExe="$(readlink -v --canonicalize-existing "$executablePath")"
fi
if [ ! -x "${browser}${browser.execdir or "/bin"}/${browserName}" ]
then
echo "cannot find executable file \`${browser}${browser.execdir or "/bin"}/${browserName}'"
exit 1
fi
makeWrapper "$oldExe" \
"$out${browser.execdir or "/bin"}/${browserName}${nameSuffix}" \
--suffix-each MOZ_PLUGIN_PATH ':' "$plugins" \
--suffix LD_LIBRARY_PATH ':' "$libs" \
@ -137,6 +287,11 @@ let
--suffix XDG_DATA_DIRS : '${gnome3.adwaita-icon-theme}/share'
''
}
#############################
# #
# END EXTRA PREF CHANGES #
# #
#############################
if [ -e "${browser}/share/icons" ]; then
mkdir -p "$out/share"
@ -166,6 +321,43 @@ let
# For manpages, in case the program supplies them
mkdir -p $out/nix-support
echo ${browser} > $out/nix-support/propagated-user-env-packages
#########################
# #
# EXTRA PREF CHANGES #
# #
#########################
# user customization
mkdir -p $out/lib/${firefoxLibName}
# creating policies.json
mkdir -p "$out/lib/${firefoxLibName}/distribution"
POL_PATH="$out/lib/${firefoxLibName}/distribution/policies.json"
rm -f "$POL_PATH"
cat ${policiesJson} >> "$POL_PATH"
# preparing for autoconfig
mkdir -p "$out/lib/${firefoxLibName}/defaults/pref"
cat > "$out/lib/${firefoxLibName}/defaults/pref/autoconfig.js" <<EOF
pref("general.config.filename", "mozilla.cfg");
pref("general.config.obscure_value", 0);
EOF
cat > "$out/lib/${firefoxLibName}/mozilla.cfg" < ${mozillaCfg}
mkdir -p $out/lib/${firefoxLibName}/distribution/extensions
for i in ${toString extensions}; do
ln -s -t $out/lib/${firefoxLibName}/distribution/extensions $i/*
done
#############################
# #
# END EXTRA PREF CHANGES #
# #
#############################
'';
preferLocalBuild = true;