>From 4622b6dfb9ff067b8a04f0f8809967d7eed58b8f Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Sat, 20 Jun 2026 12:15:54 -0400 Subject: [PATCH] Add guix.scm file to enable building with GNU Guix This allows us to use Guix as a sort of CI to aid in development. See the top of the file for more commentary. * guix.scm: New file --- guix.scm | 788 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 788 insertions(+) create mode 100644 guix.scm diff --git a/guix.scm b/guix.scm new file mode 100644 index 000000000..e95d7863a --- /dev/null +++ b/guix.scm @@ -0,0 +1,788 @@ +;;; guix.scm -- Build recipe for GNU Guix. + +;; File maintained by Morgan Smith <[email protected]> + +;; Much of this code is copied from the GNU Guix project (same +;; licensing of GPLV3+) + +;; GNU Guix has a very useful build system that we can use. It has +;; the ability to control the build environment completely. +;; +;; If you are not already familiar with the "Make" build system, then +;; you should do that first. +;; +;; By running: +;; guix build -f guix.scm +;; +;; Guix will build all of the package definitions that are returned by +;; this file (the list at the bottom). +;; +;; If we instead run: +;; guix build --max-jobs=4 --keep-going -f guix.scm +;; +;; Then Guix will run 4 builds at once and keep going even if a build +;; fails. The output of all builds will be mixed together but don't +;; fret. Guix will save a log file for each failure that you can open +;; to see only the output of that build. Look for lines that start +;; with "View build log at" +;; +;; If Guix has already built a package definition, it is smart enough +;; to not build it again. You can force it to build with the +;; "--check" flag. +;; +;; New variants can also be defined on the command-line. For example: +;; +;; guix build -e '(begin (load "guix.scm") (pkg-with-lang emacs-org "tok"))' +;; +;;; Guix Shell +;; +;; An interactive shell with packages can be created like so: +;; +;; guix shell -e '(begin (load "guix.scm") (list emacs-org-28 emacs-minimal-28))' +;; +;; However, running emacs like this will have strange issues as it +;; will share your system EMACSLOADPATH environment variable and will +;; have access to your emacs `user-init-file'. I recommend running +;; emacs in a container like this: +;; +;; # Preserve TERM environment variable so emacs can run in the terminal +;; guix shell --container --preserve='^TERM$' -e '(begin (load "guix.scm") (list emacs-org-28 emacs-minimal-28))' -- emacs +;; +;; Using short flags the same command would look like this: +;; +;; guix shell -C -E '^TERM$' -e '(begin (load "guix.scm") (list emacs-org-28 emacs-minimal-28))' -- emacs +;; +;; To run a graphical emacs under X11 try this command: +;; (the emacs minimal variants don't have graphical capabilities) +;; +;; guix shell -C -E '^DISPLAY$' --share=/tmp -e '(begin (load "guix.scm") (list emacs-org-28 emacs-28))' -- emacs +;; +;; To run a graphical emacs under wayland try this command: +;; (this requires a "pgtk" emacs variant) +;; +;; guix shell -C -E '^WAYLAND_DISPLAY$' -E '^XDG_RUNTIME_DIR$' --expose=$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY -e '(begin (load "guix.scm") (list emacs-org emacs-pgtk))' -- emacs + +(use-modules ((guix licenses) #:prefix license:) + (gnu packages) + (gnu packages base) + (gnu packages check) + (gnu packages emacs) + (gnu packages texinfo) + (guix) + (guix build utils) + (guix build-system emacs) + (guix gexp) + (guix git) + (guix git-download) + (guix packages) + (guix profiles) + (guix utils) + (ice-9 popen) + (ice-9 rdelim) + (ice-9 regex)) + +(define %source-dir (dirname (current-filename))) + +(define vcs-file? + ;; Return true if the given file is under version control. + (or (git-predicate %source-dir #:recursive? #f) + (const #t))) ;not in a Git checkout + +;; Files that are not pulled into the Guix build. Modifying these +;; files will not cause Guix to rebuild so it is useful to exclude any +;; files that are not needed. +(define exclude-files + (map + (lambda (file) + (string-append %source-dir "/" file)) + '("guix.scm" "git-hooks"))) + +(define (emacs-org-build-file? file stat) + (if (member file exclude-files) + #f + (vcs-file? file stat))) + +(define (git-output . args) + "Execute 'git ARGS ...' command and return its output without trailing +newspace." + (with-directory-excursion %source-dir + (let* ((port (apply open-pipe* OPEN_READ "git" args)) + (output (read-string port))) + (close-pipe port) + (string-trim-right output #\newline)))) + +(define (string-filter-store-item str) + "Filter out any characters from STR that aren't valid in a guix store +item name." + ;; FIXME: Tell upstream to export this variable + (string-filter (@@ (guix store) %store-item-charset) str)) + +(define org-mode-version + (delay + (with-input-from-file (string-append %source-dir "/lisp/org.el") + (lambda () + (let ((regex (make-regexp "^;; Version: (.*)")) + (version #f) + (str #f)) + (while (and (not version) + (set! str (read-line))) + (let ((match (regexp-exec regex str))) + (when (and match + (match:substring match 1)) + (set! version (match:substring match 1))))) + (or version + (error "Could not figure out version!"))))))) + +(define emacs-minimal-25 + (package + (inherit emacs-minimal) + (version "25.3") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "02y00y9q42g1iqgz5qhmsja75hwxd88yrn9zp14lanay0zkwafi5")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start) + (delete 'patch-program-file-names))) + ((#:substitutable? _ #f) #f))) + (native-inputs (modify-inputs native-inputs + (prepend (@ (gnu packages autotools) automake)))))) + +(define emacs-minimal-26 + (package + (inherit emacs-minimal) + (version "26.3") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "119ldpk7sgn9jlpyngv5y4z3i7bb8q3xp4p0qqi7i5nq39syd42d")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start) + (delete 'patch-program-file-names))) + ((#:substitutable? _ #f) #f))))) + +(define emacs-minimal-27 + (package + (inherit emacs-minimal) + (version "27.2") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "1ff182gjw9wqsbx1kj5gl2r5pbqhp4ar54g04j33fgz6g17cr9xl")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start) + (delete 'patch-program-file-names))) + ((#:substitutable? _ #f) #f))))) + +(define emacs-minimal-28 + (package + (inherit emacs-minimal) + (version "28.2") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "12144dcaihv2ymfm7g2vnvdl4h71hqnsz1mljzf34cpg6ci1h8gf")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start))) + ((#:substitutable? _ #f) #f))))) + +(define emacs-28 + (package + (inherit emacs) + (version (package-version emacs-minimal-28)) + (source (package-source emacs-minimal-28)) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start) + (delete 'build-trampolines) + (delete 'validate-comp-integrity))) + ;; This keyword is not supported by glib-or-gtk-build-system even + ;; though it would work :/ + ;; ((#:substitutable? _ #f) #f) + )))) + +(define emacs-minimal-29 + (package + (inherit emacs-minimal) + (version "29.4") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "0dd2mh6maa7dc5f49qdzj7bi4hda4wfm1cvvgq560djcz537k2ds")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:substitutable? _ #f) #f))))) + +(define emacs-29 + (package + (inherit emacs) + (version (package-version emacs-minimal-29)) + (source (package-source emacs-minimal-29)) + (arguments + (substitute-keyword-arguments arguments + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'fix-tests) + (delete 'install-site-start) + (delete 'build-trampolines) + (delete 'validate-comp-integrity))) + ;; This keyword is not supported by glib-or-gtk-build-system even + ;; though it would work :/ + ;; ((#:substitutable? _ #f) #f) + )))) + +(define emacs-minimal-30 + (package + (inherit emacs-minimal) + (version "30.2") + (source (origin + (inherit (package-source emacs-minimal)) + (method url-fetch) + (uri (string-append "mirror://gnu/emacs/emacs-" + version ".tar.xz")) + (sha256 + (base32 + "1nggbgnns7lvxn68gzlcsgwh3bigvrbn45kh6dqia9yxlqc6zwxk")) + (patches '()))) + (arguments + (substitute-keyword-arguments arguments + ((#:substitutable? _ #f) #f))))) + +(define emacs-sans-org + (package + (inherit emacs-minimal) + (arguments + (substitute-keyword-arguments arguments + ;; /var/log/guix/drvs/bp/6y4virkkzfsxvjayfb0ybpk04s6mgk-emacs-minimal-31.1.drv.gz + ;; 3 test failures: + ;; kill-whole-line-invisible: (void-function org-mode) + ;; fill-test-fill-paragraph-semlf-org-mode: (void-function org-mode) + ;; find-func-tests--library-completion + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (add-after 'patch-program-file-names 'remove-org + (lambda _ + (delete-file-recursively "lisp/org") + (delete-file-recursively "test/lisp/org") + (substitute* "lisp/Makefile.in" + (("org-manuals[ \n]") "") + (("\\./org/[^ ]+ ") "")) + ;; icalendar depends on org so it has to go as well. + ;; We need to install it later though so just move it + ;; to the root directory + (for-each (lambda (file) + (rename-file file (basename file))) + (find-files "lisp/calendar" "^(diary-)?icalendar")) + (for-each delete-file + (find-files "test/lisp/calendar" "^(diary-)?icalendar")) + (rename-file "lisp/gnus/gnus-icalendar.el" "gnus-icalendar.el") + ;; Don't generate manuals from org files + (substitute* "doc/misc/Makefile.in" + (("ORG_SETUP = .*") "ORG_SETUP =\n") + (("ORG_SRC = .*") "ORG_SRC =\n")))) + ;; We can't compile icalendar without org-mode but + ;; org-mode depends on icalendar so we can't just create a + ;; package for icalendar. + (add-after 'install 'add-back-icalendar + (lambda _ + (let ((lisp-dir (string-append #$output + ;; FIXME: hardcoded version number + "/share/emacs/31.1/lisp/"))) + (for-each (lambda (file) + (install-file file (string-append lisp-dir "calendar/"))) + (find-files "." "^(diary-)?icalendar")) + (install-file "gnus-icalendar.el" + (string-append lisp-dir "gnus/"))))))) + ((#:substitutable? _ #f) #f))))) + +(define emacs-org + (package + (name "emacs-org") + (version (force org-mode-version)) + (source (local-file "." "org-mode-checkout" + #:recursive? #t + #:select? emacs-org-build-file?)) + (build-system emacs-build-system) + (outputs (list "out" "test")) + (arguments + (list + #:substitutable? #f ;; Don't upstream this + #:disallowed-references (map cadr (package-native-inputs this-package)) + #:test-command #~(list "make" "-C" ".." "test-dirty") + ;; #:tests? #f + #:lisp-directory "lisp" + #:phases + #~(modify-phases %standard-phases + (add-after 'unpack 'patch-paths + (lambda* (#:key inputs #:allow-other-keys) + (substitute* "ob-shell.el" + (("/usr/bin/env") + (search-input-file inputs "/bin/env"))) + ;; Don't build compat + (substitute* "../mk/targets.mk" + (("-f org-install-dependencies") "")))) + (replace 'make-autoloads + (lambda _ + (invoke "make" "-C" ".." "autoloads" + (string-append "ORGVERSION=" #$version)))) + (add-before 'check 'fix-tests + (lambda* (#:key tests? inputs #:allow-other-keys) + (when tests? + (with-directory-excursion "../testing" + ;; XXX: Running tests updates ID locations. The process expects + ;; a file to be writeable in "~/.emacs.d/". + (setenv "HOME" (getcwd)) + (mkdir-p ".emacs.d") + ;; These files are modified during testing. + (with-directory-excursion "examples" + (for-each make-file-writable + '("babel.org" + "ob-awk-test.org" + "ob-sed-test.org")) + ;; Specify where sh executable is. + (let ((sh (search-input-file inputs "/bin/sh"))) + (substitute* "babel.org" + (("/bin/sh") sh)))) + ;; XXX: Fix failure in ob-tangle/collect-blocks. The test + ;; assumes that ~/../.. corresponds to /. This isn't true in + ;; our case. + (substitute* "lisp/test-ob-tangle.el" + ((" ~/\\.\\./\\.\\./") + (string-append " ~" + ;; relative path from ${HOME} to / during + ;; build + (string-join + (map-in-order + (lambda (x) + (if (equal? x "") "" "..")) + (string-split (getcwd) #\/)) "/") + "/"))) + ;; XXX: Skip failing tests. + (substitute* "lisp/test-ob-shell.el" + (("ob-shell/remote-with-stdin-or-cmdline .*" all) + (string-append all " (skip-unless nil)\n"))))))) + (add-after 'install 'install-the-rest + ;; First install gets the lisp, then this install grabs the rest + ;; (info, news, etc) + (lambda _ + (let ((elpa (elpa-directory #$output)) + (info (string-append #$output "/share/info"))) + (invoke "make" "-C" ".." "install-info" "install-etc" + (string-append "datadir=" elpa "/etc") + (string-append "infodir=" info))))) + (add-after 'install 'install-org-test + (lambda _ + (with-directory-excursion "../testing" + (copy-recursively "." + (string-append (elpa-directory #$output:test)))))) + (add-after 'install 'install-org-news + ;; Install ORG-NEWS files in doc directory. + (lambda _ + (install-file "../etc/ORG-NEWS" + (string-append #$output "/share/doc/" + #$name "-" #$version)))) + (replace 'install-license-files + (lambda args + ;; Change to top-level so we find the license. + (with-directory-excursion ".." + (apply (assoc-ref %standard-phases 'install-license-files) + args))))))) + (native-inputs + (list texinfo tzdata)) + (propagated-inputs + (list (@ (gnu packages emacs-build) emacs-compat))) + (home-page "https://orgmode.org/") + (synopsis "Outline-based notes management and organizer") + (description "Org is an Emacs mode for keeping notes, maintaining TODO +lists, and project planning with a fast and effective lightweight markup +language. It also is an authoring system with unique support for literate +programming and reproducible research. If you work with the LaTeX output +capabilities of Org-mode, you may want to install the +@code{emacs-org-texlive-collection} meta-package, which propagates the TexLive +components required by the produced @file{.tex} file.") + (license license:gpl3+))) + +;; FIXME: add these languages +;; - csharp (mono) +;; - org-babel-csharp-compiler = dotnet +;; - mono package does not provide "dotnet" +;; - maybe try "csharp"? +;; FIXME: +;; Ran 1555 tests, 1512 results as expected, 28 unexpected, 15 skipped +;; 9 expected failures +;; Ihor says maxima failures are fixed upon upgrading Maxima to Maxima >5.48. +(define emacs-org-with-integration-tests + (package + (inherit emacs-org) + (name (string-append + (package-name emacs-org) "-integration")) + (arguments + (substitute-keyword-arguments arguments + ((#:emacs inherited-emacs #~'()) + emacs) ; for libxml + ((#:test-command test-command #~'()) + #~(append + #$test-command + (list + (string-append + ;; original value + "BTEST_OB_LANGUAGES=awk C fortran maxima lilypond octave perl python java sqlite eshell calc" + ;; additional + " R clojure julia lua scheme haskell java ruby") + "BTEST_EXTRA=ess ess-julia inf-ruby geiser haskell-mode haskell"))))) + (propagated-inputs + (modify-inputs propagated-inputs + (prepend (@ (gnu packages statistics) emacs-ess) + (@ (gnu packages emacs-xyz) emacs-haskell-mode) + (@ (gnu packages emacs-xyz) emacs-inf-ruby) + (@ (gnu packages emacs-xyz) emacs-geiser) + (@ (gnu packages emacs-xyz) emacs-geiser-guile)))) + (inputs + (modify-inputs inputs + (prepend + (@ (gnu packages clojure) clojure-tools) + (@ (gnu packages commencement) gfortran-toolchain) + (@ (gnu packages guile) guile-3.0-latest) + (@ (gnu packages haskell) ghc) + (@ (gnu packages haskell-apps) git-annex) + (@ (gnu packages java) openjdk) + (list (@ (gnu packages java) openjdk) "jdk") + (@ (gnu packages julia) julia) + (@ (gnu packages lua) lua) + (@ (gnu packages maths) maxima) + (@ (gnu packages maths) octave) + (@ (gnu packages perl) perl) + (@ (gnu packages python) python-wrapper) + (@ (gnu packages ruby) ruby) + (@ (gnu packages shells) dash) + (@ (gnu packages sqlite) sqlite) + (@ (gnu packages statistics) r-minimal)))))) + +(define* (commit-transformer commit #:optional (revision "0")) + (lambda (pkg) + (package + (inherit pkg) + (version (git-version (package-version pkg) revision commit)) + (source (git-checkout + (url %source-dir) + (commit commit))) + (arguments + (substitute-keyword-arguments arguments + ((#:phases phases) + #~(modify-phases #$phases + (replace 'make-autoloads + (lambda _ + (invoke "make" "-C" ".." "autoloads" + ;; Strip git commit and revision from + ;; version. Version needs to be something + ;; that Emacs can parse with it's + ;; `version-to-list' function + (string-append "ORGVERSION=" (string-drop-right #$version 10)) + (string-append "GITVERSION=" #$commit))))))))))) + +(define* (pkg-at-commit pkg commit #:optional (revision "0")) + ((commit-transformer commit revision) pkg)) + +(define (timezone-transformer timezone) + (lambda (pkg) + (package + (inherit pkg) + (name (string-append + (package-name pkg) + "-TZ=" (string-replace-substring timezone "/" "-"))) + (arguments + (substitute-keyword-arguments arguments + ((#:phases phases) + #~(modify-phases #$phases + (add-after 'unpack 'set-timezone + (lambda _ + (setenv "TZ" #$timezone)))))))))) + +(define (pkg-with-timezone pkg timezone) + ((timezone-transformer timezone) pkg)) + +(define (lang-transformer lang) + (lambda (pkg) + (package + (inherit pkg) + (name (string-append (package-name pkg) "-LANG=" lang)) + (arguments + (substitute-keyword-arguments arguments + ;; This keyword is not supported by emacs-build-system even + ;; though it would work :/ + ;; ((#:locale _ #f) lang) + ((#:phases phases) + #~(modify-phases #$phases + (replace 'install-locale + (lambda _ + ;; install-locale demotes errors into warnings so I + ;; have to promote them to errors again + (let ((error-string + (with-error-to-string + (lambda () + ((assoc-ref #$phases 'install-locale) #:locale #$lang))))) + (if (string-prefix? "warning:" error-string) + (error error-string) + (format (current-error-port) error-string))))))))) + (native-inputs (modify-inputs native-inputs + (prepend glibc-locales)))))) + +(define (pkg-with-lang pkg lang) + ((lang-transformer lang) pkg)) + +(define (time-transformer time) + (lambda (pkg) + (package + (inherit pkg) + (name (string-append (package-name pkg) "-at-time-" + (string-filter-store-item + (string-replace-substring time " " "T")))) + (arguments + (substitute-keyword-arguments arguments + ((#:phases phases) + #~(modify-phases #$phases + (add-after 'unpack 'use-libfaketime + (lambda* (#:key inputs #:allow-other-keys) + (substitute* "../mk/default.mk" + ;; FIXME: This fixes the tests erroring with + ;; "File %s changed on disk" but I really should + ;; figure out a better solution + (("^EMACS\t= emacs") + "EMACS\t= emacs --eval='(setq query-about-changed-file nil)'")) + (setenv "FAKETIME" #$time) + (setenv "FAKETIME_DONT_RESET" "1") + (setenv "LD_PRELOAD" + (search-input-file + inputs + "lib/faketime/libfaketimeMT.so.1")))))))) + (native-inputs (modify-inputs native-inputs + (prepend libfaketime)))))) + +(define (pkg-at-time pkg time) + ((time-transformer time) pkg)) + +(define (emacs-transformer emacs) + (lambda (pkg) + (let* ((emacs-version (version-major (package-version emacs))) + (transformer + (package-input-rewriting/spec + (map (lambda (pkg) + (cons pkg (const emacs))) + (list + "emacs-next-pgtk" + "emacs" + "emacs-minimal" + "emacs-no-x" + "emacs-no-x-toolkit"))))) + (package + (inherit + (transformer + (if (version>? emacs-version "29") + pkg + (package + (inherit pkg) + (arguments + (substitute-keyword-arguments arguments + ((#:phases phases) + #~(modify-phases #$phases + (replace 'build + (lambda args + ;; Build phase doesn't work on Emacs 27 + ;; Symbol’s function definition is void: native-comp-available-p + (when #$(version>? emacs-version "27") + (apply (assoc-ref %standard-phases 'build) args)))))))) + (propagated-inputs + (modify-inputs propagated-inputs + (replace "emacs-compat" + (transformer + (package + (inherit (@ (gnu packages emacs-build) emacs-compat)) + (arguments + (substitute-keyword-arguments arguments + ((#:phases phases) + #~(modify-phases #$phases + (replace 'ensure-package-description + (lambda _ + (emacs-batch-edit-file "compat.el" + '(progn + (require 'package) + (package-generate-description-file + (package-buffer-info) + "compat-pkg.el"))))) + (replace 'build + (lambda args + ;; Build phase doesn't work on Emacs 27 + ;; Symbol’s function definition is void: native-comp-available-p + (when #$(version>? emacs-version "27") + (apply (assoc-ref %standard-phases 'build) args)))) + (add-before 'check 'fix-more-tests + (lambda _ + ;; Fails on Emacs 26 + (when #$(version>? "27" emacs-version) + (substitute* "compat-tests.el" + (("\\(ert-deftest compat-executable-find .*" all) + (string-append all " (skip-unless nil)"))))))))))))))))))) + (name (string-append "emacs-" emacs-version + (string-drop (package-name pkg) 5))))))) + +(define (pkg-with-emacs pkg emacs) + ((emacs-transformer emacs) pkg)) + +(define (outgoing-commit-pkgs) + "Build all commits between HEAD and upstream." + (let ((outgoing-string + (git-output "rev-list" "@{upstream}.."))) + (if (string-null? outgoing-string) + #f + (map + (lambda (commit) + (pkg-at-commit emacs-org commit)) + (string-split + outgoing-string + #\newline))))) + +(define (get-direct-dependent-packages pkg-name) + "Return the list of packages that have a direct dependency named +PKG-NAME." + (fold-packages + (lambda (package lst) + (if (member + pkg-name + (map car (package-direct-inputs package))) + (cons package lst) + lst)) + (list))) + +;; This would be a wonderful way to check if our changes affect +;; downstream packages. However, this function returns very few +;; packages (only 35 as of 2026-07-14) as most are actually built +;; using the org-mode builtin to emacs. This is not ideal and +;; upstream knows that. +;; See https://codeberg.org/guix/guix/issues/1055 +(define (emacs-org-dependent-packages-with-org org) + "Return the list of packages that depend on emacs-org with that +dependency replaced with ORG." + (let ((pkgs (get-direct-dependent-packages "emacs-org")) + (transformer + (package-input-rewriting/spec + (list (cons "emacs-org" (const org)))))) + (map transformer pkgs))) + +(define expensive-builds + (cons* + ;; There is no upstream package for these emacs so they have + ;; to built on the local system + + ;; The builtin emacs-build-system uses `native-comp-available-p' + ;; which was introduced in emacs-28 so these fail the build phase + ;; (pkg-with-emacs emacs-org emacs-minimal-25) + ;; (pkg-with-emacs emacs-org emacs-minimal-26) + ;; (pkg-with-emacs emacs-org emacs-minimal-27) + (pkg-with-emacs emacs-org emacs-minimal-28) + (pkg-with-emacs emacs-org emacs-minimal-29) + (pkg-with-emacs emacs-org emacs-minimal-30) + + (emacs-org-dependent-packages-with-org emacs-org))) + +(apply + append + (delq #f + (list + expensive-builds + (outgoing-commit-pkgs) + (map + (lambda (lang) + (pkg-with-lang emacs-org lang)) + ;; FIXME: also test non utf8 locales + '("C.UTF-8" + "en_US.UTF-8" + "fr_FR.UTF-8" + "de_DE.UTF-8" + "he_IL.UTF-8" + ;; FIXME: These fail 'test-org-clock/clocktable/lang' + ;; "zh_CN.UTF-8" + ;; "ja_JP.UTF-8" + ;; FIXME: Failure when abbreviated day name contains spaces + ;; see: https://list.orgmode.org/ch3pr84mb342413ebc2dd0045ec233792c5...@ch3pr84mb3424.namprd84.prod.outlook.com + ;; "tok.UTF-8" + )) + ;; FIXME: all of these fail + ;; Test DST transitions in EST + ;; (let ((emacs-org-est (pkg-with-timezone emacs-org "America/New_York"))) + ;; (list + ;; ;; (spring forward) [2009-03-08 01:59] -> [2009-03-08 03:00] + ;; (pkg-at-time emacs-org-est "@2009-03-08 01:00:00") + ;; (pkg-at-time emacs-org-est "@2009-03-08 01:30:00") + ;; (pkg-at-time emacs-org-est "@2009-03-08 03:00:00") + ;; (pkg-at-time emacs-org-est "@2009-03-08 03:30:00") + ;; ;; fall back [2009-11-01 01:59] -> [2009-11-01 01:00] + ;; (pkg-at-time emacs-org-est "@2009-11-01 01:00:00") + ;; (pkg-at-time emacs-org-est "@2009-11-01 01:30:00") + ;; (pkg-at-time emacs-org-est "@2009-11-01 02:00:00") + ;; (pkg-at-time emacs-org-est "@2009-11-01 02:30:00"))) + + (list + emacs-org + + ;; FIXME: Hangs for a really long time + ;; emacs-org-with-integration-tests + + ;; FIXME: test failures when timezone is not an integer number of hours + ;; (pkg-with-timezone emacs-org "Asia/Kathmandu") + ;; (pkg-with-timezone emacs-org "Canada/Newfoundland") + (pkg-with-timezone emacs-org "Europe/Istanbul") + (pkg-with-timezone emacs-org "America/New_York") + + (pkg-with-emacs emacs-org emacs-next-minimal))))) -- 2.54.0
I have updated the guix.scm file to include the compat package for
emacs less then 31. I'm sure some other changes got slipped in
there too.
- Build org-mode with GNU Guix (CI like thingy) Morgan Smith
- Re: Build org-mode with GNU Guix (CI like thingy) Ihor Radchenko
- Re: Build org-mode with GNU Guix (CI like thingy) Earl Chase
- Re: Build org-mode with GNU Guix (CI like thin... Morgan Smith
- Re: Build org-mode with GNU Guix (CI like ... Morgan Smith
- Re: Build org-mode with GNU Guix (CI ... Morgan Smith
- Re: Build org-mode with GNU Guix (CI like thingy) Morgan Smith
