diff mbox series

[bug#69780,3/4] git authenticate: Install pre-push and post-checkout hooks.

Message ID 6a556beb2566aa401d5064049e136ff2a7669b63.1710351278.git.ludo@gnu.org
State New
Headers show
Series Simplify 'guix git authenticate' usage | expand

Commit Message

Ludovic Courtès March 13, 2024, 5:42 p.m. UTC
* guix/scripts/git/authenticate.scm (install-hooks): New procedure.
(guix-git-authenticate): Use it.
* doc/guix.texi (Invoking guix git authenticate): Document it.

Change-Id: I4464a33193186e85b476a12740e54412bd58429c
---
 doc/guix.texi                     |  5 ++++
 guix/scripts/git/authenticate.scm | 43 ++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 1 deletion(-)

Comments

Tomas Volf March 16, 2024, 9:09 p.m. UTC | #1
On 2024-03-13 18:42:21 +0100, Ludovic Courtès wrote:
> * guix/scripts/git/authenticate.scm (install-hooks): New procedure.
> (guix-git-authenticate): Use it.
> * doc/guix.texi (Invoking guix git authenticate): Document it.
>
> Change-Id: I4464a33193186e85b476a12740e54412bd58429c
> ---
>  doc/guix.texi                     |  5 ++++
>  guix/scripts/git/authenticate.scm | 43 ++++++++++++++++++++++++++++++-
>  2 files changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index ac0766b98c..b1672803c0 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -7624,6 +7624,11 @@ Invoking guix git authenticate
>  guix git authenticate [@var{options}@dots{}]
>  @end example
>
> +The first run also attempts to install pre-push and post-checkout hooks,
> +such that @command{guix git authenticate} is invoked as soon as you run
> +@command{git push}, @command{git checkout}, and related commands; it
> +does not overwrite preexisting hooks though.
> +
>  The options below allow you to fine-tune the process.
>
>  @table @code
> diff --git a/guix/scripts/git/authenticate.scm b/guix/scripts/git/authenticate.scm
> index 36e1aa6228..13e1de3099 100644
> --- a/guix/scripts/git/authenticate.scm
> +++ b/guix/scripts/git/authenticate.scm
> @@ -129,6 +129,46 @@ (define* (record-configuration repository
>    (info (G_ "introduction and keyring configuration recorded in '~a'~%")
>          config-file))
>
> +(define (install-hooks repository)
> +  "Attempt to install in REPOSITORY pre-push and update hooks that invoke
> +'guix git authenticate'.  Bail out if one of these already exists."
> +  (define directory
> +    (repository-directory repository))
> +
> +  (define pre-push-hook
> +    (in-vicinity directory "hooks/pre-push"))
> +
> +  (define post-checkout-hook
> +    (in-vicinity directory "hooks/post-checkout"))

I think these will not work with worktrees.

> +
> +  (if (or (file-exists? pre-push-hook)
> +          (file-exists? post-checkout-hook))
> +      (begin
> +        (warning (G_ "not overriding pre-existing hooks '~a' and '~a'~%")
> +                 pre-push-hook post-checkout-hook)
> +        (display-hint (G_ "Consider running @command{guix git authenticate}
> +from your pre-push and update hooks so your repository is automatically
> +authenticated before you push or receive updates.")))
> +      (begin
> +        (call-with-output-file pre-push-hook
> +          (lambda (port)
> +            (format port "#!/bin/sh
> +set -e
> +while read local_ref local_oid remote_ref remote_oid
> +do
> +  guix git authenticate --end=\"$local_ref\"

Am I right in believing that the --end does solve #69541?  Shame it (--end) is
not documented in the --help.

> +done\n")
> +            (chmod port #o755)))

What is role of etc/git/pre-push now?  Should it be removed?  Should it be
updated to run this code instead?

> +        (call-with-output-file post-checkout-hook
> +          (lambda (port)
> +            (format port "#!/bin/sh
> +oldrev=\"$1\"
> +newrev=\"$2\"
> +exec guix git authenticate --end=\"$newrev\"\n")
> +            (chmod port #o755)))
> +        (info (G_ "installed hooks '~a' and '~a'~%")
> +              pre-push-hook post-checkout-hook))))
> +
>  (define (show-stats stats)
>    "Display STATS, an alist containing commit signing stats as returned by
>  'authenticate-repository'."
> @@ -250,7 +290,8 @@ (define (guix-git-authenticate . args)
>         (unless (configured? repository)
>           (record-configuration repository
>                                 #:commit commit #:signer signer
> -                               #:keyring-reference keyring))
> +                               #:keyring-reference keyring)
> +         (install-hooks repository))
>
>         (when (and show-stats? (not (null? stats)))
>           (show-stats stats))))))
> --
> 2.41.0
>
>
>
>

Have a nice day,
Tomas Volf

--
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
Ludovic Courtès March 19, 2024, 2:02 p.m. UTC | #2
Tomas Volf <~@wolfsden.cz> skribis:

> On 2024-03-13 18:42:21 +0100, Ludovic Courtès wrote:
>> * guix/scripts/git/authenticate.scm (install-hooks): New procedure.
>> (guix-git-authenticate): Use it.
>> * doc/guix.texi (Invoking guix git authenticate): Document it.
>>
>> Change-Id: I4464a33193186e85b476a12740e54412bd58429c

[...]

>> +  (define directory
>> +    (repository-directory repository))
>> +
>> +  (define pre-push-hook
>> +    (in-vicinity directory "hooks/pre-push"))
>> +
>> +  (define post-checkout-hook
>> +    (in-vicinity directory "hooks/post-checkout"))
>
> I think these will not work with worktrees.

Right.  I’m not sure Guile-Git can help here.

>> +while read local_ref local_oid remote_ref remote_oid
>> +do
>> +  guix git authenticate --end=\"$local_ref\"
>
> Am I right in believing that the --end does solve #69541?  Shame it (--end) is
> not documented in the --help.

Indeed, I’ll add it.

>> +done\n")
>> +            (chmod port #o755)))
>
> What is role of etc/git/pre-push now?  Should it be removed?  Should it be
> updated to run this code instead?

We could discuss it, but this is orthogonal.  The changes here are meant
for broad usage of ‘guix git authenticate’, not (or not just) within
Guix.

Ludo’.
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index ac0766b98c..b1672803c0 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -7624,6 +7624,11 @@  Invoking guix git authenticate
 guix git authenticate [@var{options}@dots{}]
 @end example
 
+The first run also attempts to install pre-push and post-checkout hooks,
+such that @command{guix git authenticate} is invoked as soon as you run
+@command{git push}, @command{git checkout}, and related commands; it
+does not overwrite preexisting hooks though.
+
 The options below allow you to fine-tune the process.
 
 @table @code
diff --git a/guix/scripts/git/authenticate.scm b/guix/scripts/git/authenticate.scm
index 36e1aa6228..13e1de3099 100644
--- a/guix/scripts/git/authenticate.scm
+++ b/guix/scripts/git/authenticate.scm
@@ -129,6 +129,46 @@  (define* (record-configuration repository
   (info (G_ "introduction and keyring configuration recorded in '~a'~%")
         config-file))
 
+(define (install-hooks repository)
+  "Attempt to install in REPOSITORY pre-push and update hooks that invoke
+'guix git authenticate'.  Bail out if one of these already exists."
+  (define directory
+    (repository-directory repository))
+
+  (define pre-push-hook
+    (in-vicinity directory "hooks/pre-push"))
+
+  (define post-checkout-hook
+    (in-vicinity directory "hooks/post-checkout"))
+
+  (if (or (file-exists? pre-push-hook)
+          (file-exists? post-checkout-hook))
+      (begin
+        (warning (G_ "not overriding pre-existing hooks '~a' and '~a'~%")
+                 pre-push-hook post-checkout-hook)
+        (display-hint (G_ "Consider running @command{guix git authenticate}
+from your pre-push and update hooks so your repository is automatically
+authenticated before you push or receive updates.")))
+      (begin
+        (call-with-output-file pre-push-hook
+          (lambda (port)
+            (format port "#!/bin/sh
+set -e
+while read local_ref local_oid remote_ref remote_oid
+do
+  guix git authenticate --end=\"$local_ref\"
+done\n")
+            (chmod port #o755)))
+        (call-with-output-file post-checkout-hook
+          (lambda (port)
+            (format port "#!/bin/sh
+oldrev=\"$1\"
+newrev=\"$2\"
+exec guix git authenticate --end=\"$newrev\"\n")
+            (chmod port #o755)))
+        (info (G_ "installed hooks '~a' and '~a'~%")
+              pre-push-hook post-checkout-hook))))
+
 (define (show-stats stats)
   "Display STATS, an alist containing commit signing stats as returned by
 'authenticate-repository'."
@@ -250,7 +290,8 @@  (define (guix-git-authenticate . args)
        (unless (configured? repository)
          (record-configuration repository
                                #:commit commit #:signer signer
-                               #:keyring-reference keyring))
+                               #:keyring-reference keyring)
+         (install-hooks repository))
 
        (when (and show-stats? (not (null? stats)))
          (show-stats stats))))))