Skip to content

Commit

Permalink
Add an option to run a script on certain events
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
llucax committed Feb 12, 2021
1 parent bdc8bb9 commit 8a22f20
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
25 changes: 25 additions & 0 deletions git-hub
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ issues) to be carried out directly from the command line.
VERSION = "git-hub devel"

import io
import os
import re
import sys
import time
Expand Down Expand Up @@ -335,6 +336,25 @@ def editor(help_msg, msg=None):
return msg


# Runs a hook script if one was provided
def run_hookscript(hook, env=None):
if config.hookscript is None:
return
if env is None:
env = dict()
env['hook'] = hook
env = dict(('HUB_{}'.format(k.upper()), str(v).lower()
if isinstance(v, bool) else str(v))
for (k, v) in env.items())
debugf('running script "{}" (env={})...', config.hookscript, env)
new_env = dict(os.environ)
new_env.update(env)
status = subprocess.call(config.hookscript, shell=True, env=new_env)
if status != 0:
warnf("The hookscript ({}) failed (status={}), continuing anyway...",
config.hookscript, status)


# git-hub specific configuration container
#
# These variables are described in the manual page.
Expand Down Expand Up @@ -366,6 +386,7 @@ class Config:
opts=['--bool']) == "true"
self.triangular = git_config('triangular', "true",
opts=['--bool']) == "true"
self.hookscript = git_config('hookscript')

def sanitize_url(self, name, url):
u = urllib.parse.urlsplit(url)
Expand Down Expand Up @@ -845,6 +866,10 @@ class CloneCmd (object):
cls.git_retry_if(args.triangular and forked,
'fetch', ['--', fetchremote],
'Fetching from {} ({})'.format(fetchremote, remote_url))
run_hookscript('postclone', env=dict(
fetchremote=fetchremote,
triangular=triangular,
))

@classmethod
def git_retry_if(cls, condition, cmd, args, progress_msg):
Expand Down
46 changes: 45 additions & 1 deletion man.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ GLOBAL OPTIONS
\-s, --silent
Be less verbose (can be specified multiple times to get less verbosity)


COMMANDS
========

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

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

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


HOOK SCRIPT
===========

If the git configuration `hub.hookscript` is present, it will be used as
a (shell) script to execute on certain events. Some data is passed as
environment variables to the script. All events will set the `HUB_HOOK`
environment variable with the name of the hook being executed.

**NOTE:** This is an experimental feature, so it is only enabled for one event
only so far.

Available hooks (events):

`postclone`
Executed after a `clone` command was done succesfully. The script will be run
with the freshly cloned repository directory as the current working
directory, so the git configuration just done by the `clone` command is
available (for example, `git config hub.forkremote` will get the fork
remote).

The following extra environment variables are defined:

`HUB_TRIANGULAR`
will be set to `true` if the clone was done in triangular mode and to
`false` otherwise.

`HUB_FETCHREMOTE`
will be set to `hub.forkremote` if `triangular` was used and to
`hub.upstreamremote` otherwise.

This hook is useful to set some extra git configuration that should be
enabled only when cloning a repository via this tool. For example, to prune
the `fork` remote when it is updated, but only when *triangular* was used in
the clone you can use:

`git config --global hub.hookscript 'if test "$HUB_HOOK" = postclone &&
$HUB_TRIANGULAR ; then git config remote.fork.prune true; fi'`


CONFIGURATION
=============

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

`hub.hookscript`
Script to run on certain events. Please have a look at `HOOK SCRIPT`_ for
more details.

[1] https://developer.github.com/v3/pulls/#get-a-single-pull-request


Expand Down
6 changes: 6 additions & 0 deletions relnotes/hookscript.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### A script can now be defined to run on certain events (hooks)

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.

0 comments on commit 8a22f20

Please sign in to comment.