import: pypi: Also guess dependencies from *.egg-info/requires.txt.
* guix/import/pypi.scm (guess-requirements): Extract "requires.txt" from the egg-info directory in addition to "requirements.txt"; strip off version constraints; use call-with-temporary-directory.
This commit is contained in:
parent
a3ece51a29
commit
e37f889404
|
@ -3,6 +3,7 @@
|
||||||
;;; Copyright © 2015 Cyril Roelandt <tipecaml@gmail.com>
|
;;; Copyright © 2015 Cyril Roelandt <tipecaml@gmail.com>
|
||||||
;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
|
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
|
||||||
|
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -36,7 +37,8 @@
|
||||||
#:use-module (guix utils)
|
#:use-module (guix utils)
|
||||||
#:use-module ((guix build utils)
|
#:use-module ((guix build utils)
|
||||||
#:select ((package-name->name+version
|
#:select ((package-name->name+version
|
||||||
. hyphen-package-name->name+version)))
|
. hyphen-package-name->name+version)
|
||||||
|
find-files))
|
||||||
#:use-module (guix import utils)
|
#:use-module (guix import utils)
|
||||||
#:use-module ((guix download) #:prefix download:)
|
#:use-module ((guix download) #:prefix download:)
|
||||||
#:use-module (guix import json)
|
#:use-module (guix import json)
|
||||||
|
@ -114,9 +116,9 @@ package definition."
|
||||||
`((propagated-inputs (,'quasiquote ,package-inputs))))))
|
`((propagated-inputs (,'quasiquote ,package-inputs))))))
|
||||||
|
|
||||||
(define (guess-requirements source-url wheel-url tarball)
|
(define (guess-requirements source-url wheel-url tarball)
|
||||||
"Given SOURCE-URL, WHEEL-URL and a TARBALL of the package, return a list of
|
"Given SOURCE-URL, WHEEL-URL and a TARBALL of the package, return a list
|
||||||
the required packages specified in the requirements.txt file. TARBALL will be
|
of the required packages specified in the requirements.txt file. TARBALL will
|
||||||
extracted in the current directory, and will be deleted."
|
be extracted in a temporary directory."
|
||||||
|
|
||||||
(define (tarball-directory url)
|
(define (tarball-directory url)
|
||||||
;; Given the URL of the package's tarball, return the name of the directory
|
;; Given the URL of the package's tarball, return the name of the directory
|
||||||
|
@ -140,8 +142,8 @@ cannot determine package dependencies"))
|
||||||
;; file, remove everything other than the actual name of the required
|
;; file, remove everything other than the actual name of the required
|
||||||
;; package, and return it.
|
;; package, and return it.
|
||||||
(string-take s
|
(string-take s
|
||||||
(or (string-index s #\space)
|
(or (string-index s (lambda (chr) (member chr '(#\space #\> #\= #\<))))
|
||||||
(string-length s))))
|
(string-length s))))
|
||||||
|
|
||||||
(define (comment? line)
|
(define (comment? line)
|
||||||
;; Return #t if the given LINE is a comment, #f otherwise.
|
;; Return #t if the given LINE is a comment, #f otherwise.
|
||||||
|
@ -197,31 +199,37 @@ cannot determine package dependencies"))
|
||||||
(read-wheel-metadata temp))
|
(read-wheel-metadata temp))
|
||||||
#f))))
|
#f))))
|
||||||
|
|
||||||
|
|
||||||
(define (guess-requirements-from-source)
|
(define (guess-requirements-from-source)
|
||||||
;; Return the package's requirements by guessing them from the source.
|
;; Return the package's requirements by guessing them from the source.
|
||||||
(let ((dirname (tarball-directory source-url)))
|
(let ((dirname (tarball-directory source-url)))
|
||||||
(if (string? dirname)
|
(if (string? dirname)
|
||||||
(let* ((req-file (string-append dirname "/requirements.txt"))
|
(call-with-temporary-directory
|
||||||
(exit-code (system* "tar" "xf" tarball req-file)))
|
(lambda (dir)
|
||||||
;; TODO: support more formats.
|
(let* ((pypi-name (string-take dirname (string-rindex dirname #\-)))
|
||||||
(if (zero? exit-code)
|
(req-files (list (string-append dirname "/requirements.txt")
|
||||||
(dynamic-wind
|
(string-append dirname "/" pypi-name ".egg-info"
|
||||||
(const #t)
|
"/requires.txt")))
|
||||||
(lambda ()
|
(exit-codes (map (lambda (file-name)
|
||||||
(read-requirements req-file))
|
(parameterize ((current-error-port (%make-void-port "rw+"))
|
||||||
(lambda ()
|
(current-output-port (%make-void-port "rw+")))
|
||||||
(delete-file req-file)
|
(system* "tar" "xf" tarball "-C" dir file-name)))
|
||||||
(rmdir dirname)))
|
req-files)))
|
||||||
(begin
|
;; Only one of these files needs to exist.
|
||||||
(warning (G_ "'tar xf' failed with exit code ~a\n")
|
(if (any zero? exit-codes)
|
||||||
exit-code)
|
(match (find-files dir)
|
||||||
'())))
|
((file . _)
|
||||||
|
(read-requirements file))
|
||||||
|
(()
|
||||||
|
(warning (G_ "No requirements file found.\n"))))
|
||||||
|
(begin
|
||||||
|
(warning (G_ "Failed to extract requirements files\n"))
|
||||||
|
'())))))
|
||||||
'())))
|
'())))
|
||||||
|
|
||||||
;; First, try to compute the requirements using the wheel, since that is the
|
;; First, try to compute the requirements using the wheel, since that is the
|
||||||
;; most reliable option. If a wheel is not provided for this package, try
|
;; most reliable option. If a wheel is not provided for this package, try
|
||||||
;; getting them by reading the "requirements.txt" file from the source. Note
|
;; getting them by reading either the "requirements.txt" file or the
|
||||||
|
;; "requires.txt" from the egg-info directory from the source tarball. Note
|
||||||
;; that "requirements.txt" is not mandatory, so this is likely to fail.
|
;; that "requirements.txt" is not mandatory, so this is likely to fail.
|
||||||
(or (guess-requirements-from-wheel)
|
(or (guess-requirements-from-wheel)
|
||||||
(guess-requirements-from-source)))
|
(guess-requirements-from-source)))
|
||||||
|
|
Loading…
Reference in New Issue