~ruther/guix-local

25043e01b6cb6696ffdc6cdedd9cdf8235bb695c — Clément Lassieur 2 years ago a25a492
gnu: icecat: Support Guix packaged extensions and native manifests.

* gnu/build/icecat-extension.scm: New file with a MAKE-ICECAT-EXTENSION
procedure that makes sure the add-on directory is a symlink, so that Icecat
can normalize it into a package store path.
* gnu/local.mk (dist_patch_DATA): Register it, as well as new patches.
* gnu/packages/browser-extensions.scm (ublock-origin)[properties]: Store the
add-on ID so that it is accessible in MAKE-ICECAT-EXTENSION.
[arguments]: Use the add-on ID as root directory.
(ublock-origin/icecat): New procedure.
* gnu/packages/gnuzilla.scm (icecat-minimal)[arguments]: Rewrite the unused
'apply-guix-specific-patches' phase so that it applies the following two
patches.
[native-search-paths]: New field.
* gnu/packages/patches/icecat-compare-paths.patch: New patch that compares
add-on paths (which are package store paths) to detect package changes.
* gnu/packages/patches/icecat-use-system-wide-dir.patch: New patch that
replaces "/usr/lib/mozilla" (the system-wide directory for extensions and
native manifests) with "$ICECAT_SYSTEM_DIR".
A gnu/build/icecat-extension.scm => gnu/build/icecat-extension.scm +70 -0
@@ 0,0 1,70 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020, 2021 Marius Bakke <marius@gnu.org>
;;; Copyright © 2023 Clément Lassieur <clement@lassieur.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix 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.
;;;
;;; GNU Guix 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 GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu build icecat-extension)
  #:use-module (guix gexp)
  #:use-module (guix packages)
  #:use-module (guix build-system trivial)
  #:export (make-icecat-extension))

(define* (make-icecat-extension pkg #:optional (pkg-output "out"))
  "Create an Icecat extension from package PKG and return a package that,
when installed, will make the extension contained in PKG available as an
Icecat browser extension.  PKG-OUTPUT specifies which output of PKG to use."
  (package
    (inherit pkg)
    (name (string-append (package-name pkg) "-icecat"))
    (native-inputs '())
    (inputs '())
    (propagated-inputs (package-propagated-inputs pkg))
    (outputs '("out"))
    (build-system trivial-build-system)
    (arguments
     (list
      #:modules '((guix build utils))
      #:builder
      #~(begin
          (use-modules (guix build utils))
          (let* ((addon-id #$(assq-ref (package-properties pkg) 'addon-id))
                 (moz-app-id "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}")
                 (search-dir (string-append #$output "/lib/icecat/extensions/"
                                            moz-app-id)))
            ;; Icecat's iterates over `search-dir` for directories.  If a
            ;; directory's name is not a valid add-on ID, it is ignored.  See
            ;; `DirectoryLocation::readAddons()` in XPIProvider.jsm.

            ;; This directory has to be a symlink, because Icecat's
            ;; `_readLinkFile(aFile)` calls `normalize()` only if `aFile` is a
            ;; symlink.

            ;; Normalizing is required because Icecat compares the add-on path
            ;; against its local database to know if there is an extension
            ;; update.  We want the add-on path to be the package store path,
            ;; so that a path change is detected every time the package is
            ;; updated.  See `updateExistingAddon()` in XPIDatabase.jsm, with
            ;; our patch `icecat-compare-paths.patch`.

            ;; We don't want the add-on path to be the profile store path,
            ;; which would change too often.  We don't want the add-on path to
            ;; be hard-coded either because it would never change (but it
            ;; wouldn't make sense anyway).

            (mkdir-p search-dir)
            (symlink (in-vicinity (ungexp pkg pkg-output) addon-id)
                     (in-vicinity search-dir addon-id))))))))

M gnu/local.mk => gnu/local.mk +3 -0
@@ 762,6 762,7 @@ GNU_SYSTEM_MODULES =				\
  %D%/build/chromium-extension.scm		\
  %D%/build/cross-toolchain.scm			\
  %D%/build/dbus-service.scm			\
  %D%/build/icecat-extension.scm		\
  %D%/build/image.scm				\
  %D%/build/jami-service.scm			\
  %D%/build/file-systems.scm			\


@@ 1415,8 1416,10 @@ dist_patch_DATA =						\
  %D%/packages/patches/icecat-makeicecat.patch			\
  %D%/packages/patches/icecat-102-makeicecat.patch		\
  %D%/packages/patches/icecat-avoid-bundled-libraries.patch	\
  %D%/packages/patches/icecat-compare-paths.patch		\
  %D%/packages/patches/icecat-use-system-graphite2+harfbuzz.patch	\
  %D%/packages/patches/icecat-use-system-media-libs.patch	\
  %D%/packages/patches/icecat-use-system-wide-dir.patch		\
  %D%/packages/patches/icedtea-7-hotspot-aarch64-use-c++98.patch	\
  %D%/packages/patches/icedtea-7-hotspot-pointer-comparison.patch	\
  %D%/packages/patches/icu4c-fix-TestHebrewCalendarInTemporalLeapYear.patch	\

M gnu/packages/browser-extensions.scm => gnu/packages/browser-extensions.scm +11 -3
@@ 1,6 1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020, 2021 Marius Bakke <marius@gnu.org>
;;; Copyright © 2023 Nicolas Graves <ngraves@ngraves.fr>
;;; Copyright © 2023 Clément Lassieur <clement@lassieur.org>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 25,6 26,7 @@
  #:use-module (guix build-system gnu)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu build chromium-extension)
  #:use-module (gnu build icecat-extension)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages python))



@@ 98,6 100,7 @@ supported content to the Kodi media center.")
                "1i8rnij3sbwg6vj6znprrsca0n5xjzhmhppaa8v6jyxg6wrrfch1"))))
    (build-system gnu-build-system)
    (outputs '("xpi" "firefox" "chromium"))
    (properties '((addon-id . "uBlock0@raymondhill.net")))
    (arguments
     (list
      #:tests? #f                      ;no tests


@@ 125,9 128,11 @@ supported content to the Kodi media center.")
              (invoke "./tools/make-chromium.sh")))
          (add-after 'build-chromium 'install
            (lambda* (#:key outputs #:allow-other-keys)
              (let ((firefox (assoc-ref outputs "firefox"))
                    (xpi (assoc-ref outputs "xpi"))
                    (chromium (assoc-ref outputs "chromium")))
              (let* ((addon-id #$(assq-ref properties 'addon-id))
                     (firefox (in-vicinity
                               (assoc-ref outputs "firefox") addon-id))
                     (xpi (assoc-ref outputs "xpi"))
                     (chromium (assoc-ref outputs "chromium")))
                (install-file "dist/build/uBlock0.firefox.xpi"
                              (string-append xpi "/lib/mozilla/extensions"))
                (copy-recursively "dist/build/uBlock0.firefox" firefox)


@@ 142,3 147,6 @@ ungoogled-chromium.")

(define-public ublock-origin/chromium
  (make-chromium-extension ublock-origin "chromium"))

(define-public ublock-origin/icecat
  (make-icecat-extension ublock-origin "firefox"))

M gnu/packages/gnuzilla.scm => gnu/packages/gnuzilla.scm +12 -10
@@ 885,16 885,13 @@ variable defined below.  It requires guile-json to be installed."
      #:phases
      #~(modify-phases %standard-phases
          (add-after 'unpack 'apply-guix-specific-patches
            (lambda* (#:key inputs native-inputs #:allow-other-keys)
              (let ((patch (search-input-file inputs "bin/patch")))
                (for-each (match-lambda
                            ((label . file)
                             (when (and (string-prefix? "icecat-" label)
                                        (string-suffix? ".patch" label))
                               (format #t "applying '~a'...~%" file)
                               (invoke patch "--force" "--no-backup-if-mismatch"
                                       "-p1" "--input" file))))
                          (or native-inputs inputs)))))
            (lambda _
              (for-each
               (lambda (file) (invoke "patch" "--force" "-p1" "-i" file))
               '(#$(local-file
                    (search-patch "icecat-compare-paths.patch"))
                 #$(local-file
                    (search-patch "icecat-use-system-wide-dir.patch"))))))
          (add-after 'apply-guix-specific-patches 'remove-bundled-libraries
            (lambda _
              ;; Remove bundled libraries that we don't use, since they may


@@ 1138,6 1135,11 @@ variable defined below.  It requires guile-json to be installed."
                 '("default16.png" "default22.png" "default24.png"
                   "default32.png" "default48.png" "content/icon64.png"
                   "mozicon128.png" "default256.png"))))))))
    (native-search-paths
     (list (search-path-specification
            (variable "ICECAT_SYSTEM_DIR")
            (separator #f)              ;single entry
            (files '("lib/icecat")))))
    (home-page "https://www.gnu.org/software/gnuzilla/")
    (synopsis "Entirely free browser derived from Mozilla Firefox")
    (description

A gnu/packages/patches/icecat-compare-paths.patch => gnu/packages/patches/icecat-compare-paths.patch +21 -0
@@ 0,0 1,21 @@
See comment in gnu/build/icecat-extension.scm.

--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -3452,6 +3452,7 @@ const XPIDatabaseReconcile = {
     if (
       newAddon ||
       oldAddon.updateDate != xpiState.mtime ||
+      oldAddon.path != xpiState.path ||
       (aUpdateCompatibility && this.isAppBundledLocation(installLocation))
     ) {
       newAddon = this.updateMetadata(
@@ -3460,8 +3461,6 @@ const XPIDatabaseReconcile = {
         xpiState,
         newAddon
       );
-    } else if (oldAddon.path != xpiState.path) {
-      newAddon = this.updatePath(installLocation, oldAddon, xpiState);
     } else if (aUpdateCompatibility || aSchemaChange) {
       newAddon = this.updateCompatibility(
         installLocation,

A gnu/packages/patches/icecat-use-system-wide-dir.patch => gnu/packages/patches/icecat-use-system-wide-dir.patch +36 -0
@@ 0,0 1,36 @@
Replace "/usr/lib/mozilla" (the system-wide directory for extensions and
native manifests) with "$ICECAT_SYSTEM_DIR".

--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -293,24 +293,12 @@ nsresult nsXREDirProvider::GetBackgroundTasksProfilesRootDir(
 static nsresult GetSystemParentDirectory(nsIFile** aFile) {
   nsresult rv;
   nsCOMPtr<nsIFile> localDir;
-#  if defined(XP_MACOSX)
-  rv = GetOSXFolderType(kOnSystemDisk, kApplicationSupportFolderType,
-                        getter_AddRefs(localDir));
-  if (NS_SUCCEEDED(rv)) {
-    rv = localDir->AppendNative("Mozilla"_ns);
-  }
-#  else
-  constexpr auto dirname =
-#    ifdef HAVE_USR_LIB64_DIR
-      "/usr/lib64/mozilla"_ns
-#    elif defined(__OpenBSD__) || defined(__FreeBSD__)
-      "/usr/local/lib/mozilla"_ns
-#    else
-      "/usr/lib/mozilla"_ns
-#    endif
-      ;
-  rv = NS_NewNativeLocalFile(dirname, false, getter_AddRefs(localDir));
-#  endif
+
+  const char* systemParentDir = getenv("ICECAT_SYSTEM_DIR");
+  if (!systemParentDir || !*systemParentDir) return NS_ERROR_FAILURE;
+
+  rv = NS_NewNativeLocalFile(nsDependentCString(systemParentDir), false,
+                             getter_AddRefs(localDir));
 
   if (NS_SUCCEEDED(rv)) {
     localDir.forget(aFile);