~ruther/guix-local

3cb3fa6747251c6beac226d0233063524bd5f4d6 — Christopher Baines 8 years ago b1225dd
guix: build: ruby-build-system: Install to the vendor directory

* guix/build/ruby-build-system.scm (install): Install gems to the vendor
  directory, rather than the GEM_HOME. The vendor directory does not include
  the version of ruby used to install the gem in the path, which makes it
  easier to add it to the GEM_PATH for all versions of ruby to use.
  (gem-home): Remove procedure.
* gnu/packages/ruby.scm (ruby, ruby-2.1)[native-search-paths]: Switch to
  lib/ruby/vendor_ruby.
  (ruby-1.8)[native-search-paths]: Remove native-search-paths.
  (gem-directory): Remove procedure.
  (ruby-ansi, ruby-ae)[arguments]: Remove use of gem-directory.
  (ruby-metaclass, ruby-instantiator, ruby-introspection, ruby-mocha,
  ruby-nokogiri, ruby-minitest-tu-shim, ruby-redcloth)[arguments]: Remove use
  of gem-home.
  (ruby-git, ruby-httpclient)[arguments]: Remove use of GEM_HOME.
* gnu/packages/databases.scm (es-dump-restore)[arguments]: Remove use of
  GEM_HOME.
3 files changed, 56 insertions(+), 81 deletions(-)

M gnu/packages/databases.scm
M gnu/packages/ruby.scm
M guix/build/ruby-build-system.scm
M gnu/packages/databases.scm => gnu/packages/databases.scm +4 -4
@@ 298,10 298,10 @@ SQL, Key/Value, XML/XQuery or Java Object storage for their data model.")
           (lambda* (#:key outputs #:allow-other-keys)
             (wrap-program (string-append (assoc-ref outputs "out")
                                          "/bin/es_dump_restore")
               `("GEM_PATH" ":" prefix (,(string-append
                                          (getenv "GEM_PATH")
                                          ":"
                                          (getenv "GEM_HOME")))))
               `("GEM_PATH" ":" prefix (,(getenv "GEM_PATH")
                                        ,(string-append
                                          (assoc-ref outputs "out")
                                          "/lib/ruby/vendor_ruby"))))
             #t)))))
    (propagated-inputs
     `(("ruby-httpclient" ,ruby-httpclient)

M gnu/packages/ruby.scm => gnu/packages/ruby.scm +28 -50
@@ 96,9 96,7 @@
    (native-search-paths
     (list (search-path-specification
            (variable "GEM_PATH")
            (files (list (string-append "lib/ruby/gems/"
                                        (version-major+minor version)
                                        ".0"))))))
            (files (list (string-append "lib/ruby/vendor_ruby"))))))
    (synopsis "Programming language interpreter")
    (description "Ruby is a dynamic object-oriented programming language with
a focus on simplicity and productivity.")


@@ 182,13 180,7 @@ a focus on simplicity and productivity.")
                            "lib/mkmf.rb"
                            "process.c")
               (("/bin/sh") (which "sh")))
             #t)))))
    (native-search-paths
     (list (search-path-specification
            (variable "GEM_PATH")
            (files (list (string-append "lib/ruby/gems/"
                                        (version-major+minor version)
                                        ".0"))))))))
             #t)))))))

(define-public ruby-1.8
  (package (inherit ruby)


@@ 218,11 210,6 @@ a focus on simplicity and productivity.")
               (("/bin/sh") (which "sh")))
             #t)))))))

(define (gem-directory ruby-version)
  "Return the relative gem install directory for RUBY-VERSION."
  (string-append "/lib/ruby/gems/" (version-major+minor ruby-version)
                 ".0/gems"))

(define-public ruby-highline
  (package
    (name "ruby-highline")


@@ 1322,13 1309,11 @@ It allows writing tests, checking results and automated testing in Ruby.")
       (modify-phases %standard-phases
         (add-after 'unpack 'add-test-unit-to-search-path
           (lambda* (#:key inputs #:allow-other-keys)
             (let* ((test-unit (assoc-ref inputs "ruby-test-unit"))
                    (test-unit-home (gem-home test-unit
                                              ,(package-version ruby))))
             (let* ((test-unit (assoc-ref inputs "ruby-test-unit")))
               (substitute* "Rakefile"
                 (("t\\.libs << \"test\"" line)
                  (string-append line "; t.libs << \""
                                 test-unit-home
                                 test-unit "/lib/ruby/vendor_ruby"
                                 "/gems/test-unit-"
                                 ,(package-version ruby-test-unit)
                                 "/lib\""))))


@@ 1387,13 1372,11 @@ as a base class when writing classes that depend upon
       (modify-phases %standard-phases
         (add-after 'unpack 'add-test-unit-to-search-path
           (lambda* (#:key inputs #:allow-other-keys)
             (let* ((test-unit (assoc-ref inputs "ruby-test-unit"))
                    (test-unit-home (gem-home test-unit ,(package-version
                                                          ruby))))
             (let* ((test-unit (assoc-ref inputs "ruby-test-unit")))
               (substitute* "Rakefile"
                 (("t\\.libs << \"test\"" line)
                  (string-append line "; t.libs << \""
                                 test-unit-home
                                 test-unit "/lib/ruby/vendor_ruby"
                                 "/gems/test-unit-"
                                 ,(package-version ruby-test-unit)
                                 "/lib\""))))


@@ 1426,13 1409,11 @@ knowing anything about the constructor.")
       (modify-phases %standard-phases
         (add-after 'unpack 'add-test-unit-to-search-path
          (lambda* (#:key inputs #:allow-other-keys)
            (let* ((test-unit (assoc-ref inputs "ruby-test-unit"))
                   (test-unit-home (gem-home test-unit ,(package-version
                                                         ruby))))
            (let* ((test-unit (assoc-ref inputs "ruby-test-unit")))
              (substitute* "Rakefile"
                (("t\\.libs << \"test\"" line)
                 (string-append line "; t.libs << \""
                                test-unit-home
                                test-unit "/lib/ruby/vendor_ruby"
                                "/gems/test-unit-"
                                ,(package-version ruby-test-unit)
                                "/lib\""))))


@@ 1499,13 1480,11 @@ conversion to (X)HTML.")
       (modify-phases %standard-phases
         (add-after 'unpack 'add-test-unit-to-search-path
          (lambda* (#:key inputs #:allow-other-keys)
            (let* ((test-unit (assoc-ref inputs "ruby-test-unit"))
                   (test-unit-home (gem-home test-unit
                                             ,(package-version ruby))))
            (let* ((test-unit (assoc-ref inputs "ruby-test-unit")))
              (substitute* "Rakefile"
                (("t\\.libs << 'test'" line)
                 (string-append line "; t.libs << \""
                                test-unit-home
                                test-unit "/lib/ruby/vendor_ruby"
                                "/gems/test-unit-"
                                ,(package-version ruby-test-unit)
                                "/lib\""))))


@@ 1870,9 1849,10 @@ run as a daemon and to be controlled by simple start/stop/restart commands.")
                      ;; store.
                      (let ((git    (string-append (assoc-ref inputs "git")
                                                   "/bin/git"))
                            (config (string-append (getenv "GEM_HOME")
                                                   "/gems/git-" ,version
                                                   "/lib/git/config.rb")))
                            (config (string-append
                                     (assoc-ref outputs "out")
                                     "/lib/ruby/vendor_ruby/gems/git-"
                                     ,version "/lib/git/config.rb")))
                        (substitute* (list config)
                          (("'git'")
                           (string-append "'" git "'")))


@@ 2057,13 2037,11 @@ to reproduce user environments.")
           ;; 'pkg-config' is not included in the GEM_PATH during
           ;; installation, so we add it directly to the load path.
           (lambda* (#:key inputs #:allow-other-keys)
             (let* ((pkg-config (assoc-ref inputs "ruby-pkg-config"))
                    (pkg-config-home (gem-home pkg-config
                                               ,(package-version ruby))))
             (let* ((pkg-config (assoc-ref inputs "ruby-pkg-config")))
               (substitute* "ext/nokogiri/extconf.rb"
                 (("gem 'pkg-config'.*")
                  (string-append "$:.unshift '"
                                 pkg-config-home
                                 pkg-config "/lib/ruby/vendor_ruby"
                                 "/gems/pkg-config-"
                                 ,(package-version ruby-pkg-config)
                                 "/lib'\n"))))


@@ 2470,13 2448,11 @@ development of Ruby gems.")
       (modify-phases %standard-phases
         (add-after 'unpack 'fix-test-include-path
          (lambda* (#:key inputs #:allow-other-keys)
             (let* ((minitest (assoc-ref inputs "ruby-minitest-4"))
                    (minitest-home (gem-home minitest
                                             ,(package-version ruby))))
             (let* ((minitest (assoc-ref inputs "ruby-minitest-4")))
               (substitute* "Rakefile"
                 (("Hoe\\.add_include_dirs .*")
                  (string-append "Hoe.add_include_dirs \""
                                 minitest-home
                                 minitest "/lib/ruby/vendor_ruby"
                                 "/gems/minitest-"
                                 ,(package-version ruby-minitest-4)
                                 "/lib" "\""))))


@@ 2883,7 2859,9 @@ alternative to Marshal for Object serialization. ")
          (lambda* (#:key outputs #:allow-other-keys)
            (wrap-program (string-append (assoc-ref outputs "out")
                                         "/bin/redcloth")
              `("GEM_HOME" ":" prefix (,(getenv "GEM_HOME"))))
              `("GEM_PATH" ":" prefix (,(string-append
                                         (assoc-ref outputs "out")
                                         "/lib/ruby/vendor_ruby"))))
            #t)))))
    (native-inputs
     `(("bundler" ,bundler)


@@ 3737,7 3715,7 @@ It has built-in support for the legacy @code{cookies.txt} and
           (lambda* (#:key outputs #:allow-other-keys)
             (wrap-program (string-append (assoc-ref outputs "out")
                                          "/bin/httpclient")
               `("GEM_HOME" ":" prefix (,(getenv "GEM_HOME"))))
               `("GEM_PATH" ":" prefix (,(getenv "GEM_PATH"))))
             #t)))))
    (native-inputs
     `(("ruby-rack" ,ruby-rack)))


@@ 3780,9 3758,9 @@ requests either using arguments or with an interactive prompt.")
         (add-before 'validate-runpath 'replace-broken-symlink
           (lambda* (#:key outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (file (string-append out
                                         ,(gem-directory (package-version ruby))
                                         "/ansi-" ,version "/lib/ansi.yml")))
                    (file (string-append
                           out "/lib/ruby/vendor_ruby/gems/ansi-"
                           ,version "/lib/ansi.yml")))
               ;; XXX: This symlink is broken since ruby 2.4.
               ;; https://lists.gnu.org/archive/html/guix-devel/2017-06/msg00034.html
               (delete-file file)


@@ 3980,9 3958,9 @@ requirement specifications systems like Cucumber.")
         (add-before 'validate-runpath 'replace-broken-symlink
           (lambda* (#:key outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (file (string-append out
                                         ,(gem-directory (package-version ruby))
                                         "/ae-" ,version "/lib/ae.yml")))
                    (file (string-append
                           out "/lib/ruby/vendor_ruby/gems/ae-"
                           ,version "/lib/ae.yml")))
               ;; XXX: This symlink is broken since ruby 2.4.
               ;; https://lists.gnu.org/archive/html/guix-devel/2017-06/msg00034.html
               (delete-file file)

M guix/build/ruby-build-system.scm => guix/build/ruby-build-system.scm +24 -27
@@ 27,8 27,7 @@
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:export (%standard-phases
            ruby-build
            gem-home))
            ruby-build))

;; Commentary:
;;


@@ 129,40 128,48 @@ GEM-FLAGS are passed to the 'gem' invokation, if present."
                                         (assoc-ref inputs "ruby"))
                           1))
         (out (assoc-ref outputs "out"))
         (gem-home (string-append out "/lib/ruby/gems/" ruby-version ".0"))
         (vendor-dir (string-append out "/lib/ruby/vendor_ruby"))
         (gem-file (first-matching-file "\\.gem$"))
         (gem-file-basename (basename gem-file))
         (gem-name (substring gem-file-basename
                              0
                              (- (string-length gem-file-basename) 4)))
         (gem-directory (string-append gem-home "/gems/" gem-name)))
    (setenv "GEM_HOME" gem-home)
    (mkdir-p gem-home)
    (and (apply system* "gem" "install" gem-file
                "--local" "--ignore-dependencies"
                ;; Executables should go into /bin, not /lib/ruby/gems.
                "--bindir" (string-append out "/bin")
                gem-flags)
                              (- (string-length gem-file-basename) 4))))
    (setenv "GEM_VENDOR" vendor-dir)
    (and (let ((install-succeeded?
                (zero?
                 (apply system* "gem" "install" gem-file
                        "--local" "--ignore-dependencies" "--vendor"
                        ;; Executables should go into /bin, not
                        ;; /lib/ruby/gems.
                        "--bindir" (string-append out "/bin")
                        gem-flags))))
           (or install-succeeded?
               (begin
                 (simple-format #t "installation failed\n")
                 (let ((failed-output-dir (string-append (getcwd) "/out")))
                   (mkdir failed-output-dir)
                   (copy-recursively out failed-output-dir))
                 #f)))
         (begin
           ;; Remove the cached gem file as this is unnecessary and contains
           ;; timestamped files rendering builds not reproducible.
           (let ((cached-gem (string-append gem-home "/cache/" gem-file)))
           (let ((cached-gem (string-append vendor-dir "/cache/" gem-file)))
             (log-file-deletion cached-gem)
             (delete-file cached-gem))
           ;; For gems with native extensions, several Makefile-related files
           ;; are created that contain timestamps or other elements making
           ;; them not reproducible.  They are unnecessary so we remove them.
           (if (file-exists? (string-append gem-directory "/ext"))
           (if (file-exists? (string-append vendor-dir "/ext"))
               (begin
                 (for-each (lambda (file)
                             (log-file-deletion file)
                             (delete-file file))
                           (append
                            (find-files (string-append gem-home "/doc")
                            (find-files (string-append vendor-dir "/doc")
                                        "page-Makefile.ri")
                            (find-files (string-append gem-home "/extensions")
                            (find-files (string-append vendor-dir "/extensions")
                                        "gem_make.out")
                            (find-files (string-append gem-directory "/ext")
                            (find-files (string-append vendor-dir "/ext")
                                        "Makefile")))))
           #t))))



@@ 182,13 189,3 @@ GEM-FLAGS are passed to the 'gem' invokation, if present."
(define* (ruby-build #:key inputs (phases %standard-phases)
                     #:allow-other-keys #:rest args)
  (apply gnu:gnu-build #:inputs inputs #:phases phases args))

(define (gem-home store-path ruby-version)
  "Return a string to the gem home directory in the store given a STORE-PATH
and the RUBY-VERSION used to build that ruby package"
  (string-append
   store-path
   "/lib/ruby/gems/"
   (regexp-substitute #f
                      (string-match "^[0-9]+\\.[0-9]+" ruby-version)
                      0 ".0")))