~ruther/guix-local

c08f9818f91c3242c38d1c78823641ab3b1e7d58 — David Thompson 11 years ago 6ef8c59
build: Add ruby build system.

* guix/build-system/ruby.scm: New file.
* guix/build/ruby-build-system: New file.
* Makefile.am (MODULES): Add new files.
* doc/guix.texi (Build Systems): Document ruby-build-system.
4 files changed, 193 insertions(+), 0 deletions(-)

M Makefile.am
M doc/guix.texi
A guix/build-system/ruby.scm
A guix/build/ruby-build-system.scm
M Makefile.am => Makefile.am +2 -0
@@ 50,6 50,7 @@ MODULES =					\
  guix/build-system/gnu.scm			\
  guix/build-system/perl.scm			\
  guix/build-system/python.scm			\
  guix/build-system/ruby.scm			\
  guix/build-system/trivial.scm			\
  guix/ftp-client.scm				\
  guix/http-client.scm				\


@@ 64,6 65,7 @@ MODULES =					\
  guix/build/gnu-dist.scm			\
  guix/build/perl-build-system.scm		\
  guix/build/python-build-system.scm		\
  guix/build/ruby-build-system.scm		\
  guix/build/store-copy.scm			\
  guix/build/utils.scm				\
  guix/build/union.scm				\

M doc/guix.texi => doc/guix.texi +8 -0
@@ 1648,6 1648,14 @@ the @code{#:make-maker-flags} parameter.
Which Perl package is used can be specified with @code{#:perl}.
@end defvr

@defvr {Scheme Variable} ruby-build-system
This variable is exported by @code{(guix build-system ruby)}.  It
implements the RubyGems build procedure used by Ruby packages, which
involves running @code{gem build} followed by @code{gem install}.

Which Ruby package is used can be specified with the @code{#:ruby}
parameter.
@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

A guix/build-system/ruby.scm => guix/build-system/ruby.scm +108 -0
@@ 0,0 1,108 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014 David Thompson <davet@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix build-system ruby)
  #:use-module (guix store)
  #:use-module (guix utils)
  #:use-module (guix packages)
  #:use-module (guix derivations)
  #:use-module (guix build-system)
  #:use-module (guix build-system gnu)
  #:use-module (gnu packages version-control)
  #:use-module (ice-9 match)
  #:use-module (srfi srfi-26)
  #:export (ruby-build
            ruby-build-system))

(define (default-ruby)
  "Return the default Ruby package."
  ;; Lazily resolve the binding to avoid a circular dependency.
  (let ((ruby (resolve-interface '(gnu packages ruby))))
    (module-ref ruby 'ruby)))

(define* (ruby-build store name source inputs
                     #:key
                     (ruby (default-ruby))
                     (test-target "test")
                     (tests? #t)
                     (phases '(@ (guix build ruby-build-system)
                                 %standard-phases))
                     (outputs '("out"))
                     (search-paths '())
                     (system (%current-system))
                     (guile #f)
                     (imported-modules '((guix build ruby-build-system)
                                         (guix build gnu-build-system)
                                         (guix build utils)))
                     (modules '((guix build ruby-build-system)
                                (guix build utils))))
  "Build SOURCE using RUBY and INPUTS."
  (define ruby-search-paths
    (append (package-native-search-paths ruby)
            (standard-search-paths)))

  (define builder
    `(begin
       (use-modules ,@modules)
       (ruby-build #:name ,name
                   #:source ,(if (derivation? source)
                                 (derivation->output-path source)
                                 source)
                   #:system ,system
                   #:test-target ,test-target
                   #:tests? ,tests?
                   #:phases ,phases
                   #:outputs %outputs
                   #:search-paths ',(map search-path-specification->sexp
                                         (append ruby-search-paths
                                                 search-paths))
                   #:inputs %build-inputs)))

  (define guile-for-build
    (match guile
      ((? package?)
       (package-derivation store guile system))
      ((and (? string?) (? derivation-path?))
       guile)
      (#f
       (let* ((distro (resolve-interface '(gnu packages commencement)))
              (guile  (module-ref distro 'guile-final)))
         (package-derivation store guile system)))))

  (let ((ruby (package-derivation store ruby system))
        (git (package-derivation store git system)))
    (build-expression->derivation store name builder
                                  #:inputs
                                  `(,@(if source
                                          `(("source" ,source))
                                          '())
                                    ("ruby" ,ruby)
                                    ,@inputs
                                    ;; Keep the standard inputs of
                                    ;; 'gnu-build-system'.
                                    ,@(standard-inputs system))
                                  #:system system
                                  #:modules imported-modules
                                  #:outputs outputs
                                  #:guile-for-build guile-for-build)))

(define ruby-build-system
  (build-system
   (name 'ruby)
   (description "The standard Ruby build system")
   (build ruby-build)))

A guix/build/ruby-build-system.scm => guix/build/ruby-build-system.scm +75 -0
@@ 0,0 1,75 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014 David Thompson <davet@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix build ruby-build-system)
  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
  #:use-module (guix build utils)
  #:use-module (ice-9 match)
  #:use-module (ice-9 regex)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:export (%standard-phases
            ruby-build))

;; Commentary:
;;
;; Builder-side code of the standard Ruby package build procedure.
;;
;; Code:

(define (first-matching-file pattern)
  "Return the first file name that matches PATTERN in the current working
directory."
  (match (find-files "." pattern)
    ((file-name . _) file-name)
    (() (error "No files matching pattern: " pattern))))

(define build
  (lambda _
    (zero? (system* "gem" "build" (first-matching-file "\\.gemspec$")))))

(define* (check #:key tests? test-target #:allow-other-keys)
  (if tests?
      (zero? (system* "rake" test-target))
      #t))

(define* (install #:key source inputs outputs #:allow-other-keys)
  (let* ((ruby-version
          (match:substring (string-match "ruby-(.*)$"
                                         (assoc-ref inputs "ruby"))
                           1))
         (gem-home (string-append (assoc-ref outputs "out")
                                  "/lib/ruby/gems/"
                                  ruby-version)))
    (setenv "GEM_HOME" gem-home)
    (mkdir-p gem-home)
    (zero? (system* "gem" "install" "--local"
                    (first-matching-file "\\.gem$")))))

(define %standard-phases
  (alist-replace
   'build build
   (alist-replace
    'install install
    (alist-replace
     'check check
     (alist-delete 'configure gnu:%standard-phases)))))

(define* (ruby-build #:key inputs (phases %standard-phases)
                     #:allow-other-keys #:rest args)
  (apply gnu:gnu-build #:inputs inputs #:phases phases args))