Subject: [bug#29951] [PATCH] WIP guix: Add wrap-script.

From: Ricardo Wurmus <[email-masked]>
Date: Fri, 05 Jan 2018 09:19:00 +0100

Hi Hartmut,

>> +                                (false-if-exception
>> +                                 (and=> (regexp-exec coding-line-regex (read-line p))
>> +                                        (lambda (m) (match:substring m 0)))))))))
>
> When using emacs, this line can also contain other local variable
> definitions. What about keeping the whole line?

The purpose here was just to retain the coding comment, because it is
interpreted by Python itself to set the file encoding.  Other values are
not used by Python to make any such decisions.

Since these modified files are only generated in a build phase to modify
the *execution* environment (and the unchanged files are available via
“guix build -S”), I think that it is reasonable to assume that users
won’t be interested in editing these files directly, so hints to the
editor don’t need to be preserved.

I find it a little cleaner to keep this coding-line preservation as
restricted as possible, but maybe you are right and it would be safer to
just copy the whole line when the coding regex matches.

>> +        (when interpreter
>> +          (let* ((header (format #f "\
>> +#!~a --no-auto-compile
>> +#!#; ~a
>> +#\\-~s
>> +#\\-~s
>> +"
>> +                                 (which "guile")
>> +                                 (or coding-line "Guix wrapper")
>> +                                 (cons 'begin (map update-env vars))
>> +                                 `(apply execl ,interpreter
>> +                                         (car (command-line))
>> +                                         (command-line))))
>
> Does this take care of proper quoting the string-values?

What string values do you refer to?  We first generate an S-expression
(where we don’t need to take care of escaping things anyway) and then
format it as a string (with “format” and the “~s” format string), and
then we print that S-expression-as-a-string into a file.

I ran this on an actual Python file in the store.  This is the original
file, which I copied to “/tmp/test-python”:

--8<---------------cut here---------------start------------->8---
#!/gnu/store/iyy9w0hcxv4dg9q92d4g023vvz50r5bq-python-3.5.3/bin/python3.5
import sys
from lib2to3.main import main

sys.exit(main("lib2to3.fixes"))
--8<---------------cut here---------------end--------------->8---

This is the code in the REPL:

--8<---------------cut here---------------start------------->8---
,use (guix build utils)
scheme@(guile-user)> (wrap-script "/tmp/test-python"
                                  '("PYTHONPATH" ":" prefix ("/foo/bar:whatever"))
                                  '("FOOBAR" ":" suffix ("/to/me")))
scheme@(guile-user)>
--8<---------------cut here---------------end--------------->8---

This is the result in “/tmp/test-python”:

--8<---------------cut here---------------start------------->8---
#!/home/rekado/.guix-profile/bin/guile --no-auto-compile
#!#; Guix wrapper
#\-(begin (let ((current (getenv "PYTHONPATH"))) (setenv "PYTHONPATH" (if current (string-append "/foo/bar:whatever" ":" current) "/foo/bar:whatever"))) (let ((current (getenv "FOOBAR"))) (setenv "FOOBAR" (if current (string-append current ":" "/to/me") "/to/me"))))
#\-(apply execl "/gnu/store/iyy9w0hcxv4dg9q92d4g023vvz50r5bq-python-3.5.3/bin/python3.5" (car (command-line)) (command-line))
#!/gnu/store/iyy9w0hcxv4dg9q92d4g023vvz50r5bq-python-3.5.3/bin/python3.5
import sys
from lib2to3.main import main

sys.exit(main("lib2to3.fixes"))
--8<---------------cut here---------------end--------------->8---

>
>> +                (call-with-ascii-input-file prog
>
> Does this work if the file contains non-ascii characters, e.g. \xf0
> (assuming "ascii" means 0-127 only)?

“call-with-ascii-input-file” opens the file as a binary, so it reads the
file as a series of bytes.  This seems fine when reading only the
shebang (which is ASCII only) and when trying to match the coding regex
on the second line.

--
Ricardo

GPG: BCA6 89B6 3655 3801 C3C6  2150 197A 5888 235F ACAC
https://elephly.net