Subject: Re: bug#37679: Local git configuration interferes with testsuite

From: Ludovic Courtès <[email-masked]>
Date: Fri, 17 Apr 2020 10:46:04 +0200

Hi Gábor,

Gábor Boskovits <[email-masked]> skribis:

> +AM_TESTS_ENVIRONMENT = 				\
> +  abs_top_srcdir="$(abs_top_srcdir)" 		\
> +  GUILE_AUTO_COMPILE=0				\
> +  GIT_CONFIG_NOSYSTEM=1				\
> +  GIT_ATTR_NOSYSTEM=1				\
> +  HOME="$(abs_top_srcdir)/tests/fake-home"	\
> +  XDG_CONFIG_HOME="$(abs_top_srcdir)/tests/fake-xgd-config-home"

As discussed on IRC yesterday (?), we can arrange to move these
variables directly in (guix tests git), which is the only place where
‘git’ is invoked.  That way, it can’t possibly interfere with other uses
of HOME, etc.

WDYT of something like the patch below?

Thanks,
Ludo’.

diff --git a/guix/tests/git.scm b/guix/tests/git.scm
index 21573ac14e..54d306fbba 100644
--- a/guix/tests/git.scm
+++ b/guix/tests/git.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2019 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2019, 2020 Ludovic Courtès <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -30,6 +30,23 @@
 (define git-command
   (make-parameter "git"))
 
+(define (call-with-environment-variables variables thunk)
+  (let ((environment (environ)))
+    (dynamic-wind
+      (lambda ()
+        (for-each (match-lambda
+                    ((variable value)
+                     (setenv variable value)))
+                  variables))
+      thunk
+      (lambda ()
+        (environ environment)))))
+
+(define-syntax-rule (with-environment-variables variables exp ...)
+  "Evaluate EXP with the given environment VARIABLES set."
+  (call-with-environment-variables variables
+                                   (lambda () exp ...)))
+
 (define (populate-git-repository directory directives)
   "Initialize a new Git checkout and repository in DIRECTORY and apply
 DIRECTIVES.  Each element of DIRECTIVES is an sexp like:
@@ -41,8 +58,21 @@ Return DIRECTORY on success."
   ;; Note: As of version 0.2.0, Guile-Git lacks the necessary bindings to do
   ;; all this, so resort to the "git" command.
   (define (git command . args)
-    (apply invoke (git-command) "-C" directory
-           command args))
+    ;; Make sure Git doesn't rely on the user's config.
+    (call-with-temporary-directory
+     (lambda (home)
+       (call-with-output-file (string-append home "/.gitconfig")
+         (lambda (port)
+           (display "[user]
+  email = [email-masked]\n  name = Charlie Guix\n"
+                    port)))
+
+       (with-environment-variables
+        `(("GIT_CONFIG_NOSYSTEM" "1")
+          ("GIT_ATTR_NOSYSTEM" "1")
+          ("HOME" ,home))
+        (apply invoke (git-command) "-C" directory
+               command args)))))
 
   (mkdir-p directory)
   (git "init")
@@ -59,7 +89,7 @@ Return DIRECTORY on success."
              (display (if (string? contents)
                           contents
                           (with-repository directory repository
-                            (contents repository)))
+                                           (contents repository)))
                       port)))
          (git "add" file)
          (loop rest)))