guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] R build system and CRAN importer (updated)


From: Ricardo Wurmus
Subject: Re: [PATCH] R build system and CRAN importer (updated)
Date: Mon, 24 Aug 2015 16:24:38 +0200

Hi David,

> Apologies if the mail client I'm using butchers the formatting... my
> Emacs mail setup isn't working quite right now so I'm using something
> else.  I hope you can still read my feedback well enough.

that’s okay.  Thank you for taking the time to review this patch set!

> +(define string->license
> +  (match-lambda
> +   ("AGPL-3" 'agpl3)
> +   ("Artistic-2.0" 'artistic2.0)
> +   ("Apache License 2.0" 'asl2.0)
> +   ("BSD_2_clause" 'bsd-2)
> +   ("BSD_3_clause" 'bsd-3)
> +   ("GPL-2" 'gpl2)
> +   ("GPL-3" 'GPL3)
> +   ("LGPL-2" 'lgpl2.0)
> +   ("LGPL-2.1" 'lgpl2.1)
> +   ("LGPL-3" 'lgpl3)
> +   ("MIT" 'x11)
> +   ((x) (string->license x))
> +   ((lst ...) `(list ,@(map string->license lst)))
> +   (_ #f)))
>
> With the addition of the Ruby gem importer, I have factorized
> string->license into (guix import utils).  Once this importer and the
> gem importer have reached master, would you like to merge this
> procedure with the factorized one?

I’m not sure this mapping is the same for CRAN as it is for others.  For
example, ‘string->license’ for the CPAN importer uses very different
strings.

> +(define (maybe-inputs package-inputs)
> +  "Given a list of PACKAGE-INPUTS, tries to generate the 'inputs' field of a
> +package definition."
> +  (match package-inputs
> +    (()
> +     '())
> +    ((package-inputs ...)
> +     `((inputs (,'quasiquote ,(format-inputs package-inputs)))))))
>
> Should these be propagated inputs?

Actually, yes, but only when the list consists of R packages.  I’ll
change it such that the field name can be customised.

> +  (sxml-match-let*
> +   (((xhtml:html
> +      ,head
> +      (xhtml:body
> +       (xhtml:h2 ,name-and-synopsis)
> +       (xhtml:p ,description)
> +       ,summary
> +       (xhtml:h4 "Downloads:") ,downloads
> +       . ,rest))
> +     (cadr sxml)))
>
> Can we avoid this cadr call and use 'match' instead?

The only reason for the ‘cadr’ is that the SXML returned by ‘cran-fetch’
is wrapped in ‘(*TOP* ...)’.  I changed the match expression in
‘sxml-match-let*’ such that ‘(*TOP* ...)’ is explicitly matched.  I
agree that this is clearer than using ‘cadr’.

> +   (let* ((name       (match:prefix (string-match ": " name-and-synopsis)))
> +          (synopsis   (match:suffix (string-match ": " name-and-synopsis)))
> +          (version    (nodes->text (table-datum summary "Version:")))
> +          (license    ((compose string->license nodes->text)
> +                       (table-datum summary "License:")))
> +          (home-page  (nodes->text ((sxpath '((xhtml:a 1)))
> +                                    (table-datum summary "URL:"))))
> +          (source-url (string-append "mirror://cran/"
> +                                     ;; Remove double dots, because we want 
> an
> +                                     ;; absolute path.
> +                                     (regexp-substitute/global
> +                                      #f "\\.\\./"
> +                                      (string-join
> +                                       ((sxpath '((xhtml:a 1) @ href *text*))
> +                                        (table-datum downloads "
> Package source: ")))
>
> Line is too long.

Oops.  Fixed.

> +                                      'pre 'post)))
> +          (tarball    (with-store store (download-to-store store 
> source-url)))
> +          (sysdepends (map match:substring
> +                           (list-matches
> +                            "[^ ]+"
> +                            ;; Strip off comma and parenthetical
> +                            ;; expressions.
> +                            (regexp-substitute/global
> +                             #f "(,|\\([^\\)]+\\))"
> +                             (nodes->text (table-datum summary
> "SystemRequirements:"))
>
> Line is too long.

Fixed.

> +                             'pre 'post))))
> +          (imports    (map guix-name
> +                           ((sxpath '(// xhtml:a *text*))
> +                            (table-datum summary "Imports:")))))
> +     `(package
> +        (name ,(guix-name name))
> +        (version ,version)
> +        (source (origin
> +                  (method url-fetch)
> +                  (uri (string-append ,@(factorize-uri source-url version)))
>
> Food for thought: For Ruby, I decided that rather than repeating the
> same 'string-append' form all over the place, I would have a procedure
> called 'rubygems-uri' in (guix build-system ruby) that accepts a
> 'name' and 'version' argument and returns the correct URI.  If the
> source tarballs are all hosted on CRAN, I think this would be a nice
> thing to add.  It can be done later, though.

Good idea!

> +(define (generate-site-path inputs)
> +  (string-join (map (lambda (input)
> +                      (string-append (cdr input) "/site-library"))
> +                    ;; Restrict to inputs beginning with "r-".
> +                    (filter (lambda (input)
> +                              (string-prefix? "r-" (car input)))
> +                            inputs))
>
> Use 'match-lambda' instead of car/cdr above.

Fixed.  I’m guilty of not using ‘match-lambda’ often enough :)

> +               ":"))
> +
> +(define* (check #:key test-target inputs outputs tests? #:allow-other-keys)
> +  "Run the test suite of a given R package."
> +  (let* ((libdir    (string-append (assoc-ref outputs "out") 
> "/site-library/"))
> +         (pkg-name  (car (scandir libdir (negate (cut member <> '("."
> ".."))))))
>
> Ludo prefers that we use 'match' instead of car/cdring.  A comment
> here would help me understand why the package name needs to be
> determined this way.

I think here ‘car’ is okay.  ‘scandir’ returns a list of matching file
names and I only expect one anyway, so I take the first with ‘car’.
‘first’ would also be okay here.

I’ll add a comment to explain why this is required.  The reason is that
R package names are case-sensitive and cannot be derived from the Guix
package name.  The R build system has no way to know the original name
of the R package, but the exact name is required as an argument to
‘tools::testInstalledPackage’, which runs the tests for a package given
its name and the path to the “library” (a location for a collection of R
packages) containing it.

In the case of Guix, there is only one R package in any collection (=
“library”), so we can just take the name of the only directory in the
collection path to figure out the original name of the R package.

> +        (begin
> +          (setenv "R_LIBS_SITE" site-path)
> +          (pipe-to-r (string-append "tools::testInstalledPackage(\""
> pkg-name "\", "
> +                                    "lib.loc = \"" libdir "\")")
> +                     (list "--no-save" "--slave")))
>
> Nitpick: Use a quoted list: '("--no-save" "--slave")

Fixed.

Thanks again!  I’ll send a new patch once I’ve written a couple of tests
for all this.

Cheers,
Ricardo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]