Prechádzať zdrojové kódy

* Now PreReceiveShellHook configure GIT_DIR environ variable
* Append PostReceiveShellHook

Stéphane Klein 10 rokov pred
rodič
commit
445a5462a6
4 zmenil súbory, kde vykonal 66 pridanie a 3 odobranie
  1. 31 1
      dulwich/hooks.py
  2. 3 1
      dulwich/repo.py
  3. 7 0
      dulwich/server.py
  4. 25 1
      dulwich/tests/test_hooks.py

+ 31 - 1
dulwich/hooks.py

@@ -148,16 +148,46 @@ class PreReceiveShellHook(ShellHook):
     """pre-receive shell hook"""
 
     def __init__(self, controldir):
+        self.controldir = controldir
         filepath = os.path.join(controldir, 'hooks', 'pre-receive')
         ShellHook.__init__(self, 'pre-receive', filepath, 0)
 
     def execute(self, stdin):
         try:
+            env = os.environ.copy()
+            env['GIT_DIR'] = self.controldir
             p = subprocess.Popen(
                 self.filepath,
                 stdin=subprocess.PIPE,
                 stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE
+                stderr=subprocess.PIPE,
+                env=env
+            )
+            self.stdout, self.stderr = p.communicate(stdin)
+            return p.returncode
+        except OSError:  # no file. silent failure.
+            self.stdout = None
+            return 0
+
+
+class PostReceiveShellHook(ShellHook):
+    """post-receive shell hook"""
+
+    def __init__(self, controldir):
+        self.controldir = controldir
+        filepath = os.path.join(controldir, 'hooks', 'post-receive')
+        ShellHook.__init__(self, 'post-receive', filepath, 0)
+
+    def execute(self, stdin):
+        try:
+            env = os.environ.copy()
+            env['GIT_DIR'] = self.controldir
+            p = subprocess.Popen(
+                self.filepath,
+                stdin=subprocess.PIPE,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
+                env=env
             )
             self.stdout, self.stderr = p.communicate(stdin)
             return p.returncode

+ 3 - 1
dulwich/repo.py

@@ -63,7 +63,8 @@ from dulwich.hooks import (
     PreCommitShellHook,
     PostCommitShellHook,
     CommitMsgShellHook,
-    PreReceiveShellHook
+    PreReceiveShellHook,
+    PostReceiveShellHook
     )
 
 from dulwich.refs import (
@@ -676,6 +677,7 @@ class Repo(BaseRepo):
         self.hooks['commit-msg'] = CommitMsgShellHook(self.controldir())
         self.hooks['post-commit'] = PostCommitShellHook(self.controldir())
         self.hooks['pre-receive'] = PreReceiveShellHook(self.controldir())
+        self.hooks['post-receive'] = PostReceiveShellHook(self.controldir())
 
     def controldir(self):
         """Return the path of the control directory."""

+ 7 - 0
dulwich/server.py

@@ -834,6 +834,13 @@ class ReceivePackHandler(Handler):
             # backend can now deal with this refs and read a
             # pack using self.read
             status = self._apply_pack(client_refs)
+            hook = self.repo.hooks.get('post-receive', None)
+            if hook:
+                hook.execute(
+                    stdin='\n'.join([' '.join(i) for i in client_refs])
+                )
+                if hook.stdout:
+                    self.proto.write_sideband(2, hook.stdout)
         else:
             status = [
                 ('unpack', 'ok'),

+ 25 - 1
dulwich/tests/test_hooks.py

@@ -28,7 +28,8 @@ from dulwich.hooks import (
     PreCommitShellHook,
     PostCommitShellHook,
     CommitMsgShellHook,
-    PreReceiveShellHook
+    PreReceiveShellHook,
+    PostReceiveShellHook,
 )
 
 from dulwich.tests import TestCase
@@ -176,3 +177,26 @@ exit 1
 
         self.assertEqual(hook.execute("line1\nline2\nline3\n"), 0)
         self.assertIsNone(hook.stdout)
+
+    def test_hook_post_receive(self):
+        repo_dir = os.path.join(tempfile.mkdtemp())
+        os.makedirs(os.path.join(repo_dir, 'hooks'))
+        self.addCleanup(shutil.rmtree, repo_dir)
+
+        post_receive = os.path.join(repo_dir, 'hooks', 'post-receive')
+        hook = PostReceiveShellHook(repo_dir)
+
+        with open(post_receive, 'wb') as f:
+            f.write("""#!/bin/sh
+
+while read x ; do echo $x ; done
+exit 0
+            """)
+
+        os.chmod(post_receive, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+
+        self.assertEqual(hook.execute("line1\nline2\nline3\n"), 0)
+        self.assertEqual(
+            hook.stdout,
+            "line1\nline2\nline3\n"
+        )