unofficial mirror of bug-guix@gnu.org 
 help / color / mirror / code / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: Nikita Karetnikov <nikita@karetnikov.org>
Cc: bug-guix@gnu.org
Subject: Re: Toward 0.2
Date: Tue, 26 Feb 2013 20:14:52 +0100	[thread overview]
Message-ID: <87wqtu3n0z.fsf@gnu.org> (raw)
In-Reply-To: <87hakzwdzu.fsf@karetnikov.org> (Nikita Karetnikov's message of "Tue, 26 Feb 2013 05:43:35 -0500")

Nikita Karetnikov <nikita@karetnikov.org> skribis:

> ice-9/boot-9.scm:106:20: In procedure #<procedure 913a8c0 at ice-9/boot-9.scm:97:6 (thrown-k . args)>:
> ice-9/boot-9.scm:106:20: In procedure module-lookup: Unbound variable: memoize

As Mark noted, that’s because of a circular dependency.

> (define-module (wrap-program)
>   #:use-module (guix packages)
>   #:use-module (guix store)
>   #:use-module (srfi srfi-26)
>   #:export (store-location
>             wrap-program))
>
> (define (store-location package output rest)
>   "Return a PACKAGE-related location."
>   (string-append (package-output (open-connection) package output)
>                  rest))

There’s a problem here: this is “host” code, whereas we want code to run
in the builder–i.e., a procedure in (guix build utils).

Remember that (guix build ...) modules must not use Guix modules other
than (guix build ...).  This is a convention to distinguish between code
for the “builder stratum”, and code for the “host stratum”.

> (define (wrap-program program prefix? variable var-dir)
>   "Copy PROGRAM to .PROGRAM-real and make PROGRAM a wrapper."

So here PROGRAM would be a file name (not necessarily absolute).

>   (let* ((bin-location (store-location program "out"
>                                        (string-append "/bin"))) ; not safe
>          (program-name (package-name program))
>          (old (string-append bin-location "/" program-name))
>          (new (string-append bin-location "/." program-name "-real"))
>          (tmp (string-append bin-location "/." program-name "-tmp")))

You just need to keep ‘old’ and ‘new’ (the installation of the wrapper
doesn’t need to be atomic.)

>     (define (change-variable)
>       ;; Prepend VAR-DIR to VARIABLE or return VAR-DIR.
>       (if prefix?
>           (string-append var-dir ":$" variable)
>           var-dir))

This should add a colon before $VARIABLE if and only if VARIABLE is
non-empty, like this:

  export VARIABLE=xxx:${VARIABLE:+:}$VARIABLE

>     (copy-file old new)

Just ‘rename-file’.

>     (call-with-output-file
>         tmp
>       (cut format <> "#!/bin/sh~%export ~a=\"~a\"~%exec ./~a \"$@\"~%"
>            variable (change-variable) (basename new)))

Use (which "bash") instead of /bin/sh.  Avoid ‘cut’ because it’s not
helpful here.

Also it’s better to use the absolute file name for ‘exec’, so just
replace (basename new) by (canonicalize-path new).

>     (chmod tmp #o755)

OK.

However, this only allows for prefix, and of one variable only.  I was
instead suggesting this API:

    (define* (wrap-program file #:rest variables)
       ...)

  Where each rest argument has a form like this:

    ("PATH" ":" prefix ("/nix/.../foo/bin" "/nix/.../bar/bin"))

  Instead of ‘prefix’, users could ask for ‘prefix’ (prepend to the search
  path) or ‘=’ (set the search path to exactly that value.)

Examples:

  (wrap-program "wget" '(("PATH" ":" prefix ("/nix/.../gawk/bin"))))
  =>
  #!/.../sh
  export PATH=/nix/.../gawk/bin:${PATH:+:}$PATH
  exec /.../bin/.wget-real


  (wrap-program "wget" '(("PATH" ":" = ("/nix/.../gawk/bin"))
                         ("CERT_PATH" ":" suffix '("/nix/.../share/certs"))))
  =>
  #!/.../sh
  export PATH=/nix/.../gawk/bin
  export CERT_PATH=$CERT_PATH${CERT_PATH:+:}:/nix/.../share/certs
  exec /.../bin/.wget-real

Perhaps the separator string could be optional.

WDYT?

Let me know if this is unclear.

Thanks,
Ludo’.

  parent reply	other threads:[~2013-02-26 19:15 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-17 15:10 Toward 0.2 Ludovic Courtès
2013-02-18  1:58 ` Nikita Karetnikov
2013-02-18 10:26   ` Ludovic Courtès
2013-02-20  0:39     ` Nikita Karetnikov
2013-02-20 11:28       ` Ludovic Courtès
2013-02-21 17:36         ` Nikita Karetnikov
2013-02-22 14:31           ` Ludovic Courtès
2013-02-26 10:43             ` Nikita Karetnikov
2013-02-26 16:51               ` Mark H Weaver
2013-02-26 19:14               ` Ludovic Courtès [this message]
2013-02-28 20:53                 ` Nikita Karetnikov
2013-03-01  9:15                   ` Ludovic Courtès
2013-03-01 15:01                     ` Nikita Karetnikov
2013-03-01 17:28                       ` Ludovic Courtès
2013-03-02 20:17                         ` Nikita Karetnikov
2013-03-02 21:30                           ` Ludovic Courtès
2013-03-03 12:52                             ` [PATCH] utils: Add 'wrap-program'. (was: Toward 0.2) Nikita Karetnikov
2013-03-03 21:29                               ` [PATCH] utils: Add 'wrap-program' Ludovic Courtès
2013-03-03 23:11                                 ` Nikita Karetnikov
2013-03-04 10:08                                   ` Ludovic Courtès
2013-02-20  9:00 ` Toward 0.2 Andreas Enge
2013-04-15 21:59 ` Ludovic Courtès
2013-04-29 21:32   ` Ludovic Courtès
2013-05-11 20:41   ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wqtu3n0z.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=bug-guix@gnu.org \
    --cc=nikita@karetnikov.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).