diff --git a/modules/misc/news.nix b/modules/misc/news.nix index a20a8d373..bee8d3900 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1222,6 +1222,32 @@ in A new module is available: 'programs.readline'. ''; } + + { + time = "2020-03-15T16:55:28+00:00"; + condition = config.programs.firefox.enable; + message = '' + In anticipation of Firefox dropping support for extension + sideloading[1], we now install extensions directly to + Firefox profiles managed through Home Manager's + + 'programs.firefox.profiles' + + option. + + Unfortunately this will most likely trigger an "Existing + file is in the way" error when activating your configuration + since Firefox keeps a copy of the add-on in the location + Home Manager wants to overwrite. If this is the case, remove + the listed '.xpi' files and try again. + + This change also means that extensions installed through + Home Manager may disappear from unmanaged profiles in future + Firefox releases. + + [1] https://blog.mozilla.org/addons/2019/10/31/firefox-to-discontinue-sideloaded-extensions/ + ''; + } ]; }; } diff --git a/modules/programs/firefox.nix b/modules/programs/firefox.nix index 708b05417..1db2952c2 100644 --- a/modules/programs/firefox.nix +++ b/modules/programs/firefox.nix @@ -6,8 +6,21 @@ let cfg = config.programs.firefox; + mozillaConfigPath = ".mozilla"; + + firefoxConfigPath = "${mozillaConfigPath}/firefox"; + + profilesPath = firefoxConfigPath; + + # The extensions path shared by all profiles; will not be supported + # by future Firefox versions. extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"; + extensionsEnvPkg = pkgs.buildEnv { + name = "hm-firefox-extensions"; + paths = cfg.extensions; + }; + profiles = flip mapAttrs' cfg.profiles (_: profile: nameValuePair "Profile${toString profile.id}" { @@ -250,32 +263,30 @@ in home.file = mkMerge ( [{ - ".mozilla/${extensionPath}" = mkIf (cfg.extensions != []) ( - let - extensionsEnv = pkgs.buildEnv { - name = "hm-firefox-extensions"; - paths = cfg.extensions; - }; - in { - source = "${extensionsEnv}/share/mozilla/${extensionPath}"; - recursive = true; - } - ); + "${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) { + source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; + recursive = true; + }; - ".mozilla/firefox/profiles.ini" = mkIf (cfg.profiles != {}) { + "${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) { text = profilesIni; }; }] ++ flip mapAttrsToList cfg.profiles (_: profile: { - ".mozilla/firefox/${profile.path}/chrome/userChrome.css" = + "${profilesPath}/${profile.path}/chrome/userChrome.css" = mkIf (profile.userChrome != "") { text = profile.userChrome; }; - ".mozilla/firefox/${profile.path}/user.js" = + "${profilesPath}/${profile.path}/user.js" = mkIf (profile.settings != {} || profile.extraConfig != "") { text = mkUserJs profile.settings profile.extraConfig; }; + + "${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) { + source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; + recursive = true; + }; }) ); };