build: ruby: Add support for tarball and directory sources.
Previously, the Ruby build system only knew how to work with gem archives, which made it difficult to build unreleased gems from a Git repository or released gems in tarball form. * gnu/build/ruby-build-system.scm (gnu:unpack, gem-archive?): New procedures. (unpack): Use GNU build system unpack phase for non-gem sources. (build): Rebuild the gemspec iff the source is a gem archive. * guix.texi ("ruby-build-system"): Mention that tarballs and directories are acceptable.
This commit is contained in:
parent
27cc9f2544
commit
5dc876231b
|
@ -2506,12 +2506,13 @@ This variable is exported by @code{(guix build-system ruby)}. It
|
||||||
implements the RubyGems build procedure used by Ruby packages, which
|
implements the RubyGems build procedure used by Ruby packages, which
|
||||||
involves running @code{gem build} followed by @code{gem install}.
|
involves running @code{gem build} followed by @code{gem install}.
|
||||||
|
|
||||||
The @code{source} field of a package that uses this build system is
|
The @code{source} field of a package that uses this build system
|
||||||
expected to reference a gem archive instead of a traditional tarball,
|
typically references a gem archive, since this is the format that Ruby
|
||||||
since this is the format that all Ruby developers use when releasing
|
developers use when releasing their software. The build system unpacks
|
||||||
their software. The build system unpacks the gem archive, potentially
|
the gem archive, potentially patches the source, runs the test suite,
|
||||||
patches the source, runs the test suite, repackages the gem, and
|
repackages the gem, and installs it. Additionally, directories and
|
||||||
installs it.
|
tarballs may be referenced to allow building unreleased gems from Git or
|
||||||
|
a traditional source release tarball.
|
||||||
|
|
||||||
Which Ruby package is used can be specified with the @code{#:ruby}
|
Which Ruby package is used can be specified with the @code{#:ruby}
|
||||||
parameter. A list of additional flags to be passed to the @command{gem}
|
parameter. A list of additional flags to be passed to the @command{gem}
|
||||||
|
|
|
@ -41,53 +41,63 @@ directory."
|
||||||
((file-name . _) file-name)
|
((file-name . _) file-name)
|
||||||
(() (error "No files matching pattern: " pattern))))
|
(() (error "No files matching pattern: " pattern))))
|
||||||
|
|
||||||
|
(define gnu:unpack (assq-ref gnu:%standard-phases 'unpack))
|
||||||
|
|
||||||
|
(define (gem-archive? file-name)
|
||||||
|
(string-match "^.*\\.gem$" file-name))
|
||||||
|
|
||||||
(define* (unpack #:key source #:allow-other-keys)
|
(define* (unpack #:key source #:allow-other-keys)
|
||||||
"Unpack the gem SOURCE and enter the resulting directory."
|
"Unpack the gem SOURCE and enter the resulting directory."
|
||||||
(and (zero? (system* "gem" "unpack" source))
|
(if (gem-archive? source)
|
||||||
;; The unpacked gem directory is named the same as the archive, sans
|
(and (zero? (system* "gem" "unpack" source))
|
||||||
;; the ".gem" extension. It is renamed to simply "gem" in an effort to
|
;; The unpacked gem directory is named the same as the archive,
|
||||||
;; keep file names shorter to avoid UNIX-domain socket file names and
|
;; sans the ".gem" extension. It is renamed to simply "gem" in an
|
||||||
;; shebangs that exceed the system's fixed maximum length when running
|
;; effort to keep file names shorter to avoid UNIX-domain socket
|
||||||
;; test suites.
|
;; file names and shebangs that exceed the system's fixed maximum
|
||||||
(let ((dir (match:substring (string-match "^(.*)\\.gem$"
|
;; length when running test suites.
|
||||||
(basename source))
|
(let ((dir (match:substring (string-match "^(.*)\\.gem$"
|
||||||
1)))
|
(basename source))
|
||||||
(rename-file dir "gem")
|
1)))
|
||||||
(chdir "gem")
|
(rename-file dir "gem")
|
||||||
#t)))
|
(chdir "gem")
|
||||||
|
#t))
|
||||||
|
;; Use GNU unpack strategy for things that aren't gem archives.
|
||||||
|
(gnu:unpack #:source source)))
|
||||||
|
|
||||||
(define* (build #:key source #:allow-other-keys)
|
(define* (build #:key source #:allow-other-keys)
|
||||||
"Build a new gem using the gemspec from the SOURCE gem."
|
"Build a new gem using the gemspec from the SOURCE gem."
|
||||||
|
(define (first-gemspec)
|
||||||
|
(first-matching-file "\\.gemspec$"))
|
||||||
|
|
||||||
;; Remove the original gemspec, if present, and replace it with a new one.
|
;; Remove the original gemspec, if present, and replace it with a new one.
|
||||||
;; This avoids issues with upstream gemspecs requiring tools such as git to
|
;; This avoids issues with upstream gemspecs requiring tools such as git to
|
||||||
;; generate the files list.
|
;; generate the files list.
|
||||||
(let ((gemspec (or (false-if-exception
|
(when (gem-archive? source)
|
||||||
(first-matching-file "\\.gemspec$"))
|
(let ((gemspec (or (false-if-exception (first-gemspec))
|
||||||
;; Make new gemspec if one wasn't shipped.
|
;; Make new gemspec if one wasn't shipped.
|
||||||
".gemspec")))
|
".gemspec")))
|
||||||
|
|
||||||
(when (file-exists? gemspec) (delete-file gemspec))
|
(when (file-exists? gemspec) (delete-file gemspec))
|
||||||
|
|
||||||
;; Extract gemspec from source gem.
|
;; Extract gemspec from source gem.
|
||||||
(let ((pipe (open-pipe* OPEN_READ "gem" "spec" "--ruby" source)))
|
(let ((pipe (open-pipe* OPEN_READ "gem" "spec" "--ruby" source)))
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
(const #t)
|
(const #t)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(call-with-output-file gemspec
|
(call-with-output-file gemspec
|
||||||
(lambda (out)
|
(lambda (out)
|
||||||
;; 'gem spec' writes to stdout, but 'gem build' only reads
|
;; 'gem spec' writes to stdout, but 'gem build' only reads
|
||||||
;; gemspecs from a file, so we redirect the output to a file.
|
;; gemspecs from a file, so we redirect the output to a file.
|
||||||
(while (not (eof-object? (peek-char pipe)))
|
(while (not (eof-object? (peek-char pipe)))
|
||||||
(write-char (read-char pipe) out))))
|
(write-char (read-char pipe) out))))
|
||||||
#t)
|
#t)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(close-pipe pipe))))
|
(close-pipe pipe))))))
|
||||||
|
|
||||||
;; Build a new gem from the current working directory. This also allows any
|
;; Build a new gem from the current working directory. This also allows any
|
||||||
;; dynamic patching done in previous phases to be present in the installed
|
;; dynamic patching done in previous phases to be present in the installed
|
||||||
;; gem.
|
;; gem.
|
||||||
(zero? (system* "gem" "build" gemspec))))
|
(zero? (system* "gem" "build" (first-gemspec))))
|
||||||
|
|
||||||
(define* (check #:key tests? test-target #:allow-other-keys)
|
(define* (check #:key tests? test-target #:allow-other-keys)
|
||||||
"Run the gem's test suite rake task TEST-TARGET. Skip the tests if TESTS?
|
"Run the gem's test suite rake task TEST-TARGET. Skip the tests if TESTS?
|
||||||
|
|
Loading…
Reference in New Issue