From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Thompson Subject: [PATCH] build: ruby: Patch executables to set necessary gem load path. Date: Sat, 07 Mar 2015 19:00:06 -0500 Message-ID: <871tl04aux.fsf@fsf.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:48016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUOdd-0005G6-3e for guix-devel@gnu.org; Sat, 07 Mar 2015 19:00:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YUOdb-0004uu-OG for guix-devel@gnu.org; Sat, 07 Mar 2015 19:00:09 -0500 Received: from mail.fsf.org ([208.118.235.13]:56385) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUOdb-0004ul-Ju for guix-devel@gnu.org; Sat, 07 Mar 2015 19:00:07 -0500 Received: from 209-6-40-86.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.40.86]:49629 helo=izanagi) by mail.fsf.org with esmtpsa (TLS-1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1YUOda-0007VE-Un for guix-devel@gnu.org; Sat, 07 Mar 2015 19:00:07 -0500 List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: guix-devel@gnu.org --=-=-= Content-Type: text/plain This patch addresses the issue of how to ensure that Ruby executables are able to load all of the additional Ruby libraries that they need in order to work: with a new 'patch-executables' build phase. Instead of using wrap-program, I instead take advantage of the wrappers that the 'gem' command already creates for Ruby executables. There's guaranteed to be a line in which the executable's host gem is loaded that looks like `gem 'foo', version`. I simply insert a Ruby code snippet above it that adds all of the necessary gems to the 'Gem.path' array. Users of Ruby programs must still apply the $GEM_PATH suggested by 'guix package --search-paths' in order for the gem that the executable belongs to (the gem that they explicitly installed) to be found. I think this is reasonable and much like how you must set the proper load paths for Guile programs to work. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-build-ruby-Patch-executables-to-set-necessary-gem-lo.patch >From 614fedc2b359f123dfdf4e31eee30e7ce47e1bd2 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Sat, 7 Mar 2015 18:39:52 -0500 Subject: [PATCH] build: ruby: Patch executables to set necessary gem load path. * guix/build/ruby-build-system.scm (gem-directory): New procedure. (install): Deduplicate gem directory code. (patch-executables): New procedure. (%standard-phases): Add 'patch-executables' phase. --- guix/build/ruby-build-system.scm | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/guix/build/ruby-build-system.scm b/guix/build/ruby-build-system.scm index a143df4..85ad4d7 100644 --- a/guix/build/ruby-build-system.scm +++ b/guix/build/ruby-build-system.scm @@ -32,6 +32,16 @@ ;; ;; Code: +(define (gem-directory inputs) + "Return the gem installation directory for the version of Ruby within +INPUTS." + ;; Leave off the patch version number in the directory name. + (string-append "/lib/ruby/gems" + (match:substring (string-match "ruby-(.*)\\.[0-9]$" + (assoc-ref inputs "ruby")) + 1) + ".0")) + (define (first-matching-file pattern) "Return the first file name that matches PATTERN in the current working directory." @@ -57,12 +67,8 @@ directory." #t)) (define* (install #:key source inputs outputs #:allow-other-keys) - (let* ((ruby-version - (match:substring (string-match "ruby-(.*)\\.[0-9]$" - (assoc-ref inputs "ruby")) - 1)) - (out (assoc-ref outputs "out")) - (gem-home (string-append out "/lib/ruby/gems/" ruby-version ".0"))) + (let* ((out (assoc-ref outputs "out")) + (gem-home (string-append out (gem-directory inputs)))) (setenv "GEM_HOME" gem-home) (mkdir-p gem-home) (zero? (system* "gem" "install" "--local" @@ -70,12 +76,32 @@ directory." ;; Executables should go into /bin, not /lib/ruby/gems. "--bindir" (string-append out "/bin"))))) +(define* (patch-executables #:key inputs outputs #:allow-other-keys) + (let* ((out (assoc-ref outputs "out")) + (gem-dir (gem-directory inputs)) + ;; Ruby code to add all input gems to the load path. + (ruby-snippet + (string-concatenate + (filter-map (match-lambda + ((_ . input) + (let ((path (string-append input gem-dir))) + (and (file-exists? path) + (string-append "Gem.path.unshift '" + path "'\n"))))) + inputs)))) + ;; Insert code snippet before the built gem is loaded. + (substitute* (find-files (string-append out "/bin") ".*") + (("(gem '.*', version\n)" gem-load-line) + (string-append ruby-snippet gem-load-line))) + #t)) + (define %standard-phases (modify-phases gnu:%standard-phases (delete configure) (add-after unpack gitify gitify) (replace build build) (replace install install) + (add-after install patch-executables patch-executables) (replace check check))) (define* (ruby-build #:key inputs (phases %standard-phases) -- 2.1.4 --=-=-= Content-Type: text/plain -- David Thompson Web Developer - Free Software Foundation - http://fsf.org GPG Key: 0FF1D807 Support the FSF: https://fsf.org/donate --=-=-=--