diff --git a/law/contrib/git/__init__.py b/law/contrib/git/__init__.py index 76367fb2..539095ea 100644 --- a/law/contrib/git/__init__.py +++ b/law/contrib/git/__init__.py @@ -8,6 +8,7 @@ import os +import threading import subprocess from abc import abstractmethod @@ -43,6 +44,7 @@ def __init__(self, *args, **kwargs): super(BundleGitRepository, self).__init__(*args, **kwargs) self._checksum = None + self._checksum_lock = threading.RLock() @abstractmethod def get_repo_path(self): @@ -53,16 +55,23 @@ def checksum(self): if self.custom_checksum != NO_STR: return self.custom_checksum - if self._checksum is None: - cmd = [rel_path(__file__, "scripts", "repository_checksum.sh"), self.get_repo_path()] - cmd = quote_cmd(cmd) - - code, out, _ = interruptable_popen(cmd, shell=True, executable="/bin/bash", - stdout=subprocess.PIPE) - if code != 0: - raise Exception("repository checksum calculation failed") - - self._checksum = out.strip() + with self._checksum_lock: + if self._checksum is None: + cmd = quote_cmd([ + rel_path(__file__, "scripts", "repository_checksum.sh"), + self.get_repo_path(), + ]) + + code, out, _ = interruptable_popen( + cmd, + shell=True, + executable="/bin/bash", + stdout=subprocess.PIPE, + ) + if code != 0: + raise Exception("repository checksum calculation failed") + + self._checksum = out.strip() return self._checksum diff --git a/law/contrib/mercurial/__init__.py b/law/contrib/mercurial/__init__.py index ca18e6ea..2baa1455 100644 --- a/law/contrib/mercurial/__init__.py +++ b/law/contrib/mercurial/__init__.py @@ -8,6 +8,7 @@ import os +import threading import subprocess from abc import abstractmethod @@ -18,7 +19,7 @@ from law.target.local import LocalFileTarget from law.parameter import NO_STR, CSVParameter from law.decorator import log -from law.util import rel_path, interruptable_popen +from law.util import rel_path, interruptable_popen, quote_cmd class BundleMercurialRepository(Task): @@ -43,6 +44,7 @@ def __init__(self, *args, **kwargs): super(BundleMercurialRepository, self).__init__(*args, **kwargs) self._checksum = None + self._checksum_lock = threading.RLock(()) @abstractmethod def get_repo_path(self): @@ -53,15 +55,23 @@ def checksum(self): if self.custom_checksum != NO_STR: return self.custom_checksum - if self._checksum is None: - checksum_script = rel_path(__file__, "scripts", "repository_checksum.sh") - cmd = [checksum_script, self.get_repo_path()] - - code, out, _ = interruptable_popen(cmd, stdout=subprocess.PIPE) - if code != 0: - raise Exception("repository checksum calculation failed") - - self._checksum = out.strip() + with self._checksum_lock: + if self._checksum is None: + cmd = quote_cmd([ + rel_path(__file__, "scripts", "repository_checksum.sh"), + self.get_repo_path(), + ]) + + code, out, _ = interruptable_popen( + cmd, + shell=True, + executable="/bin/bash", + stdout=subprocess.PIPE, + ) + if code != 0: + raise Exception("repository checksum calculation failed") + + self._checksum = out.strip() return self._checksum