unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH 3/5] build: Add 'emacs-build-system'
@ 2015-06-21  8:31 Federico Beffa
  2015-06-21 20:40 ` Alex Kost
  2015-07-06 17:47 ` Alex Kost
  0 siblings, 2 replies; 24+ messages in thread
From: Federico Beffa @ 2015-06-21  8:31 UTC (permalink / raw)
  To: Guix-devel

[-- Attachment #1: Type: text/plain, Size: 33 bytes --]

A new 'emacs-buld-system'.

Fede

[-- Attachment #2: 0003-build-Add-emacs-build-system.patch --]
[-- Type: text/x-diff, Size: 17135 bytes --]

From 9c090ddd7de011b369208cdeb28eb3eaa5dc6011 Mon Sep 17 00:00:00 2001
From: Federico Beffa <beffa@fbengineering.ch>
Date: Sun, 21 Jun 2015 10:10:05 +0200
Subject: [PATCH 3/5] build: Add 'emacs-build-system'.

* Makefile.am (MODULES): Add 'guix/build-system/emacs.scm' and
  'guix/build/emacs-build-system.scm'.
* guix/build-system/emacs.scm: New file.
* guix/build/emacs-build-system.scm: New file.
* doc/guix.texi (Build Systems): Document it.
---
 Makefile.am                       |   2 +
 doc/guix.texi                     |  11 ++
 guix/build-system/emacs.scm       | 141 +++++++++++++++++++++++++
 guix/build/emacs-build-system.scm | 212 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 366 insertions(+)
 create mode 100644 guix/build-system/emacs.scm
 create mode 100644 guix/build/emacs-build-system.scm

diff --git a/Makefile.am b/Makefile.am
index c027fb3..a013b7a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ MODULES =					\
   guix/licenses.scm				\
   guix/build-system.scm				\
   guix/build-system/cmake.scm			\
+  guix/build-system/emacs.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -67,6 +68,7 @@ MODULES =					\
   guix/ui.scm					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
+  guix/build/emacs-build-system.scm		\
   guix/build/git.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
   guix/build/gnu-build-system.scm		\
diff --git a/doc/guix.texi b/doc/guix.texi
index 3ca105a..00fe5bb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2404,6 +2404,17 @@ Which Haskell compiler is used can be specified with the @code{#:haskell}
 parameter which defaults to @code{ghc}.
 @end defvr
 
+@defvr {Scheme Variable} emacs-build-system
+This variable is exported by @code{(guix build-system haskell)}.  It
+implements an installation procedure similar to the one of Emacs own
+packaging system.  It first creates the @code{PACKAGE-autoloads.el}
+file, then it byte compiles all Emacs Lisp files.  Differently from the
+Emacs packaging system, the @code{info} documentation files are moved to
+the standard documentation direcotry and the @code{dir} file is deleted.
+Each package is installed in its own directory under
+@code{share/emacs/site-lisp/guix.d}.
+@end defvr
+
 Lastly, for packages that do not need anything as sophisticated, a
 ``trivial'' build system is provided.  It is trivial in the sense that
 it provides basically no support: it does not pull any implicit inputs,
diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
new file mode 100644
index 0000000..da2b594
--- /dev/null
+++ b/guix/build-system/emacs.scm
@@ -0,0 +1,141 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build-system emacs)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-26)
+  #:export (%emacs-build-system-modules
+            emacs-build
+            emacs-build-system))
+
+;; Commentary:
+;;
+;; Standard build procedure for Emacs packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %emacs-build-system-modules
+  ;; Build-side modules imported by default.
+  `((guix build emacs-build-system)
+    (guix build emacs-utils)
+    ,@%gnu-build-system-modules))
+
+(define (default-emacs)
+  "Return the default Emacs package."
+  ;; Lazily resolve the binding to avoid a circular dependency.
+  (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
+    ;; we use 'emacs' instead of 'emacs-no-x' because the latter appears not
+    ;; to be loading some macros and causes problems to some packages.  For
+    ;; example, with the latter AUCTeX gives the error message:
+    ;; "(invalid-function dbus-ignore-errors)".
+    (module-ref emacs-mod 'emacs)))
+
+(define* (lower name
+                #:key source inputs native-inputs outputs system target
+                (emacs (default-emacs))
+                #:allow-other-keys
+                #:rest arguments)
+  "Return a bag for NAME."
+  (define private-keywords
+    '(#:target #:emacs #:inputs #:native-inputs))
+
+  (and (not target)                               ;XXX: no cross-compilation
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+
+                        ;; Keep the standard inputs of 'gnu-build-system'.
+                        ,@(standard-packages)))
+         (build-inputs `(("emacs" ,emacs)
+                         ,@native-inputs))
+         (outputs outputs)
+         (build emacs-build)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (emacs-build store name inputs
+                      #:key source
+                      (tests? #t)
+                      (test-target "test")
+                      (configure-flags ''())
+                      (phases '(@ (guix build emacs-build-system)
+                                  %standard-phases))
+                      (outputs '("out"))
+                      (search-paths '())
+                      (system (%current-system))
+                      (guile #f)
+                      (imported-modules %emacs-build-system-modules)
+                      (modules '((guix build emacs-build-system)
+                                 (guix build utils)
+                                 (guix build emacs-utils))))
+  "Build SOURCE using EMACS, and with INPUTS."
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (emacs-build #:name ,name
+                    #:source ,(match (assoc-ref inputs "source")
+                                (((? derivation? source))
+                                 (derivation->output-path source))
+                                ((source)
+                                 source)
+                                (source
+                                 source))
+                    #:configure-flags ,configure-flags
+                    #:system ,system
+                    #:test-target ,test-target
+                    #:tests? ,tests?
+                    #:phases ,phases
+                    #:outputs %outputs
+                    #:search-paths ',(map search-path-specification->sexp
+                                          search-paths)
+                    #:inputs %build-inputs)))
+  
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f                                         ; the default
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile  (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define emacs-build-system
+  (build-system
+    (name 'emacs)
+    (description "The build system for Emacs packages")
+    (lower lower)))
+
+;;; emacs.scm ends here
diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm
new file mode 100644
index 0000000..86dcdb9
--- /dev/null
+++ b/guix/build/emacs-build-system.scm
@@ -0,0 +1,212 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build emacs-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build emacs-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:export (%standard-phases
+            emacs-build))
+
+;; Commentary:
+;;
+;; Builder-side code of the build procedure for ELPA Emacs packages.
+;;
+;; Code:
+
+;; Directory suffix where we install ELPA packages.  We avoid ".../elpa" as
+;; Emacs expects to find the ELPA repository 'archive-contents' file and the
+;; archive signature.
+(define %install-suffix "/share/emacs/site-lisp/guix.d")
+
+(define-syntax lambda*-with-emacs-env
+  (lambda (x)
+    "Creates a 'lambda*' expression where the following variables are bound to
+the values expected by the 'emacs-build-system': 'emacs', 'out', 'name-ver',
+'name', 'elpa-name-ver', 'elpa-name', 'info-dir', 'el-dir'.  The first
+parameter of the syntax must be a list of symbols which become key parameters
+of the procedure.  'inputs' and 'outputs' are automatically added to them.
+The remaining parameters become the body of the procedure."
+    (syntax-case x ()
+      ((k (p ...) e1 e2 ...)
+       (with-syntax (((outputs inputs emacs out name-ver name elpa-name-ver
+                               elpa-name info-dir el-dir)
+                      (map (cut datum->syntax #'k <>)
+                           '(outputs inputs emacs out name-ver name
+                                     elpa-name-ver elpa-name
+                                     info-dir el-dir))))
+         #'(lambda* (#:key outputs inputs p ... #:allow-other-keys)
+             (let* ((emacs (string-append (assoc-ref inputs "emacs")
+                                          "/bin/emacs"))
+                    (out (assoc-ref outputs "out"))
+                    (name-ver (store-dir->name-version out))
+                    (name (package-name->name+version name-ver))
+                    (elpa-name-ver (store-dir->elpa-name-version out))
+                    (elpa-name (package-name->name+version elpa-name-ver))
+                    (info-dir (string-append out "/share/info/" name-ver))
+                    (el-dir (string-append out %install-suffix
+                                           "/" elpa-name-ver)))
+               e1 e2 ...)))))))
+
+;; Compile .el files.
+(define build
+  (lambda*-with-emacs-env ()
+    (let ((deps-dirs (emacs-inputs-dirs inputs)))
+      (setenv "SHELL" "sh")
+      (parameterize ((%emacs emacs))
+        (emacs-byte-compile-directory el-dir
+                                      (emacs-inputs-el-dirs deps-dirs))))))
+
+;; Substitute the absolute \"/bin/\" directory with the right location in the
+;; store in '.el' files.
+(define patch-el-files
+  (lambda*-with-emacs-env ()
+    (let ((substitute-cmd (lambda ()
+                            (substitute* (find-files "." "\\.el$")
+                              (("\"/bin/(.*)\"" _ cmd)
+                               (string-append "\"" (which cmd) "\""))))))
+      (with-directory-excursion el-dir
+        ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still encoded
+        ;; with the "ISO-8859-1" locale.
+        (unless (false-if-exception (substitute-cmd))
+          (with-fluids ((%default-port-encoding "ISO-8859-1"))
+            (substitute-cmd))))
+      #t)))
+
+;;  Install the package contents.
+(define install
+  (lambda*-with-emacs-env ()
+    (let ((src-dir (getcwd))
+          (tgt-dir (string-append out %install-suffix "/" elpa-name-ver)))
+    (copy-recursively src-dir tgt-dir)
+    #t)))
+
+;;  Move info files from the ELPA package directory to the info directory.
+(define move-doc
+  (lambda*-with-emacs-env ()
+    (let ((info-files (find-files el-dir "\\.info$")))
+      (unless (null? info-files)
+        (mkdir-p info-dir)
+        (with-directory-excursion el-dir
+          (when (file-exists? "dir") (delete-file "dir"))
+          (for-each (lambda (f)
+                      (copy-file f (string-append info-dir "/" (basename f)))
+                      (delete-file f))
+                    info-files)))
+      #t)))
+
+;;  Generate the autoloads file.
+(define make-autoloads
+  (lambda*-with-emacs-env ()
+    (parameterize ((%emacs emacs))
+      (emacs-generate-autoloads elpa-name el-dir))
+    #t))
+
+(define (emacs-package? name)
+  "Check if NAME correspond to the name of an Emacs package."
+  (string-prefix? "emacs-" name))
+
+(define (emacs-inputs inputs)
+  "Retrive the list of Emacs packages from inputs."
+  (filter (lambda (p)
+            (and (pair? p)
+                 (emacs-package? (package-name->name+version (first p)))))
+          inputs))
+
+(define (emacs-inputs-dirs inputs)
+  "Extract the list of Emacs package directories from INPUTS."
+  (let ((emacs-ins (emacs-inputs inputs)))
+    (match emacs-ins
+      (((name . dir) ...) dir))))
+
+(define (emacs-inputs-el-dirs dirs)
+  "Build the list of Emacs Lisp directories from the Emacs package directory
+DIRS."
+  (map (lambda (d)
+         (string-append d %install-suffix "/"
+                        (store-dir->elpa-name-version d)))
+       dirs))
+
+(define (package-name-version->elpa-name-version name-ver)
+  "Convert the Guix package NAME-VER to the corresponding ELPA name-version
+format.  Essnetially drop the prefix used in Guix."
+  (let ((name (store-dir->name-version name-ver)))
+    (if (emacs-package? name-ver)
+        (store-dir->name-version name-ver)
+        name-ver)))
+
+(define (store-dir->elpa-name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename after the
+second hyphen.  This corresponds to 'name-version' as used in ELPA packages."
+  ((compose package-name-version->elpa-name-version
+            store-dir->name-version)
+   store-dir))
+
+(define (store-dir->name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename
+after the first hyphen.  This corresponds to 'name-version' of the package."
+  (let* ((base (basename store-dir)))
+    (string-drop base
+                 (+ 1 (string-index base #\-)))))
+
+;; from (guix utils).  Should we put it in (guix build utils)?
+(define (package-name->name+version name)
+  "Given NAME, a package name like \"foo-0.9.1b\", return two values:
+\"foo\" and \"0.9.1b\".  When the version part is unavailable, NAME and
+#f are returned.  The first hyphen followed by a digit is considered to
+introduce the version part."
+  ;; See also `DrvName' in Nix.
+
+  (define number?
+    (cut char-set-contains? char-set:digit <>))
+
+  (let loop ((chars   (string->list name))
+             (prefix '()))
+    (match chars
+      (()
+       (values name #f))
+      ((#\- (? number? n) rest ...)
+       (values (list->string (reverse prefix))
+               (list->string (cons n rest))))
+      ((head tail ...)
+       (loop tail (cons head prefix))))))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'install install)
+    (add-after 'install 'make-autoloads make-autoloads)
+    (add-after 'make-autoloads 'patch-el-files patch-el-files)
+    (add-after 'make-autoloads 'move-doc move-doc)))
+
+(define* (emacs-build #:key inputs (phases %standard-phases)
+                      #:allow-other-keys #:rest args)
+  "Build the given Emacs package, applying all of PHASES in order."
+  (apply gnu:gnu-build
+         #:inputs inputs #:phases phases
+         args))
+
+;;; emacs-build-system.scm ends here
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-21  8:31 Federico Beffa
@ 2015-06-21 20:40 ` Alex Kost
  2015-06-22  8:51   ` Federico Beffa
  2015-07-06 17:47 ` Alex Kost
  1 sibling, 1 reply; 24+ messages in thread
From: Alex Kost @ 2015-06-21 20:40 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

Federico Beffa (2015-06-21 11:31 +0300) wrote:

[...]
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 3ca105a..00fe5bb 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -2404,6 +2404,17 @@ Which Haskell compiler is used can be specified with the @code{#:haskell}
>  parameter which defaults to @code{ghc}.
>  @end defvr
>  
> +@defvr {Scheme Variable} emacs-build-system
> +This variable is exported by @code{(guix build-system haskell)}.  It

Typo (haskell → emacs):
   This variable is exported by @code{(guix build-system emacs)}.  It

> +implements an installation procedure similar to the one of Emacs own
> +packaging system.  It first creates the @code{PACKAGE-autoloads.el}
> +file, then it byte compiles all Emacs Lisp files.  Differently from the
> +Emacs packaging system, the @code{info} documentation files are moved to
> +the standard documentation direcotry and the @code{dir} file is deleted.

Typo (direcotry → directory):
   the standard documentation directory and the @code{dir} file is deleted.

> +Each package is installed in its own directory under
> +@code{share/emacs/site-lisp/guix.d}.
> +@end defvr
> +
>  Lastly, for packages that do not need anything as sophisticated, a
>  ``trivial'' build system is provided.  It is trivial in the sense that
>  it provides basically no support: it does not pull any implicit inputs,
> diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
> new file mode 100644
> index 0000000..da2b594
> --- /dev/null
> +++ b/guix/build-system/emacs.scm
[...]
> +                    #:tests? ,tests?
> +                    #:phases ,phases
> +                    #:outputs %outputs
> +                    #:search-paths ',(map search-path-specification->sexp
> +                                          search-paths)
> +                    #:inputs %build-inputs)))
> +  
spaces on this line ^

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-21 20:40 ` Alex Kost
@ 2015-06-22  8:51   ` Federico Beffa
  2015-06-22 11:49     ` Mathieu Lirzin
  2015-06-22 17:59     ` Alex Kost
  0 siblings, 2 replies; 24+ messages in thread
From: Federico Beffa @ 2015-06-22  8:51 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

On Sun, Jun 21, 2015 at 10:40 PM, Alex Kost <alezost@gmail.com> wrote:
>> new file mode 100644
>> index 0000000..da2b594
>> --- /dev/null
>> +++ b/guix/build-system/emacs.scm
> [...]
>> +                    #:tests? ,tests?
>> +                    #:phases ,phases
>> +                    #:outputs %outputs
>> +                    #:search-paths ',(map search-path-specification->sexp
>> +                                          search-paths)
>> +                    #:inputs %build-inputs)))
>> +
> spaces on this line ^

Hi, thanks for the review!

This and other spaces that you indicate as "extra", are included by
Emacs by pressing TAB. This is because, as an example, the above
snippet finishes an internal define form and not a top-level form.

I'm following the Emacs behavior. Is there a convention to suppress
all spaces (in spite of what Emacs does)?

Regards,
Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22  8:51   ` Federico Beffa
@ 2015-06-22 11:49     ` Mathieu Lirzin
  2015-06-22 17:59     ` Alex Kost
  1 sibling, 0 replies; 24+ messages in thread
From: Mathieu Lirzin @ 2015-06-22 11:49 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel, Alex Kost

Federico Beffa <beffa@ieee.org> writes:

> I'm following the Emacs behavior. Is there a convention to suppress
> all spaces (in spite of what Emacs does)?

'M-x delete-trailing-whitespace' ?

--
Mathieu Lirzin

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22  8:51   ` Federico Beffa
  2015-06-22 11:49     ` Mathieu Lirzin
@ 2015-06-22 17:59     ` Alex Kost
  2015-06-22 19:33       ` Federico Beffa
  1 sibling, 1 reply; 24+ messages in thread
From: Alex Kost @ 2015-06-22 17:59 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

[-- Attachment #1: Type: text/plain, Size: 1574 bytes --]

Federico Beffa (2015-06-22 11:51 +0300) wrote:

> On Sun, Jun 21, 2015 at 10:40 PM, Alex Kost <alezost@gmail.com> wrote:
>>> new file mode 100644
>>> index 0000000..da2b594
>>> --- /dev/null
>>> +++ b/guix/build-system/emacs.scm
>> [...]
>>> +                    #:tests? ,tests?
>>> +                    #:phases ,phases
>>> +                    #:outputs %outputs
>>> +                    #:search-paths ',(map search-path-specification->sexp
>>> +                                          search-paths)
>>> +                    #:inputs %build-inputs)))
>>> +
>> spaces on this line ^
>
> Hi, thanks for the review!
>
> This and other spaces that you indicate as "extra", are included by
> Emacs by pressing TAB. This is because, as an example, the above
> snippet finishes an internal define form and not a top-level form.

Then don't press TAB on an empty line if you are not going to write
something there :-)

> I'm following the Emacs behavior. Is there a convention to suppress
> all spaces (in spite of what Emacs does)?

Well, these trailing spaces are artifacts of (inaccurate) coding.  Emacs
can't read user's mind to decide if the spaces are redundant or
intended.

As Mathieu, I also use 'delete-trailing-whitespace' command when I want
to get rid of the whitespaces in the current buffer.  You may try to put
it into 'after-save-hook', but I would not do this as I don't like when
my files are edited without asking me.

Also I prefer to _see_ the trailing whitespaces.  For that I set
'show-trailing-whitespace' variable to t in "text" and "prog" buffers:


[-- Attachment #2: show-whitespaces.el --]
[-- Type: application/emacs-lisp, Size: 199 bytes --]

[-- Attachment #3: Type: text/plain, Size: 10 bytes --]


-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22 17:59     ` Alex Kost
@ 2015-06-22 19:33       ` Federico Beffa
  2015-06-22 19:40         ` Thompson, David
  2015-06-23 11:57         ` Alex Kost
  0 siblings, 2 replies; 24+ messages in thread
From: Federico Beffa @ 2015-06-22 19:33 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

On Mon, Jun 22, 2015 at 7:59 PM, Alex Kost <alezost@gmail.com> wrote:
> Federico Beffa (2015-06-22 11:51 +0300) wrote:
>
>> On Sun, Jun 21, 2015 at 10:40 PM, Alex Kost <alezost@gmail.com> wrote:
>>>> new file mode 100644
>>>> index 0000000..da2b594
>>>> --- /dev/null
>>>> +++ b/guix/build-system/emacs.scm
>>> [...]
>>>> +                    #:tests? ,tests?
>>>> +                    #:phases ,phases
>>>> +                    #:outputs %outputs
>>>> +                    #:search-paths ',(map search-path-specification->sexp
>>>> +                                          search-paths)
>>>> +                    #:inputs %build-inputs)))
>>>> +
>>> spaces on this line ^
>>
>> Hi, thanks for the review!
>>
>> This and other spaces that you indicate as "extra", are included by
>> Emacs by pressing TAB. This is because, as an example, the above
>> snippet finishes an internal define form and not a top-level form.
>
> Then don't press TAB on an empty line if you are not going to write
> something there :-)
>
>> I'm following the Emacs behavior. Is there a convention to suppress
>> all spaces (in spite of what Emacs does)?
>
> Well, these trailing spaces are artifacts of (inaccurate) coding.  Emacs
> can't read user's mind to decide if the spaces are redundant or
> intended.

No need to read the mind... you just look if there are characters
other than white spaces (and possibly TABs) between newlines :-)

But, my question was NOT: how can I see white spaces. Rather: is there
a Guix coding style "rule" which states that white spaces there are
undesired.

I personally prefer to have them, because then, if I use M-up/down, I
move to the beginning/end of a whole top-level block, without stopping
at internal points and that's what I want most of the time.

So, these spaces are not just coding artifacts, but have some use.

Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22 19:33       ` Federico Beffa
@ 2015-06-22 19:40         ` Thompson, David
  2015-06-23  6:51           ` Federico Beffa
  2015-06-23 11:57         ` Alex Kost
  1 sibling, 1 reply; 24+ messages in thread
From: Thompson, David @ 2015-06-22 19:40 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel, Alex Kost

On Mon, Jun 22, 2015 at 3:33 PM, Federico Beffa <beffa@ieee.org> wrote:
>
> But, my question was NOT: how can I see white spaces. Rather: is there
> a Guix coding style "rule" which states that white spaces there are
> undesired.
>
> I personally prefer to have them, because then, if I use M-up/down, I
> move to the beginning/end of a whole top-level block, without stopping
> at internal points and that's what I want most of the time.
>
> So, these spaces are not just coding artifacts, but have some use.

There should be *no* trailing whitespace in submitted patches, and we
should add a note about it to our contribution guidelines if it's not
already there.

- Dave

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22 19:40         ` Thompson, David
@ 2015-06-23  6:51           ` Federico Beffa
  2015-06-25 11:57             ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-06-23  6:51 UTC (permalink / raw)
  To: Thompson, David; +Cc: Guix-devel, Alex Kost

On Mon, Jun 22, 2015 at 9:40 PM, Thompson, David
<dthompson2@worcester.edu> wrote:
> On Mon, Jun 22, 2015 at 3:33 PM, Federico Beffa <beffa@ieee.org> wrote:
>>
>> But, my question was NOT: how can I see white spaces. Rather: is there
>> a Guix coding style "rule" which states that white spaces there are
>> undesired.
>>
>> I personally prefer to have them, because then, if I use M-up/down, I
>> move to the beginning/end of a whole top-level block, without stopping
>> at internal points and that's what I want most of the time.
>>
>> So, these spaces are not just coding artifacts, but have some use.
>
> There should be *no* trailing whitespace in submitted patches, and we
> should add a note about it to our contribution guidelines if it's not
> already there.

OK, I will delete those spaces then. But, I'm curious about the
rationale for such a rule.

Regards,
Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-22 19:33       ` Federico Beffa
  2015-06-22 19:40         ` Thompson, David
@ 2015-06-23 11:57         ` Alex Kost
  2015-06-24 16:12           ` Federico Beffa
  1 sibling, 1 reply; 24+ messages in thread
From: Alex Kost @ 2015-06-23 11:57 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

Federico Beffa (2015-06-22 22:33 +0300) wrote:

> On Mon, Jun 22, 2015 at 7:59 PM, Alex Kost <alezost@gmail.com> wrote:
>
>> Well, these trailing spaces are artifacts of (inaccurate) coding.  Emacs
>> can't read user's mind to decide if the spaces are redundant or
>> intended.
>
> No need to read the mind... you just look if there are characters
> other than white spaces (and possibly TABs) between newlines :-)
>
> But, my question was NOT: how can I see white spaces. Rather: is there
> a Guix coding style "rule" which states that white spaces there are
> undesired.
>
> I personally prefer to have them, because then, if I use M-up/down, I
> move to the beginning/end of a whole top-level block, without stopping
> at internal points and that's what I want most of the time.
>
> So, these spaces are not just coding artifacts, but have some use.

Ouch, I didn't realize that you left the spaces intentionally, sorry.  I
always thought that "avoiding trailing whitespaces" is a general
convention everywhere.

But I see your point now, that's a nice trick!

For lisp/scheme code I use 'beginning-of-defun'/'end-of-defun' commands
instead of 'backward-paragraph'/'forward-paragraph' (if that's what is
bound to M-up/down for you).

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-23 11:57         ` Alex Kost
@ 2015-06-24 16:12           ` Federico Beffa
  2015-06-25 12:33             ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-06-24 16:12 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

[-- Attachment #1: Type: text/plain, Size: 1382 bytes --]

Thanks for the review!

On Tue, Jun 23, 2015 at 1:57 PM, Alex Kost <alezost@gmail.com> wrote:
> Federico Beffa (2015-06-22 22:33 +0300) wrote:
>
>> On Mon, Jun 22, 2015 at 7:59 PM, Alex Kost <alezost@gmail.com> wrote:
>>
>>> Well, these trailing spaces are artifacts of (inaccurate) coding.  Emacs
>>> can't read user's mind to decide if the spaces are redundant or
>>> intended.
>>
>> No need to read the mind... you just look if there are characters
>> other than white spaces (and possibly TABs) between newlines :-)
>>
>> But, my question was NOT: how can I see white spaces. Rather: is there
>> a Guix coding style "rule" which states that white spaces there are
>> undesired.
>>
>> I personally prefer to have them, because then, if I use M-up/down, I
>> move to the beginning/end of a whole top-level block, without stopping
>> at internal points and that's what I want most of the time.
>>
>> So, these spaces are not just coding artifacts, but have some use.
>
> Ouch, I didn't realize that you left the spaces intentionally, sorry.  I
> always thought that "avoiding trailing whitespaces" is a general
> convention everywhere.
>
> But I see your point now, that's a nice trick!
>
> For lisp/scheme code I use 'beginning-of-defun'/'end-of-defun' commands
> instead of 'backward-paragraph'/'forward-paragraph' (if that's what is
> bound to M-up/down for you).
>
> --
> Alex

[-- Attachment #2: 0003-build-Add-emacs-build-system.patch --]
[-- Type: text/x-diff, Size: 17131 bytes --]

From 725d42eb3e5c44bcec1bd81988d1f952e6be02a4 Mon Sep 17 00:00:00 2001
From: Federico Beffa <beffa@fbengineering.ch>
Date: Sun, 21 Jun 2015 10:10:05 +0200
Subject: [PATCH 3/5] build: Add 'emacs-build-system'.

* Makefile.am (MODULES): Add 'guix/build-system/emacs.scm' and
  'guix/build/emacs-build-system.scm'.
* guix/build-system/emacs.scm: New file.
* guix/build/emacs-build-system.scm: New file.
* doc/guix.texi (Build Systems): Document it.
---
 Makefile.am                       |   2 +
 doc/guix.texi                     |  11 ++
 guix/build-system/emacs.scm       | 141 +++++++++++++++++++++++++
 guix/build/emacs-build-system.scm | 212 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 366 insertions(+)
 create mode 100644 guix/build-system/emacs.scm
 create mode 100644 guix/build/emacs-build-system.scm

diff --git a/Makefile.am b/Makefile.am
index c027fb3..a013b7a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ MODULES =					\
   guix/licenses.scm				\
   guix/build-system.scm				\
   guix/build-system/cmake.scm			\
+  guix/build-system/emacs.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -67,6 +68,7 @@ MODULES =					\
   guix/ui.scm					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
+  guix/build/emacs-build-system.scm		\
   guix/build/git.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
   guix/build/gnu-build-system.scm		\
diff --git a/doc/guix.texi b/doc/guix.texi
index f8756ed..777f070 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2404,6 +2404,17 @@ Which Haskell compiler is used can be specified with the @code{#:haskell}
 parameter which defaults to @code{ghc}.
 @end defvr
 
+@defvr {Scheme Variable} emacs-build-system
+This variable is exported by @code{(guix build-system emacs)}.  It
+implements an installation procedure similar to the one of Emacs own
+packaging system.  It first creates the @code{PACKAGE-autoloads.el}
+file, then it byte compiles all Emacs Lisp files.  Differently from the
+Emacs packaging system, the @code{info} documentation files are moved to
+the standard documentation directory and the @code{dir} file is deleted.
+Each package is installed in its own directory under
+@code{share/emacs/site-lisp/guix.d}.
+@end defvr
+
 Lastly, for packages that do not need anything as sophisticated, a
 ``trivial'' build system is provided.  It is trivial in the sense that
 it provides basically no support: it does not pull any implicit inputs,
diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
new file mode 100644
index 0000000..03c1eb2
--- /dev/null
+++ b/guix/build-system/emacs.scm
@@ -0,0 +1,141 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build-system emacs)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-26)
+  #:export (%emacs-build-system-modules
+            emacs-build
+            emacs-build-system))
+
+;; Commentary:
+;;
+;; Standard build procedure for Emacs packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %emacs-build-system-modules
+  ;; Build-side modules imported by default.
+  `((guix build emacs-build-system)
+    (guix build emacs-utils)
+    ,@%gnu-build-system-modules))
+
+(define (default-emacs)
+  "Return the default Emacs package."
+  ;; Lazily resolve the binding to avoid a circular dependency.
+  (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
+    ;; we use 'emacs' instead of 'emacs-no-x' because the latter appears not
+    ;; to be loading some macros and causes problems to some packages.  For
+    ;; example, with the latter AUCTeX gives the error message:
+    ;; "(invalid-function dbus-ignore-errors)".
+    (module-ref emacs-mod 'emacs)))
+
+(define* (lower name
+                #:key source inputs native-inputs outputs system target
+                (emacs (default-emacs))
+                #:allow-other-keys
+                #:rest arguments)
+  "Return a bag for NAME."
+  (define private-keywords
+    '(#:target #:emacs #:inputs #:native-inputs))
+
+  (and (not target)                               ;XXX: no cross-compilation
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+
+                        ;; Keep the standard inputs of 'gnu-build-system'.
+                        ,@(standard-packages)))
+         (build-inputs `(("emacs" ,emacs)
+                         ,@native-inputs))
+         (outputs outputs)
+         (build emacs-build)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (emacs-build store name inputs
+                      #:key source
+                      (tests? #t)
+                      (test-target "test")
+                      (configure-flags ''())
+                      (phases '(@ (guix build emacs-build-system)
+                                  %standard-phases))
+                      (outputs '("out"))
+                      (search-paths '())
+                      (system (%current-system))
+                      (guile #f)
+                      (imported-modules %emacs-build-system-modules)
+                      (modules '((guix build emacs-build-system)
+                                 (guix build utils)
+                                 (guix build emacs-utils))))
+  "Build SOURCE using EMACS, and with INPUTS."
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (emacs-build #:name ,name
+                    #:source ,(match (assoc-ref inputs "source")
+                                (((? derivation? source))
+                                 (derivation->output-path source))
+                                ((source)
+                                 source)
+                                (source
+                                 source))
+                    #:configure-flags ,configure-flags
+                    #:system ,system
+                    #:test-target ,test-target
+                    #:tests? ,tests?
+                    #:phases ,phases
+                    #:outputs %outputs
+                    #:search-paths ',(map search-path-specification->sexp
+                                          search-paths)
+                    #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f                                         ; the default
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile  (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define emacs-build-system
+  (build-system
+    (name 'emacs)
+    (description "The build system for Emacs packages")
+    (lower lower)))
+
+;;; emacs.scm ends here
diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm
new file mode 100644
index 0000000..86dcdb9
--- /dev/null
+++ b/guix/build/emacs-build-system.scm
@@ -0,0 +1,212 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build emacs-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build emacs-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:export (%standard-phases
+            emacs-build))
+
+;; Commentary:
+;;
+;; Builder-side code of the build procedure for ELPA Emacs packages.
+;;
+;; Code:
+
+;; Directory suffix where we install ELPA packages.  We avoid ".../elpa" as
+;; Emacs expects to find the ELPA repository 'archive-contents' file and the
+;; archive signature.
+(define %install-suffix "/share/emacs/site-lisp/guix.d")
+
+(define-syntax lambda*-with-emacs-env
+  (lambda (x)
+    "Creates a 'lambda*' expression where the following variables are bound to
+the values expected by the 'emacs-build-system': 'emacs', 'out', 'name-ver',
+'name', 'elpa-name-ver', 'elpa-name', 'info-dir', 'el-dir'.  The first
+parameter of the syntax must be a list of symbols which become key parameters
+of the procedure.  'inputs' and 'outputs' are automatically added to them.
+The remaining parameters become the body of the procedure."
+    (syntax-case x ()
+      ((k (p ...) e1 e2 ...)
+       (with-syntax (((outputs inputs emacs out name-ver name elpa-name-ver
+                               elpa-name info-dir el-dir)
+                      (map (cut datum->syntax #'k <>)
+                           '(outputs inputs emacs out name-ver name
+                                     elpa-name-ver elpa-name
+                                     info-dir el-dir))))
+         #'(lambda* (#:key outputs inputs p ... #:allow-other-keys)
+             (let* ((emacs (string-append (assoc-ref inputs "emacs")
+                                          "/bin/emacs"))
+                    (out (assoc-ref outputs "out"))
+                    (name-ver (store-dir->name-version out))
+                    (name (package-name->name+version name-ver))
+                    (elpa-name-ver (store-dir->elpa-name-version out))
+                    (elpa-name (package-name->name+version elpa-name-ver))
+                    (info-dir (string-append out "/share/info/" name-ver))
+                    (el-dir (string-append out %install-suffix
+                                           "/" elpa-name-ver)))
+               e1 e2 ...)))))))
+
+;; Compile .el files.
+(define build
+  (lambda*-with-emacs-env ()
+    (let ((deps-dirs (emacs-inputs-dirs inputs)))
+      (setenv "SHELL" "sh")
+      (parameterize ((%emacs emacs))
+        (emacs-byte-compile-directory el-dir
+                                      (emacs-inputs-el-dirs deps-dirs))))))
+
+;; Substitute the absolute \"/bin/\" directory with the right location in the
+;; store in '.el' files.
+(define patch-el-files
+  (lambda*-with-emacs-env ()
+    (let ((substitute-cmd (lambda ()
+                            (substitute* (find-files "." "\\.el$")
+                              (("\"/bin/(.*)\"" _ cmd)
+                               (string-append "\"" (which cmd) "\""))))))
+      (with-directory-excursion el-dir
+        ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still encoded
+        ;; with the "ISO-8859-1" locale.
+        (unless (false-if-exception (substitute-cmd))
+          (with-fluids ((%default-port-encoding "ISO-8859-1"))
+            (substitute-cmd))))
+      #t)))
+
+;;  Install the package contents.
+(define install
+  (lambda*-with-emacs-env ()
+    (let ((src-dir (getcwd))
+          (tgt-dir (string-append out %install-suffix "/" elpa-name-ver)))
+    (copy-recursively src-dir tgt-dir)
+    #t)))
+
+;;  Move info files from the ELPA package directory to the info directory.
+(define move-doc
+  (lambda*-with-emacs-env ()
+    (let ((info-files (find-files el-dir "\\.info$")))
+      (unless (null? info-files)
+        (mkdir-p info-dir)
+        (with-directory-excursion el-dir
+          (when (file-exists? "dir") (delete-file "dir"))
+          (for-each (lambda (f)
+                      (copy-file f (string-append info-dir "/" (basename f)))
+                      (delete-file f))
+                    info-files)))
+      #t)))
+
+;;  Generate the autoloads file.
+(define make-autoloads
+  (lambda*-with-emacs-env ()
+    (parameterize ((%emacs emacs))
+      (emacs-generate-autoloads elpa-name el-dir))
+    #t))
+
+(define (emacs-package? name)
+  "Check if NAME correspond to the name of an Emacs package."
+  (string-prefix? "emacs-" name))
+
+(define (emacs-inputs inputs)
+  "Retrive the list of Emacs packages from inputs."
+  (filter (lambda (p)
+            (and (pair? p)
+                 (emacs-package? (package-name->name+version (first p)))))
+          inputs))
+
+(define (emacs-inputs-dirs inputs)
+  "Extract the list of Emacs package directories from INPUTS."
+  (let ((emacs-ins (emacs-inputs inputs)))
+    (match emacs-ins
+      (((name . dir) ...) dir))))
+
+(define (emacs-inputs-el-dirs dirs)
+  "Build the list of Emacs Lisp directories from the Emacs package directory
+DIRS."
+  (map (lambda (d)
+         (string-append d %install-suffix "/"
+                        (store-dir->elpa-name-version d)))
+       dirs))
+
+(define (package-name-version->elpa-name-version name-ver)
+  "Convert the Guix package NAME-VER to the corresponding ELPA name-version
+format.  Essnetially drop the prefix used in Guix."
+  (let ((name (store-dir->name-version name-ver)))
+    (if (emacs-package? name-ver)
+        (store-dir->name-version name-ver)
+        name-ver)))
+
+(define (store-dir->elpa-name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename after the
+second hyphen.  This corresponds to 'name-version' as used in ELPA packages."
+  ((compose package-name-version->elpa-name-version
+            store-dir->name-version)
+   store-dir))
+
+(define (store-dir->name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename
+after the first hyphen.  This corresponds to 'name-version' of the package."
+  (let* ((base (basename store-dir)))
+    (string-drop base
+                 (+ 1 (string-index base #\-)))))
+
+;; from (guix utils).  Should we put it in (guix build utils)?
+(define (package-name->name+version name)
+  "Given NAME, a package name like \"foo-0.9.1b\", return two values:
+\"foo\" and \"0.9.1b\".  When the version part is unavailable, NAME and
+#f are returned.  The first hyphen followed by a digit is considered to
+introduce the version part."
+  ;; See also `DrvName' in Nix.
+
+  (define number?
+    (cut char-set-contains? char-set:digit <>))
+
+  (let loop ((chars   (string->list name))
+             (prefix '()))
+    (match chars
+      (()
+       (values name #f))
+      ((#\- (? number? n) rest ...)
+       (values (list->string (reverse prefix))
+               (list->string (cons n rest))))
+      ((head tail ...)
+       (loop tail (cons head prefix))))))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'install install)
+    (add-after 'install 'make-autoloads make-autoloads)
+    (add-after 'make-autoloads 'patch-el-files patch-el-files)
+    (add-after 'make-autoloads 'move-doc move-doc)))
+
+(define* (emacs-build #:key inputs (phases %standard-phases)
+                      #:allow-other-keys #:rest args)
+  "Build the given Emacs package, applying all of PHASES in order."
+  (apply gnu:gnu-build
+         #:inputs inputs #:phases phases
+         args))
+
+;;; emacs-build-system.scm ends here
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-23  6:51           ` Federico Beffa
@ 2015-06-25 11:57             ` Ludovic Courtès
  2015-06-25 18:39               ` Federico Beffa
  0 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2015-06-25 11:57 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel, Alex Kost

Federico Beffa <beffa@ieee.org> skribis:

> On Mon, Jun 22, 2015 at 9:40 PM, Thompson, David
> <dthompson2@worcester.edu> wrote:
>> On Mon, Jun 22, 2015 at 3:33 PM, Federico Beffa <beffa@ieee.org> wrote:
>>>
>>> But, my question was NOT: how can I see white spaces. Rather: is there
>>> a Guix coding style "rule" which states that white spaces there are
>>> undesired.
>>>
>>> I personally prefer to have them, because then, if I use M-up/down, I
>>> move to the beginning/end of a whole top-level block, without stopping
>>> at internal points and that's what I want most of the time.
>>>
>>> So, these spaces are not just coding artifacts, but have some use.
>>
>> There should be *no* trailing whitespace in submitted patches, and we
>> should add a note about it to our contribution guidelines if it's not
>> already there.

+1

> OK, I will delete those spaces then. But, I'm curious about the
> rationale for such a rule.

It’s mostly that no-trailing-whitespace is a simple canonical form.
Having everyone follow it makes sure we don’t run into annoying patch
conflicts due to whitespace, nor “noisy patches” that remove trailing
spaces here and there.

Ludo’.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-24 16:12           ` Federico Beffa
@ 2015-06-25 12:33             ` Ludovic Courtès
  2015-06-25 18:36               ` Federico Beffa
  0 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2015-06-25 12:33 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel, Alex Kost

Federico Beffa <beffa@ieee.org> skribis:

> From 725d42eb3e5c44bcec1bd81988d1f952e6be02a4 Mon Sep 17 00:00:00 2001
> From: Federico Beffa <beffa@fbengineering.ch>
> Date: Sun, 21 Jun 2015 10:10:05 +0200
> Subject: [PATCH 3/5] build: Add 'emacs-build-system'.
>
> * Makefile.am (MODULES): Add 'guix/build-system/emacs.scm' and
>   'guix/build/emacs-build-system.scm'.
> * guix/build-system/emacs.scm: New file.
> * guix/build/emacs-build-system.scm: New file.
> * doc/guix.texi (Build Systems): Document it.

Overall LGTM.
One last round of comments:

> +@defvr {Scheme Variable} emacs-build-system
> +This variable is exported by @code{(guix build-system emacs)}.  It
> +implements an installation procedure similar to the one of Emacs own
                                                                   ^
Add an apostrophe here.  —————————————————————————————————————————–’

> +packaging system.  It first creates the @code{PACKAGE-autoloads.el}
                   ^
Add an @pxref to the Emacs manual and then start a new paragraph.
Use @var{package} rather than PACKAGE.

> +file, then it byte compiles all Emacs Lisp files.  Differently from the
> +Emacs packaging system, the @code{info} documentation files are moved to

s/@code{info}/Info/

> +the standard documentation directory and the @code{dir} file is deleted.

@file{dir}

> +Each package is installed in its own directory under
> +@code{share/emacs/site-lisp/guix.d}.

@file as well.

> +(define-syntax lambda*-with-emacs-env
> +  (lambda (x)
> +    "Creates a 'lambda*' expression where the following variables are bound to
> +the values expected by the 'emacs-build-system': 'emacs', 'out', 'name-ver',
> +'name', 'elpa-name-ver', 'elpa-name', 'info-dir', 'el-dir'.  The first
> +parameter of the syntax must be a list of symbols which become key parameters
> +of the procedure.  'inputs' and 'outputs' are automatically added to them.
> +The remaining parameters become the body of the procedure."

Interesting trick.

> +    (syntax-case x ()
> +      ((k (p ...) e1 e2 ...)
> +       (with-syntax (((outputs inputs emacs out name-ver name elpa-name-ver
> +                               elpa-name info-dir el-dir)
> +                      (map (cut datum->syntax #'k <>)
> +                           '(outputs inputs emacs out name-ver name
> +                                     elpa-name-ver elpa-name
> +                                     info-dir el-dir))))
> +         #'(lambda* (#:key outputs inputs p ... #:allow-other-keys)
> +             (let* ((emacs (string-append (assoc-ref inputs "emacs")
> +                                          "/bin/emacs"))
> +                    (out (assoc-ref outputs "out"))
> +                    (name-ver (store-dir->name-version out))
> +                    (name (package-name->name+version name-ver))
> +                    (elpa-name-ver (store-dir->elpa-name-version out))
> +                    (elpa-name (package-name->name+version elpa-name-ver))
> +                    (info-dir (string-append out "/share/info/" name-ver))
> +                    (el-dir (string-append out %install-suffix
> +                                           "/" elpa-name-ver)))
> +               e1 e2 ...)))))))

The problem is that this forcefully introduces bindings in an opaque way
(that is, regardless of whether the ‘outputs’ binding appears in the
source, there’s an ‘outputs’ binding that magically appears; this is
“unhygienic” or “non referentially transparent,” or just “bad”.  ;-))

Ideally, the identifiers that appear in the macro expansion should
either be in the source, or be unique (compiler-generated.)

What about starting from the ‘phase-lambda’ macro that Taylan proposed
at <https://lists.gnu.org/archive/html/guix-devel/2015-02/msg00712.html>?

It doesn’t solve everything, so perhaps you would need something like:

  (elpa-lambda ((emacs emacs-program) (el-dir emacs-lisp-directory))
    ...)

where ‘emacs-program’ and ‘emacs-lisp-directory’ are literals.

How does that sound?

> +(define (emacs-inputs inputs)
> +  "Retrive the list of Emacs packages from inputs."

“Retrieve” and “INPUTS”

> +  (filter (lambda (p)
> +            (and (pair? p)
> +                 (emacs-package? (package-name->name+version (first p)))))

(match-lambda
  ((label . directory)
   (emacs-package? (package-name+version directory))))

(Which means the ‘first’ above should have been ‘second’?)

For top-level bindings, try to consistently use non-abbreviated
words–e.g., ‘store-directory->name+version’ instead of
‘store-dir->name-version’ (also ‘+’ to denote the multiple-value return
in this example.)

Could you send an updated patch?

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-25 12:33             ` Ludovic Courtès
@ 2015-06-25 18:36               ` Federico Beffa
  2015-06-27  9:59                 ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-06-25 18:36 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Guix-devel, Alex Kost

[-- Attachment #1: Type: text/plain, Size: 4115 bytes --]

Thanks for the review!

I've done the suggested modifications apart from the comments below.

On Thu, Jun 25, 2015 at 2:33 PM, Ludovic Courtès <ludo@gnu.org> wrote:
> Federico Beffa <beffa@ieee.org> skribis:
>> +(define-syntax lambda*-with-emacs-env
>> +  (lambda (x)
>> +    "Creates a 'lambda*' expression where the following variables are bound to
>> +the values expected by the 'emacs-build-system': 'emacs', 'out', 'name-ver',
>> +'name', 'elpa-name-ver', 'elpa-name', 'info-dir', 'el-dir'.  The first
>> +parameter of the syntax must be a list of symbols which become key parameters
>> +of the procedure.  'inputs' and 'outputs' are automatically added to them.
>> +The remaining parameters become the body of the procedure."
>
> Interesting trick.
>
>> +    (syntax-case x ()
>> +      ((k (p ...) e1 e2 ...)
>> +       (with-syntax (((outputs inputs emacs out name-ver name elpa-name-ver
>> +                               elpa-name info-dir el-dir)
>> +                      (map (cut datum->syntax #'k <>)
>> +                           '(outputs inputs emacs out name-ver name
>> +                                     elpa-name-ver elpa-name
>> +                                     info-dir el-dir))))
>> +         #'(lambda* (#:key outputs inputs p ... #:allow-other-keys)
>> +             (let* ((emacs (string-append (assoc-ref inputs "emacs")
>> +                                          "/bin/emacs"))
>> +                    (out (assoc-ref outputs "out"))
>> +                    (name-ver (store-dir->name-version out))
>> +                    (name (package-name->name+version name-ver))
>> +                    (elpa-name-ver (store-dir->elpa-name-version out))
>> +                    (elpa-name (package-name->name+version elpa-name-ver))
>> +                    (info-dir (string-append out "/share/info/" name-ver))
>> +                    (el-dir (string-append out %install-suffix
>> +                                           "/" elpa-name-ver)))
>> +               e1 e2 ...)))))))
>
> The problem is that this forcefully introduces bindings in an opaque way
> (that is, regardless of whether the ‘outputs’ binding appears in the
> source, there’s an ‘outputs’ binding that magically appears; this is
> “unhygienic” or “non referentially transparent,” or just “bad”.  ;-))
>
> Ideally, the identifiers that appear in the macro expansion should
> either be in the source, or be unique (compiler-generated.)

I was so sure that you would say so, that I did a copy of the file
before removing the 'let's and introducing the syntax.

If this would be proposed as a general utility, then I would agree
with you. But it's not. It is a module internal implementation detail
aimed at reducing boilerplate in this particular place only (where all
procedures need 'outputs' and most of the other variables) and every
introduced binding is documented. The name tells what it does in such
an obvious way that it makes the code shorter without degrading
readability.

In fact there are also popular general utilities promoted by highly
regarded programmers, which introduce what you call "bad" macros:
http://ep.yimg.com/ty/cdn/paulgraham/onlisp.pdf Chapter 14.

In any case, I've reverted to the boilerplate version (correcting it
according to the other comments).

>> +  (filter (lambda (p)
>> +            (and (pair? p)
>> +                 (emacs-package? (package-name->name+version (first p)))))
>
> (match-lambda
>   ((label . directory)
>    (emacs-package? (package-name+version directory))))
>
> (Which means the ‘first’ above should have been ‘second’?)

I'm not sure I understand your comment:
'package-name->name+version' takes a package name, therefore I pass it
the 1st element of each input.
'emacs-package?' checks for the agreed prefix in the name. Prior to
this check I discard the version suffix to make sure that, e.g.,
"emacs-123.456", is not confused for an emacs package.

(By the way, 'match-lambda' appears not to be documented in Guile.)

Thanks,
Fede

[-- Attachment #2: 0003-build-Add-emacs-build-system.patch --]
[-- Type: text/x-diff, Size: 16717 bytes --]

From e24d0b11280f4fcd106f371b98b7481f7c044eb0 Mon Sep 17 00:00:00 2001
From: Federico Beffa <beffa@fbengineering.ch>
Date: Sun, 21 Jun 2015 10:10:05 +0200
Subject: [PATCH 3/5] build: Add 'emacs-build-system'.

* Makefile.am (MODULES): Add 'guix/build-system/emacs.scm' and
  'guix/build/emacs-build-system.scm'.
* guix/build-system/emacs.scm: New file.
* guix/build/emacs-build-system.scm: New file.
* doc/guix.texi (Build Systems): Document it.
---
 Makefile.am                       |   2 +
 doc/guix.texi                     |  13 +++
 guix/build-system/emacs.scm       | 141 +++++++++++++++++++++++++++
 guix/build/emacs-build-system.scm | 197 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 353 insertions(+)
 create mode 100644 guix/build-system/emacs.scm
 create mode 100644 guix/build/emacs-build-system.scm

diff --git a/Makefile.am b/Makefile.am
index c027fb3..a013b7a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ MODULES =					\
   guix/licenses.scm				\
   guix/build-system.scm				\
   guix/build-system/cmake.scm			\
+  guix/build-system/emacs.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -67,6 +68,7 @@ MODULES =					\
   guix/ui.scm					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
+  guix/build/emacs-build-system.scm		\
   guix/build/git.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
   guix/build/gnu-build-system.scm		\
diff --git a/doc/guix.texi b/doc/guix.texi
index 9ef6021..3e47900 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2404,6 +2404,19 @@ Which Haskell compiler is used can be specified with the @code{#:haskell}
 parameter which defaults to @code{ghc}.
 @end defvr
 
+@defvr {Scheme Variable} emacs-build-system
+This variable is exported by @code{(guix build-system emacs)}.  It
+implements an installation procedure similar to the one of Emacs' own
+packaging system (@pxref{Packages,,, emacs, The GNU Emacs Manual}).
+
+It first creates the @code{@var{package}-autoloads.el} file, then it
+byte compiles all Emacs Lisp files.  Differently from the Emacs
+packaging system, the Info documentation files are moved to the standard
+documentation directory and the @file{dir} file is deleted.  Each
+package is installed in its own directory under
+@file{share/emacs/site-lisp/guix.d}.
+@end defvr
+
 Lastly, for packages that do not need anything as sophisticated, a
 ``trivial'' build system is provided.  It is trivial in the sense that
 it provides basically no support: it does not pull any implicit inputs,
diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
new file mode 100644
index 0000000..03c1eb2
--- /dev/null
+++ b/guix/build-system/emacs.scm
@@ -0,0 +1,141 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build-system emacs)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-26)
+  #:export (%emacs-build-system-modules
+            emacs-build
+            emacs-build-system))
+
+;; Commentary:
+;;
+;; Standard build procedure for Emacs packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %emacs-build-system-modules
+  ;; Build-side modules imported by default.
+  `((guix build emacs-build-system)
+    (guix build emacs-utils)
+    ,@%gnu-build-system-modules))
+
+(define (default-emacs)
+  "Return the default Emacs package."
+  ;; Lazily resolve the binding to avoid a circular dependency.
+  (let ((emacs-mod (resolve-interface '(gnu packages emacs))))
+    ;; we use 'emacs' instead of 'emacs-no-x' because the latter appears not
+    ;; to be loading some macros and causes problems to some packages.  For
+    ;; example, with the latter AUCTeX gives the error message:
+    ;; "(invalid-function dbus-ignore-errors)".
+    (module-ref emacs-mod 'emacs)))
+
+(define* (lower name
+                #:key source inputs native-inputs outputs system target
+                (emacs (default-emacs))
+                #:allow-other-keys
+                #:rest arguments)
+  "Return a bag for NAME."
+  (define private-keywords
+    '(#:target #:emacs #:inputs #:native-inputs))
+
+  (and (not target)                               ;XXX: no cross-compilation
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+
+                        ;; Keep the standard inputs of 'gnu-build-system'.
+                        ,@(standard-packages)))
+         (build-inputs `(("emacs" ,emacs)
+                         ,@native-inputs))
+         (outputs outputs)
+         (build emacs-build)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (emacs-build store name inputs
+                      #:key source
+                      (tests? #t)
+                      (test-target "test")
+                      (configure-flags ''())
+                      (phases '(@ (guix build emacs-build-system)
+                                  %standard-phases))
+                      (outputs '("out"))
+                      (search-paths '())
+                      (system (%current-system))
+                      (guile #f)
+                      (imported-modules %emacs-build-system-modules)
+                      (modules '((guix build emacs-build-system)
+                                 (guix build utils)
+                                 (guix build emacs-utils))))
+  "Build SOURCE using EMACS, and with INPUTS."
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (emacs-build #:name ,name
+                    #:source ,(match (assoc-ref inputs "source")
+                                (((? derivation? source))
+                                 (derivation->output-path source))
+                                ((source)
+                                 source)
+                                (source
+                                 source))
+                    #:configure-flags ,configure-flags
+                    #:system ,system
+                    #:test-target ,test-target
+                    #:tests? ,tests?
+                    #:phases ,phases
+                    #:outputs %outputs
+                    #:search-paths ',(map search-path-specification->sexp
+                                          search-paths)
+                    #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f                                         ; the default
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile  (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define emacs-build-system
+  (build-system
+    (name 'emacs)
+    (description "The build system for Emacs packages")
+    (lower lower)))
+
+;;; emacs.scm ends here
diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm
new file mode 100644
index 0000000..b70e0f6
--- /dev/null
+++ b/guix/build/emacs-build-system.scm
@@ -0,0 +1,197 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;;
+;;; 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 (guix build emacs-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build emacs-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:export (%standard-phases
+            emacs-build))
+
+;; Commentary:
+;;
+;; Builder-side code of the build procedure for ELPA Emacs packages.
+;;
+;; Code:
+
+;; Directory suffix where we install ELPA packages.  We avoid ".../elpa" as
+;; Emacs expects to find the ELPA repository 'archive-contents' file and the
+;; archive signature.
+(define %install-suffix "/share/emacs/site-lisp/guix.d")
+
+(define* (build #:key outputs inputs #:allow-other-keys)
+  "Compile .el files."
+  (let* ((emacs (string-append (assoc-ref inputs "emacs") "/bin/emacs"))
+         (out (assoc-ref outputs "out"))
+         (elpa-name-ver (store-directory->elpa-name-version out))
+         (el-dir (string-append out %install-suffix "/" elpa-name-ver))
+         (deps-dirs (emacs-inputs-directories inputs)))
+    (setenv "SHELL" "sh")
+    (parameterize ((%emacs emacs))
+      (emacs-byte-compile-directory el-dir
+                                    (emacs-inputs-el-directories deps-dirs)))))
+
+(define* (patch-el-files #:key outputs #:allow-other-keys)
+  "Substitute the absolute \"/bin/\" directory with the right location in the
+store in '.el' files."
+  (let* ((out (assoc-ref outputs "out"))
+         (elpa-name-ver (store-directory->elpa-name-version out))
+         (el-dir (string-append out %install-suffix "/" elpa-name-ver))
+         (substitute-cmd (lambda ()
+                           (substitute* (find-files "." "\\.el$")
+                             (("\"/bin/(.*)\"" _ cmd)
+                              (string-append "\"" (which cmd) "\""))))))
+    (with-directory-excursion el-dir
+      ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still encoded
+      ;; with the "ISO-8859-1" locale.
+      (unless (false-if-exception (substitute-cmd))
+        (with-fluids ((%default-port-encoding "ISO-8859-1"))
+          (substitute-cmd))))
+    #t))
+
+(define* (install #:key outputs #:allow-other-keys)
+  "Install the package contents."
+  (let* ((out (assoc-ref outputs "out"))
+         (elpa-name-ver (store-directory->elpa-name-version out))
+         (src-dir (getcwd))
+         (tgt-dir (string-append out %install-suffix "/" elpa-name-ver)))
+    (copy-recursively src-dir tgt-dir)
+    #t))
+
+(define* (move-doc #:key outputs #:allow-other-keys)
+  "Move info files from the ELPA package directory to the info directory."
+  (let* ((out (assoc-ref outputs "out"))
+         (elpa-name-ver (store-directory->elpa-name-version out))
+         (el-dir (string-append out %install-suffix "/" elpa-name-ver))
+         (name-ver (store-directory->name-version out))
+         (info-dir (string-append out "/share/info/" name-ver))
+         (info-files (find-files el-dir "\\.info$")))
+    (unless (null? info-files)
+      (mkdir-p info-dir)
+      (with-directory-excursion el-dir
+        (when (file-exists? "dir") (delete-file "dir"))
+        (for-each (lambda (f)
+                    (copy-file f (string-append info-dir "/" (basename f)))
+                    (delete-file f))
+                  info-files)))
+    #t))
+
+(define* (make-autoloads #:key outputs inputs #:allow-other-keys)
+  "Generate the autoloads file."
+  (let* ((emacs (string-append (assoc-ref inputs "emacs") "/bin/emacs"))
+         (out (assoc-ref outputs "out"))
+         (elpa-name-ver (store-directory->elpa-name-version out))
+         (elpa-name (package-name->name+version elpa-name-ver))
+         (el-dir (string-append out %install-suffix "/" elpa-name-ver)))
+    (parameterize ((%emacs emacs))
+      (emacs-generate-autoloads elpa-name el-dir))
+    #t))
+
+(define (emacs-package? name)
+  "Check if NAME correspond to the name of an Emacs package."
+  (string-prefix? "emacs-" name))
+
+(define (emacs-inputs inputs)
+  "Retrieve the list of Emacs packages from INPUTS."
+  (filter (lambda (p)
+            (and (pair? p)
+                 (emacs-package? (package-name->name+version (first p)))))
+          inputs))
+
+(define (emacs-inputs-directories inputs)
+  "Extract the list of Emacs package directories from INPUTS."
+  (let ((emacs-ins (emacs-inputs inputs)))
+    (match emacs-ins
+      (((name . dir) ...) dir))))
+
+(define (emacs-inputs-el-directories dirs)
+  "Build the list of Emacs Lisp directories from the Emacs package directory
+DIRS."
+  (map (lambda (d)
+         (string-append d %install-suffix "/"
+                        (store-directory->elpa-name-version d)))
+       dirs))
+
+(define (package-name-version->elpa-name-version name-ver)
+  "Convert the Guix package NAME-VER to the corresponding ELPA name-version
+format.  Essnetially drop the prefix used in Guix."
+  (let ((name (store-directory->name-version name-ver)))
+    (if (emacs-package? name-ver)
+        (store-directory->name-version name-ver)
+        name-ver)))
+
+(define (store-directory->elpa-name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename after the
+second hyphen.  This corresponds to 'name-version' as used in ELPA packages."
+  ((compose package-name-version->elpa-name-version
+            store-directory->name-version)
+   store-dir))
+
+(define (store-directory->name-version store-dir)
+  "Given a store directory STORE-DIR return the part of the basename
+after the first hyphen.  This corresponds to 'name-version' of the package."
+  (let* ((base (basename store-dir)))
+    (string-drop base
+                 (+ 1 (string-index base #\-)))))
+
+;; from (guix utils).  Should we put it in (guix build utils)?
+(define (package-name->name+version name)
+  "Given NAME, a package name like \"foo-0.9.1b\", return two values:
+\"foo\" and \"0.9.1b\".  When the version part is unavailable, NAME and
+#f are returned.  The first hyphen followed by a digit is considered to
+introduce the version part."
+  ;; See also `DrvName' in Nix.
+
+  (define number?
+    (cut char-set-contains? char-set:digit <>))
+
+  (let loop ((chars   (string->list name))
+             (prefix '()))
+    (match chars
+      (()
+       (values name #f))
+      ((#\- (? number? n) rest ...)
+       (values (list->string (reverse prefix))
+               (list->string (cons n rest))))
+      ((head tail ...)
+       (loop tail (cons head prefix))))))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'install install)
+    (add-after 'install 'make-autoloads make-autoloads)
+    (add-after 'make-autoloads 'patch-el-files patch-el-files)
+    (add-after 'make-autoloads 'move-doc move-doc)))
+
+(define* (emacs-build #:key inputs (phases %standard-phases)
+                      #:allow-other-keys #:rest args)
+  "Build the given Emacs package, applying all of PHASES in order."
+  (apply gnu:gnu-build
+         #:inputs inputs #:phases phases
+         args))
+
+;;; emacs-build-system.scm ends here
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-25 11:57             ` Ludovic Courtès
@ 2015-06-25 18:39               ` Federico Beffa
  0 siblings, 0 replies; 24+ messages in thread
From: Federico Beffa @ 2015-06-25 18:39 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Guix-devel, Alex Kost

On Thu, Jun 25, 2015 at 1:57 PM, Ludovic Courtès <ludo@gnu.org> wrote:
> Federico Beffa <beffa@ieee.org> skribis:
>
>> On Mon, Jun 22, 2015 at 9:40 PM, Thompson, David
>> <dthompson2@worcester.edu> wrote:
>>> On Mon, Jun 22, 2015 at 3:33 PM, Federico Beffa <beffa@ieee.org> wrote:
>>>>
>>>> But, my question was NOT: how can I see white spaces. Rather: is there
>>>> a Guix coding style "rule" which states that white spaces there are
>>>> undesired.
>>>>
>>>> I personally prefer to have them, because then, if I use M-up/down, I
>>>> move to the beginning/end of a whole top-level block, without stopping
>>>> at internal points and that's what I want most of the time.
>>>>
>>>> So, these spaces are not just coding artifacts, but have some use.
>>>
>>> There should be *no* trailing whitespace in submitted patches, and we
>>> should add a note about it to our contribution guidelines if it's not
>>> already there.
>
> +1
>
>> OK, I will delete those spaces then. But, I'm curious about the
>> rationale for such a rule.
>
> It’s mostly that no-trailing-whitespace is a simple canonical form.
> Having everyone follow it makes sure we don’t run into annoying patch
> conflicts due to whitespace, nor “noisy patches” that remove trailing
> spaces here and there.

Makes sense. Thanks for the explanation.

Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-25 18:36               ` Federico Beffa
@ 2015-06-27  9:59                 ` Ludovic Courtès
  0 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2015-06-27  9:59 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel, Alex Kost

Federico Beffa <beffa@ieee.org> skribis:

> On Thu, Jun 25, 2015 at 2:33 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>> Federico Beffa <beffa@ieee.org> skribis:

[...]

>> The problem is that this forcefully introduces bindings in an opaque way
>> (that is, regardless of whether the ‘outputs’ binding appears in the
>> source, there’s an ‘outputs’ binding that magically appears; this is
>> “unhygienic” or “non referentially transparent,” or just “bad”.  ;-))
>>
>> Ideally, the identifiers that appear in the macro expansion should
>> either be in the source, or be unique (compiler-generated.)
>
> I was so sure that you would say so, that I did a copy of the file
> before removing the 'let's and introducing the syntax.

:-)

> If this would be proposed as a general utility, then I would agree
> with you. But it's not. It is a module internal implementation detail

Sure, sure, but the problems here are not theoretical.  The possibility
of having one user introduce a binding that clashes without noticing is
real, and it can be hard to debug.  “But it’s all internal in a single
file,” right, but some future hacker might not notice the
unhygenically-introduced bindings.

Simply put, people may not expect such issues to arise in Scheme, so
it’s best to not violate the rule of least surprise, IMO.

>>> +  (filter (lambda (p)
>>> +            (and (pair? p)
>>> +                 (emacs-package? (package-name->name+version (first p)))))
>>
>> (match-lambda
>>   ((label . directory)
>>    (emacs-package? (package-name+version directory))))
>>
>> (Which means the ‘first’ above should have been ‘second’?)
>
> I'm not sure I understand your comment:
> 'package-name->name+version' takes a package name, therefore I pass it
> the 1st element of each input.

The first element of an input is a label, which often happens to be a
package name, but doesn’t have to.  Would it be possible to extract the
package name from the directory name?

> (By the way, 'match-lambda' appears not to be documented in Guile.)

Oops.

> From e24d0b11280f4fcd106f371b98b7481f7c044eb0 Mon Sep 17 00:00:00 2001
> From: Federico Beffa <beffa@fbengineering.ch>
> Date: Sun, 21 Jun 2015 10:10:05 +0200
> Subject: [PATCH 3/5] build: Add 'emacs-build-system'.
>
> * Makefile.am (MODULES): Add 'guix/build-system/emacs.scm' and
>   'guix/build/emacs-build-system.scm'.
> * guix/build-system/emacs.scm: New file.
> * guix/build/emacs-build-system.scm: New file.
> * doc/guix.texi (Build Systems): Document it.

[...]

> +(define (emacs-inputs-directories inputs)
> +  "Extract the list of Emacs package directories from INPUTS."
> +  (let ((emacs-ins (emacs-inputs inputs)))
> +    (match emacs-ins
> +      (((name . dir) ...) dir))))

Minor issue, but I would s/emacs-ins/inputs/, s/dir/directories/,
s/name/names/.  (See the “Naming” section in
<http://mumble.net/~campbell/scheme/style.txt>.)

OK to push with changes to this and ‘emacs-inputs’ as discussed above.

Thank you, and sorry for being as predictable and boring as you
expected.  ;-)

Ludo’.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-06-21  8:31 Federico Beffa
  2015-06-21 20:40 ` Alex Kost
@ 2015-07-06 17:47 ` Alex Kost
  1 sibling, 0 replies; 24+ messages in thread
From: Alex Kost @ 2015-07-06 17:47 UTC (permalink / raw)
  To: guix-devel

Wouldn't it be better to name it "elpa-build-system" as that's what it
is in my opinion, since it does not retrieve the source directly from
upstream but from ELPA/MELPA/... "repositories" instead.

I imagine there may appear another build system for simple emacs
packages (that don't provide Makefile, etc.) that will compile elisp
files, generate autoloads and so on.  I think it will be a system that
should be called "emacs-build-system".  WDYT?

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
@ 2015-07-07  7:21 Federico Beffa
  2015-07-07 16:58 ` Alex Kost
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-07-07  7:21 UTC (permalink / raw)
  To: alezost; +Cc: Guix-devel

Alex Kost <alezost@gmail.com> writes:

> Wouldn't it be better to name it "elpa-build-system" as that's what it
> is in my opinion, since it does not retrieve the source directly from
> upstream but from ELPA/MELPA/... "repositories" instead.

The build system doesn't assume anything about the source location.

>
> I imagine there may appear another build system for simple emacs
> packages (that don't provide Makefile, etc.) that will compile elisp
> files, generate autoloads and so on.  I think it will be a system that
> should be called "emacs-build-system".  WDYT?

That's what the proposed build system does. If it lacks some
functionality that you think is desirable, I think it is better to add
it here rather than adding another, almost identical, build system.

Regards,
Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-07  7:21 [PATCH 3/5] build: Add 'emacs-build-system' Federico Beffa
@ 2015-07-07 16:58 ` Alex Kost
  2015-07-08 20:22   ` Federico Beffa
  0 siblings, 1 reply; 24+ messages in thread
From: Alex Kost @ 2015-07-07 16:58 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

Federico Beffa (2015-07-07 10:21 +0300) wrote:

> Alex Kost <alezost@gmail.com> writes:
>
>> Wouldn't it be better to name it "elpa-build-system" as that's what it
>> is in my opinion, since it does not retrieve the source directly from
>> upstream but from ELPA/MELPA/... "repositories" instead.
>
> The build system doesn't assume anything about the source location.
>>
>> I imagine there may appear another build system for simple emacs
>> packages (that don't provide Makefile, etc.) that will compile elisp
>> files, generate autoloads and so on.  I think it will be a system that
>> should be called "emacs-build-system".  WDYT?
>
> That's what the proposed build system does. If it lacks some
> functionality that you think is desirable, I think it is better to add
> it here rather than adding another, almost identical, build system.

Ah, I'm very sorry, You are right; emacs build system and elpa importer
were mixed in my head :-)

A side note: I think generally it would be preferable to use an upstream
release in the package recipe rather than to use a melpa(-stable) URL,
i.e.:

  http://foo-upstream.org/foo-0.1.tar.gz  instead of
  http://stable.melpa.org/packages/foo-0.1.tar

Also along with the concern that melpa stores a tarball only for the
latest package version I think I've found another problem that will
happen with a package from any repository: there are many single-file
packages and these ones are not put in tarballs.  I mean the package in
this case is just a simple elisp file, so the 'unpack' will fail.

Look at <http://elpa.gnu.org/packages/rainbow-mode.html> for example:

  guix import elpa --archive=gnu rainbow-mode

gives a package that fails on 'unpack' phase.

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-07 16:58 ` Alex Kost
@ 2015-07-08 20:22   ` Federico Beffa
  2015-07-09  8:51     ` Alex Kost
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-07-08 20:22 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

On Tue, Jul 7, 2015 at 6:58 PM, Alex Kost <alezost@gmail.com> wrote:
> A side note: I think generally it would be preferable to use an upstream
> release in the package recipe rather than to use a melpa(-stable) URL,
> i.e.:
>
>   http://foo-upstream.org/foo-0.1.tar.gz  instead of
>   http://stable.melpa.org/packages/foo-0.1.tar

I believe that such information is not available from ELPA archives.
Therefore the ELPA importer has no way to do this. But, obviously,
manual modification is possible. (By the way, the tar files are
similar but not identical.)

>
> Also along with the concern that melpa stores a tarball only for the
> latest package version I think I've found another problem that will
> happen with a package from any repository: there are many single-file
> packages and these ones are not put in tarballs.  I mean the package in
> this case is just a simple elisp file, so the 'unpack' will fail.
>
> Look at <http://elpa.gnu.org/packages/rainbow-mode.html> for example:
>
>   guix import elpa --archive=gnu rainbow-mode
>
> gives a package that fails on 'unpack' phase.

Currently this can be handled, as in many packages using other build
systems, by custom phases. But handling of this type of packages would
definitely be useful. Unfortunately, in the near future, I will not
have time to spend on this. I've pushed the code as reviewed on the ML
today. If you are interested, feel free to improve/extend it.

Regards,
Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-08 20:22   ` Federico Beffa
@ 2015-07-09  8:51     ` Alex Kost
  2015-07-09 20:41       ` Federico Beffa
  0 siblings, 1 reply; 24+ messages in thread
From: Alex Kost @ 2015-07-09  8:51 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

Federico Beffa (2015-07-08 23:22 +0300) wrote:

> On Tue, Jul 7, 2015 at 6:58 PM, Alex Kost <alezost@gmail.com> wrote:
>> A side note: I think generally it would be preferable to use an upstream
>> release in the package recipe rather than to use a melpa(-stable) URL,
>> i.e.:
>>
>>   http://foo-upstream.org/foo-0.1.tar.gz  instead of
>>   http://stable.melpa.org/packages/foo-0.1.tar
>
> I believe that such information is not available from ELPA archives.
> Therefore the ELPA importer has no way to do this. But, obviously,
> manual modification is possible. (By the way, the tar files are
> similar but not identical.)

Surely, I didn't mean that it's a task for the elpa importer.  I'm
totally for the manual modification to use an upstream release, not the
melpa(-stable) one.

By "the tar files are similar" do you mean that MELPA usually leaves
only elisp files in the tarballs?  I think since it's a common practice
to put elisp files in the root directory of the repo, we should add a
phase to the emacs build system to remove non-elisp files (like
.gitignore or README) from the final
/gnu/store/…-foo-0.1/share/emacs/site-lisp/guix.d/foo-0.1/ directory.

>> Also along with the concern that melpa stores a tarball only for the
>> latest package version I think I've found another problem that will
>> happen with a package from any repository: there are many single-file
>> packages and these ones are not put in tarballs.  I mean the package in
>> this case is just a simple elisp file, so the 'unpack' will fail.
>>
>> Look at <http://elpa.gnu.org/packages/rainbow-mode.html> for example:
>>
>>   guix import elpa --archive=gnu rainbow-mode
>>
>> gives a package that fails on 'unpack' phase.
>
> Currently this can be handled, as in many packages using other build
> systems, by custom phases. But handling of this type of packages would
> definitely be useful. Unfortunately, in the near future, I will not
> have time to spend on this. I've pushed the code as reviewed on the ML
> today. If you are interested, feel free to improve/extend it.

Thanks for the proposal :-)

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-09  8:51     ` Alex Kost
@ 2015-07-09 20:41       ` Federico Beffa
  2015-07-10  6:47         ` Alex Kost
  0 siblings, 1 reply; 24+ messages in thread
From: Federico Beffa @ 2015-07-09 20:41 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

On Thu, Jul 9, 2015 at 10:51 AM, Alex Kost <alezost@gmail.com> wrote:
> Federico Beffa (2015-07-08 23:22 +0300) wrote:
>
>> On Tue, Jul 7, 2015 at 6:58 PM, Alex Kost <alezost@gmail.com> wrote:
>>> A side note: I think generally it would be preferable to use an upstream
>>> release in the package recipe rather than to use a melpa(-stable) URL,
>>> i.e.:
>>>
>>>   http://foo-upstream.org/foo-0.1.tar.gz  instead of
>>>   http://stable.melpa.org/packages/foo-0.1.tar
>>
>> I believe that such information is not available from ELPA archives.
>> Therefore the ELPA importer has no way to do this. But, obviously,
>> manual modification is possible. (By the way, the tar files are
>> similar but not identical.)
>
> Surely, I didn't mean that it's a task for the elpa importer.  I'm
> totally for the manual modification to use an upstream release, not the
> melpa(-stable) one.
>
> By "the tar files are similar" do you mean that MELPA usually leaves
> only elisp files in the tarballs?  I think since it's a common practice
> to put elisp files in the root directory of the repo, we should add a
> phase to the emacs build system to remove non-elisp files (like
> .gitignore or README) from the final
> /gnu/store/…-foo-0.1/share/emacs/site-lisp/guix.d/foo-0.1/ directory.

One difference that I noticed in the tar files is that tar coming from
elpa archives always include the .info file, while the upstream ones
do not always do so. I've not investigated further differences.

While often the READMEs are not very usefull, sometimes they are.
Therefore I do not like the idea of removing them, nor anything else
provided by the package. It's upstream who should decide what's
relevant. With the use of 'guix.d' there will be no name clashes. Did
you happen to see the following thread?

https://lists.gnu.org/archive/html/guix-devel/2015-06/msg00392.html

Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-09 20:41       ` Federico Beffa
@ 2015-07-10  6:47         ` Alex Kost
  2015-07-10  7:43           ` Federico Beffa
  2015-07-15 21:52           ` Ludovic Courtès
  0 siblings, 2 replies; 24+ messages in thread
From: Alex Kost @ 2015-07-10  6:47 UTC (permalink / raw)
  To: Federico Beffa; +Cc: Guix-devel

[-- Attachment #1: Type: text/plain, Size: 2824 bytes --]

Federico Beffa (2015-07-09 23:41 +0300) wrote:

> On Thu, Jul 9, 2015 at 10:51 AM, Alex Kost <alezost@gmail.com> wrote:
>> Federico Beffa (2015-07-08 23:22 +0300) wrote:
>>
>>> On Tue, Jul 7, 2015 at 6:58 PM, Alex Kost <alezost@gmail.com> wrote:
>>>> A side note: I think generally it would be preferable to use an upstream
>>>> release in the package recipe rather than to use a melpa(-stable) URL,
>>>> i.e.:
>>>>
>>>>   http://foo-upstream.org/foo-0.1.tar.gz  instead of
>>>>   http://stable.melpa.org/packages/foo-0.1.tar
>>>
>>> I believe that such information is not available from ELPA archives.
>>> Therefore the ELPA importer has no way to do this. But, obviously,
>>> manual modification is possible. (By the way, the tar files are
>>> similar but not identical.)
>>
>> Surely, I didn't mean that it's a task for the elpa importer.  I'm
>> totally for the manual modification to use an upstream release, not the
>> melpa(-stable) one.
>>
>> By "the tar files are similar" do you mean that MELPA usually leaves
>> only elisp files in the tarballs?  I think since it's a common practice
>> to put elisp files in the root directory of the repo, we should add a
>> phase to the emacs build system to remove non-elisp files (like
>> .gitignore or README) from the final
>> /gnu/store/…-foo-0.1/share/emacs/site-lisp/guix.d/foo-0.1/ directory.
>
> One difference that I noticed in the tar files is that tar coming from
> elpa archives always include the .info file, while the upstream ones
> do not always do so. I've not investigated further differences.

I think that the upstream never include (at least they shouldn't)
".info" files.  So perhaps it would be good to add a phase for building
info manual if there are ".texi" files and no ".info".

> While often the READMEs are not very usefull, sometimes they are.

But do people look at ~/.guix-profile/share/emacs/site-lisp/guix.d/foo
directory to find README and other useful non-elisp files?

> Therefore I do not like the idea of removing them, nor anything else
> provided by the package. It's upstream who should decide what's
> relevant. With the use of 'guix.d' there will be no name clashes. Did
> you happen to see the following thread?
>
> https://lists.gnu.org/archive/html/guix-devel/2015-06/msg00392.html

Yes, I read it, but when you say «provided by the package» and «It's
upstream who should decide», you are talking about the packages imported
from (m)elpa, not the upstream itself.  Since melpa is unusable (due to
a hash problem), we'll have to use the direct upstream releases, which
are not stripped from ".gitignore" and other unrelated files.  So all
these files will move into "…/.guix.d/package" dir.

As an example, try the following variant of "emacs-mmm-mode" package:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: emacs-mmm-mode.scm --]
[-- Type: text/x-scheme, Size: 727 bytes --]

(define-public emacs-mmm-mode
  (package
    (name "emacs-mmm-mode")
    (version "0.5.4")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "https://github.com/purcell/mmm-mode/archive/"
             version ".tar.gz"))
       (file-name (string-append name "-" version ".tar.gz"))
       (sha256
        (base32
         "10kwslnflbjqm62wkrq420crqzdqalzfflp9pqk1i12zm6dm4mfv"))))
    (build-system emacs-build-system)
    (home-page "https://github.com/purcell/mmm-mode")
    (synopsis
     "Allow multiple major modes in an Emacs buffer")
    (description
     "MMM Mode is a minor mode that allows multiple major modes to coexist in a
single buffer.")
    (license license:gpl3+)))

[-- Attachment #3: Type: text/plain, Size: 898 bytes --]


As you can see, there are many odd files in the
"…/share/emacs/site-lisp/guix.d/mmm-mode-0.5.4" directory.

So I suggest to add a phase for deleting non-".el[c]" files from the
".guix.d/package" directory.

And just in case: I have nothing against GNU ELPA repository (especially
taking into account that it is the only "home" for some packages).  I'm
against melpa and melpa-stable, because:

- Why should we rely on a third-party server that do something with the
  upstream files to produce a final tarball?

- MELPA(-stable) is not usable anyway, because the tarballs of the same
  version are updated all the time, so the hash is being permanently
  changed.

However, if a package from ELPA has a real upstream release that can be
used with "gnu-build-system" (e.g., emms, auctex, mmm-mode), I think we
should prefer it instead of importing it from ELPA.

-- 
Alex

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-10  6:47         ` Alex Kost
@ 2015-07-10  7:43           ` Federico Beffa
  2015-07-15 21:52           ` Ludovic Courtès
  1 sibling, 0 replies; 24+ messages in thread
From: Federico Beffa @ 2015-07-10  7:43 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel

On Fri, Jul 10, 2015 at 8:47 AM, Alex Kost <alezost@gmail.com> wrote:
> Federico Beffa (2015-07-09 23:41 +0300) wrote:
>
>> On Thu, Jul 9, 2015 at 10:51 AM, Alex Kost <alezost@gmail.com> wrote:
>>> Federico Beffa (2015-07-08 23:22 +0300) wrote:
>>>
>>>> On Tue, Jul 7, 2015 at 6:58 PM, Alex Kost <alezost@gmail.com> wrote:
>>>>> A side note: I think generally it would be preferable to use an upstream
>>>>> release in the package recipe rather than to use a melpa(-stable) URL,
>>>>> i.e.:
>>>>>
>>>>>   http://foo-upstream.org/foo-0.1.tar.gz  instead of
>>>>>   http://stable.melpa.org/packages/foo-0.1.tar
>>>>
>>>> I believe that such information is not available from ELPA archives.
>>>> Therefore the ELPA importer has no way to do this. But, obviously,
>>>> manual modification is possible. (By the way, the tar files are
>>>> similar but not identical.)
>>>
>>> Surely, I didn't mean that it's a task for the elpa importer.  I'm
>>> totally for the manual modification to use an upstream release, not the
>>> melpa(-stable) one.
>>>
>>> By "the tar files are similar" do you mean that MELPA usually leaves
>>> only elisp files in the tarballs?  I think since it's a common practice
>>> to put elisp files in the root directory of the repo, we should add a
>>> phase to the emacs build system to remove non-elisp files (like
>>> .gitignore or README) from the final
>>> /gnu/store/…-foo-0.1/share/emacs/site-lisp/guix.d/foo-0.1/ directory.
>>
>> One difference that I noticed in the tar files is that tar coming from
>> elpa archives always include the .info file, while the upstream ones
>> do not always do so. I've not investigated further differences.
>
> I think that the upstream never include (at least they shouldn't)
> ".info" files.  So perhaps it would be good to add a phase for building
> info manual if there are ".texi" files and no ".info".
>
>> While often the READMEs are not very usefull, sometimes they are.
>
> But do people look at ~/.guix-profile/share/emacs/site-lisp/guix.d/foo
> directory to find README and other useful non-elisp files?

My guess is that people using the Emacs packaging system (and by
extension Emacs users) do, because that's very similar to the Emacs'
native packaging strategy.

>
>> Therefore I do not like the idea of removing them, nor anything else
>> provided by the package. It's upstream who should decide what's
>> relevant. With the use of 'guix.d' there will be no name clashes. Did
>> you happen to see the following thread?
>>
>> https://lists.gnu.org/archive/html/guix-devel/2015-06/msg00392.html
>
> Yes, I read it, but when you say «provided by the package» and «It's
> upstream who should decide», you are talking about the packages imported
> from (m)elpa, not the upstream itself.  Since melpa is unusable (due to
> a hash problem), we'll have to use the direct upstream releases, which
> are not stripped from ".gitignore" and other unrelated files.  So all
> these files will move into "…/.guix.d/package" dir.
>
> As an example, try the following variant of "emacs-mmm-mode" package:
>
>
>
> As you can see, there are many odd files in the
> "…/share/emacs/site-lisp/guix.d/mmm-mode-0.5.4" directory.
>
> So I suggest to add a phase for deleting non-".el[c]" files from the
> ".guix.d/package" directory.
>
> And just in case: I have nothing against GNU ELPA repository (especially
> taking into account that it is the only "home" for some packages).  I'm
> against melpa and melpa-stable, because:
>
> - Why should we rely on a third-party server that do something with the
>   upstream files to produce a final tarball?

Well, that's just a necessary step to make Emacs 'package.el' work properly.

>
> - MELPA(-stable) is not usable anyway, because the tarballs of the same
>   version are updated all the time, so the hash is being permanently
>   changed.
>
> However, if a package from ELPA has a real upstream release that can be
> used with "gnu-build-system" (e.g., emms, auctex, mmm-mode), I think we
> should prefer it instead of importing it from ELPA.

Nowadays many Emacs packages recommend to use Emacs' packaging system
as the preferred method of installation. See e.g.
https://github.com/purcell/mmm-mode

However, the hash problem with packages from melpa appears to be a show stopper.

Fede

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/5] build: Add 'emacs-build-system'
  2015-07-10  6:47         ` Alex Kost
  2015-07-10  7:43           ` Federico Beffa
@ 2015-07-15 21:52           ` Ludovic Courtès
  1 sibling, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2015-07-15 21:52 UTC (permalink / raw)
  To: Alex Kost; +Cc: Guix-devel, Federico Beffa

Alex Kost <alezost@gmail.com> skribis:

> So I suggest to add a phase for deleting non-".el[c]" files from the
> ".guix.d/package" directory.

Agreed; what about putting READMEs etc. elsewhere, like under
‘share/doc/PACKAGE’ if we want to preserve them?

> And just in case: I have nothing against GNU ELPA repository (especially
> taking into account that it is the only "home" for some packages).  I'm
> against melpa and melpa-stable, because:
>
> - Why should we rely on a third-party server that do something with the
>   upstream files to produce a final tarball?
>
> - MELPA(-stable) is not usable anyway, because the tarballs of the same
>   version are updated all the time, so the hash is being permanently
>   changed.

I agree that these two points make MELPA (at least the MELPA server)
unsuitable for our purposes.

Of course it’s still useful to import recipes from there and use them as
a starting point for packages.

> However, if a package from ELPA has a real upstream release that can be
> used with "gnu-build-system" (e.g., emms, auctex, mmm-mode), I think we
> should prefer it instead of importing it from ELPA.

Agreed.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2015-07-15 21:52 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-07  7:21 [PATCH 3/5] build: Add 'emacs-build-system' Federico Beffa
2015-07-07 16:58 ` Alex Kost
2015-07-08 20:22   ` Federico Beffa
2015-07-09  8:51     ` Alex Kost
2015-07-09 20:41       ` Federico Beffa
2015-07-10  6:47         ` Alex Kost
2015-07-10  7:43           ` Federico Beffa
2015-07-15 21:52           ` Ludovic Courtès
  -- strict thread matches above, loose matches on Subject: below --
2015-06-21  8:31 Federico Beffa
2015-06-21 20:40 ` Alex Kost
2015-06-22  8:51   ` Federico Beffa
2015-06-22 11:49     ` Mathieu Lirzin
2015-06-22 17:59     ` Alex Kost
2015-06-22 19:33       ` Federico Beffa
2015-06-22 19:40         ` Thompson, David
2015-06-23  6:51           ` Federico Beffa
2015-06-25 11:57             ` Ludovic Courtès
2015-06-25 18:39               ` Federico Beffa
2015-06-23 11:57         ` Alex Kost
2015-06-24 16:12           ` Federico Beffa
2015-06-25 12:33             ` Ludovic Courtès
2015-06-25 18:36               ` Federico Beffa
2015-06-27  9:59                 ` Ludovic Courtès
2015-07-06 17:47 ` Alex Kost

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).