From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fl7xu-0003RR-Bu for guix-patches@gnu.org; Thu, 02 Aug 2018 03:24:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fl7xq-0008Ib-BK for guix-patches@gnu.org; Thu, 02 Aug 2018 03:24:06 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:33190) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fl7xq-0008IR-5b for guix-patches@gnu.org; Thu, 02 Aug 2018 03:24:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fl7xq-0005wA-0M for guix-patches@gnu.org; Thu, 02 Aug 2018 03:24:02 -0400 Subject: [bug#29951] [PATCH] WIP guix: Add wrap-script. Resent-Message-ID: References: <20180102204434.2716-1-rekado@elephly.net> <69141465-bdd7-4855-c5d0-a3750646273b@crazy-compilers.com> <87o9m84t2n.fsf@elephly.net> <87sh3xcmib.fsf@gmail.com> From: Ricardo Wurmus In-reply-to: <87sh3xcmib.fsf@gmail.com> Date: Thu, 02 Aug 2018 09:23:16 +0200 Message-ID: <87600ts04b.fsf@elephly.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: Chris Marusich Cc: Hartmut Goebel , 29951@debbugs.gnu.org Hi Chris, > Ricardo Wurmus writes: > >> This is the result in =E2=80=9C/tmp/test-python=E2=80=9D: >> >> #!/home/rekado/.guix-profile/bin/guile --no-auto-compile >> #!#; Guix wrapper >> #\-(begin (let ((current (getenv "PYTHONPATH"))) (setenv "PYTHONPATH" (i= f current (string-append "/foo/bar:whatever" ":" current) "/foo/bar:whateve= r"))) (let ((current (getenv "FOOBAR"))) (setenv "FOOBAR" (if current (stri= ng-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")) > > I understand that the part beginning with #! and ending with !# are a > block comment in scheme, so they will be ignored by Guile, and that > "Guix wrapper" shows up after a ;, so it will also be considered a > comment by Guile, but I don't understand why the lines following that > need to begin with #\-. I also don't understand why Guile doesn't > complain about it. Why do the lines begin with #\-? #\- is Guile syntax for the character =E2=80=9C-=E2=80=9D. To ensure that = the target language ignores these lines they must start with =E2=80=9C#=E2=80=9D. In = Guile, however, we cannot just use =E2=80=9C#=E2=80=9D on its own. The =E2=80=9C#= =E2=80=9D in Guile is the start of a reader macro. We don=E2=80=99t really want a reader macro at the beginning of each line, though =E2=80=93 we just want to move on and get to= the expression. So we use =E2=80=9C#\-=E2=80=9D, which evaluates to the character =E2=80=9C= -=E2=80=9D. It is valid in Scheme to write code that evaluates to something and then ignore that value. Here=E2=80=99s an example: 10 23 #\a #\b 5 (display "hello") Guile would evaluate the numbers and characters one after the other, and none of them would have any effect on the final expression that displays =E2=80=9Chello=E2=80=9D. In the wrapper we do the same kind of thing. This line: #\-(begin (let =E2=80=A6) =E2=80=A6) is really just two Scheme values: a single arbitrary character and the S-expression that we care about. We only care about the side-effects of evaluating the S-expression. A language that uses =E2=80=9C#=E2=80=9D to mark comments, on the other han= d, would simply ignore the whole line. The result is that we can use Guile to set environment variables and then hand over execution to the target language interpreter, which would run in the new environment. The advantage of this approach is: we don=E2=80=99t have to rename wrapped scripts any more (=E2=80=9C.foo-real=E2=80=9D), which makes for prettier us= age messages (=E2=80=9CUsage: foo -v=E2=80=9D instead of =E2=80=9CUsage: .foo-real -v=E2= =80=9D) and avoids problems when an application checks its own name to determine what actions it should take. -- Ricardo