Skip to content

Commit 8a22f20

Browse files
committed
Add an option to run a script on certain events
When the `hub.hookscript` git configuration is present, it will be used as a script to run on certain events. For now this feature is considered experimental and only the `postclone` event is defined. Please have a look at the `HOOK SCRIPT` section in the man for details.
1 parent bdc8bb9 commit 8a22f20

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

git-hub

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ issues) to be carried out directly from the command line.
3838
VERSION = "git-hub devel"
3939

4040
import io
41+
import os
4142
import re
4243
import sys
4344
import time
@@ -335,6 +336,25 @@ def editor(help_msg, msg=None):
335336
return msg
336337

337338

339+
# Runs a hook script if one was provided
340+
def run_hookscript(hook, env=None):
341+
if config.hookscript is None:
342+
return
343+
if env is None:
344+
env = dict()
345+
env['hook'] = hook
346+
env = dict(('HUB_{}'.format(k.upper()), str(v).lower()
347+
if isinstance(v, bool) else str(v))
348+
for (k, v) in env.items())
349+
debugf('running script "{}" (env={})...', config.hookscript, env)
350+
new_env = dict(os.environ)
351+
new_env.update(env)
352+
status = subprocess.call(config.hookscript, shell=True, env=new_env)
353+
if status != 0:
354+
warnf("The hookscript ({}) failed (status={}), continuing anyway...",
355+
config.hookscript, status)
356+
357+
338358
# git-hub specific configuration container
339359
#
340360
# These variables are described in the manual page.
@@ -366,6 +386,7 @@ class Config:
366386
opts=['--bool']) == "true"
367387
self.triangular = git_config('triangular', "true",
368388
opts=['--bool']) == "true"
389+
self.hookscript = git_config('hookscript')
369390

370391
def sanitize_url(self, name, url):
371392
u = urllib.parse.urlsplit(url)
@@ -845,6 +866,10 @@ class CloneCmd (object):
845866
cls.git_retry_if(args.triangular and forked,
846867
'fetch', ['--', fetchremote],
847868
'Fetching from {} ({})'.format(fetchremote, remote_url))
869+
run_hookscript('postclone', env=dict(
870+
fetchremote=fetchremote,
871+
triangular=triangular,
872+
))
848873

849874
@classmethod
850875
def git_retry_if(cls, condition, cmd, args, progress_msg):

man.rst

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ GLOBAL OPTIONS
4949
\-s, --silent
5050
Be less verbose (can be specified multiple times to get less verbosity)
5151

52-
5352
COMMANDS
5453
========
5554

@@ -161,6 +160,8 @@ __ https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-gith
161160
Any standard **git clone** option can be passed. Not all of them might make
162161
sense when cloning a GitHub repo to be used with this tool though.
163162

163+
This command will run the `hub.hookscript` on some events, please have a look
164+
at `HOOK SCRIPT`_ for more details.
164165

165166
`issue`
166167
This command is used to manage GitHub issues through a set of subcommands.
@@ -472,6 +473,45 @@ __ https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-gith
472473
Alias for `issue close`.
473474

474475

476+
HOOK SCRIPT
477+
===========
478+
479+
If the git configuration `hub.hookscript` is present, it will be used as
480+
a (shell) script to execute on certain events. Some data is passed as
481+
environment variables to the script. All events will set the `HUB_HOOK`
482+
environment variable with the name of the hook being executed.
483+
484+
**NOTE:** This is an experimental feature, so it is only enabled for one event
485+
only so far.
486+
487+
Available hooks (events):
488+
489+
`postclone`
490+
Executed after a `clone` command was done succesfully. The script will be run
491+
with the freshly cloned repository directory as the current working
492+
directory, so the git configuration just done by the `clone` command is
493+
available (for example, `git config hub.forkremote` will get the fork
494+
remote).
495+
496+
The following extra environment variables are defined:
497+
498+
`HUB_TRIANGULAR`
499+
will be set to `true` if the clone was done in triangular mode and to
500+
`false` otherwise.
501+
502+
`HUB_FETCHREMOTE`
503+
will be set to `hub.forkremote` if `triangular` was used and to
504+
`hub.upstreamremote` otherwise.
505+
506+
This hook is useful to set some extra git configuration that should be
507+
enabled only when cloning a repository via this tool. For example, to prune
508+
the `fork` remote when it is updated, but only when *triangular* was used in
509+
the clone you can use:
510+
511+
`git config --global hub.hookscript 'if test "$HUB_HOOK" = postclone &&
512+
$HUB_TRIANGULAR ; then git config remote.fork.prune true; fi'`
513+
514+
475515
CONFIGURATION
476516
=============
477517

@@ -534,6 +574,10 @@ from. These are the git config keys used:
534574
Makes **--triangular** for `clone` if set to "true" (boolean value). See
535575
`clone` documentation for details.
536576

577+
`hub.hookscript`
578+
Script to run on certain events. Please have a look at `HOOK SCRIPT`_ for
579+
more details.
580+
537581
[1] https://developer.github.com/v3/pulls/#get-a-single-pull-request
538582

539583

relnotes/hookscript.feature.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
### A script can now be defined to run on certain events (hooks)
2+
3+
When the `hub.hookscript` git configuration is present, it will be used as
4+
a script to run on certain events. For now this feature is considered
5+
experimental and only the `postclone` event is defined. Please have a look at
6+
the `HOOK SCRIPT` section in the man for details.

0 commit comments

Comments
 (0)