diff options
Diffstat (limited to 'project.py')
| -rw-r--r-- | project.py | 75 |
1 files changed, 68 insertions, 7 deletions
| @@ -23,6 +23,7 @@ import shutil | |||
| 23 | import stat | 23 | import stat |
| 24 | import subprocess | 24 | import subprocess |
| 25 | import sys | 25 | import sys |
| 26 | import tarfile | ||
| 26 | import tempfile | 27 | import tempfile |
| 27 | import time | 28 | import time |
| 28 | 29 | ||
| @@ -82,7 +83,7 @@ def _ProjectHooks(): | |||
| 82 | """ | 83 | """ |
| 83 | global _project_hook_list | 84 | global _project_hook_list |
| 84 | if _project_hook_list is None: | 85 | if _project_hook_list is None: |
| 85 | d = os.path.abspath(os.path.dirname(__file__)) | 86 | d = os.path.realpath(os.path.abspath(os.path.dirname(__file__))) |
| 86 | d = os.path.join(d , 'hooks') | 87 | d = os.path.join(d , 'hooks') |
| 87 | _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)] | 88 | _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)] |
| 88 | return _project_hook_list | 89 | return _project_hook_list |
| @@ -986,15 +987,62 @@ class Project(object): | |||
| 986 | 987 | ||
| 987 | ## Sync ## | 988 | ## Sync ## |
| 988 | 989 | ||
| 990 | def _ExtractArchive(self, tarpath, path=None): | ||
| 991 | """Extract the given tar on its current location | ||
| 992 | |||
| 993 | Args: | ||
| 994 | - tarpath: The path to the actual tar file | ||
| 995 | |||
| 996 | """ | ||
| 997 | try: | ||
| 998 | with tarfile.open(tarpath, 'r') as tar: | ||
| 999 | tar.extractall(path=path) | ||
| 1000 | return True | ||
| 1001 | except (IOError, tarfile.TarError) as e: | ||
| 1002 | print("error: Cannot extract archive %s: " | ||
| 1003 | "%s" % (tarpath, str(e)), file=sys.stderr) | ||
| 1004 | return False | ||
| 1005 | |||
| 989 | def Sync_NetworkHalf(self, | 1006 | def Sync_NetworkHalf(self, |
| 990 | quiet=False, | 1007 | quiet=False, |
| 991 | is_new=None, | 1008 | is_new=None, |
| 992 | current_branch_only=False, | 1009 | current_branch_only=False, |
| 993 | clone_bundle=True, | 1010 | clone_bundle=True, |
| 994 | no_tags=False): | 1011 | no_tags=False, |
| 1012 | archive=False): | ||
| 995 | """Perform only the network IO portion of the sync process. | 1013 | """Perform only the network IO portion of the sync process. |
| 996 | Local working directory/branch state is not affected. | 1014 | Local working directory/branch state is not affected. |
| 997 | """ | 1015 | """ |
| 1016 | if archive and not isinstance(self, MetaProject): | ||
| 1017 | if self.remote.url.startswith(('http://', 'https://')): | ||
| 1018 | print("error: %s: Cannot fetch archives from http/https " | ||
| 1019 | "remotes." % self.name, file=sys.stderr) | ||
| 1020 | return False | ||
| 1021 | |||
| 1022 | name = self.relpath.replace('\\', '/') | ||
| 1023 | name = name.replace('/', '_') | ||
| 1024 | tarpath = '%s.tar' % name | ||
| 1025 | topdir = self.manifest.topdir | ||
| 1026 | |||
| 1027 | try: | ||
| 1028 | self._FetchArchive(tarpath, cwd=topdir) | ||
| 1029 | except GitError as e: | ||
| 1030 | print('error: %s' % str(e), file=sys.stderr) | ||
| 1031 | return False | ||
| 1032 | |||
| 1033 | # From now on, we only need absolute tarpath | ||
| 1034 | tarpath = os.path.join(topdir, tarpath) | ||
| 1035 | |||
| 1036 | if not self._ExtractArchive(tarpath, path=topdir): | ||
| 1037 | return False | ||
| 1038 | try: | ||
| 1039 | os.remove(tarpath) | ||
| 1040 | except OSError as e: | ||
| 1041 | print("warn: Cannot remove archive %s: " | ||
| 1042 | "%s" % (tarpath, str(e)), file=sys.stderr) | ||
| 1043 | self._CopyFiles() | ||
| 1044 | return True | ||
| 1045 | |||
| 998 | if is_new is None: | 1046 | if is_new is None: |
| 999 | is_new = not self.Exists | 1047 | is_new = not self.Exists |
| 1000 | if is_new: | 1048 | if is_new: |
| @@ -1169,7 +1217,7 @@ class Project(object): | |||
| 1169 | last_mine = None | 1217 | last_mine = None |
| 1170 | cnt_mine = 0 | 1218 | cnt_mine = 0 |
| 1171 | for commit in local_changes: | 1219 | for commit in local_changes: |
| 1172 | commit_id, committer_email = commit.split(' ', 1) | 1220 | commit_id, committer_email = commit.decode('utf-8').split(' ', 1) |
| 1173 | if committer_email == self.UserEmail: | 1221 | if committer_email == self.UserEmail: |
| 1174 | last_mine = commit_id | 1222 | last_mine = commit_id |
| 1175 | cnt_mine += 1 | 1223 | cnt_mine += 1 |
| @@ -1580,6 +1628,19 @@ class Project(object): | |||
| 1580 | 1628 | ||
| 1581 | ## Direct Git Commands ## | 1629 | ## Direct Git Commands ## |
| 1582 | 1630 | ||
| 1631 | def _FetchArchive(self, tarpath, cwd=None): | ||
| 1632 | cmd = ['archive', '-v', '-o', tarpath] | ||
| 1633 | cmd.append('--remote=%s' % self.remote.url) | ||
| 1634 | cmd.append('--prefix=%s/' % self.relpath) | ||
| 1635 | cmd.append(self.revisionExpr) | ||
| 1636 | |||
| 1637 | command = GitCommand(self, cmd, cwd=cwd, | ||
| 1638 | capture_stdout=True, | ||
| 1639 | capture_stderr=True) | ||
| 1640 | |||
| 1641 | if command.Wait() != 0: | ||
| 1642 | raise GitError('git archive %s: %s' % (self.name, command.stderr)) | ||
| 1643 | |||
| 1583 | def _RemoteFetch(self, name=None, | 1644 | def _RemoteFetch(self, name=None, |
| 1584 | current_branch_only=False, | 1645 | current_branch_only=False, |
| 1585 | initial=False, | 1646 | initial=False, |
| @@ -1847,11 +1908,11 @@ class Project(object): | |||
| 1847 | cookiefile = line[len(prefix):] | 1908 | cookiefile = line[len(prefix):] |
| 1848 | break | 1909 | break |
| 1849 | if p.wait(): | 1910 | if p.wait(): |
| 1850 | line = iter(p.stderr).next() | 1911 | err_msg = p.stderr.read() |
| 1851 | if ' -print_config' in line: | 1912 | if ' -print_config' in err_msg: |
| 1852 | pass # Persistent proxy doesn't support -print_config. | 1913 | pass # Persistent proxy doesn't support -print_config. |
| 1853 | else: | 1914 | else: |
| 1854 | print(line + p.stderr.read(), file=sys.stderr) | 1915 | print(err_msg, file=sys.stderr) |
| 1855 | if cookiefile: | 1916 | if cookiefile: |
| 1856 | return cookiefile | 1917 | return cookiefile |
| 1857 | except OSError as e: | 1918 | except OSError as e: |
| @@ -1971,7 +2032,7 @@ class Project(object): | |||
| 1971 | self._InitHooks() | 2032 | self._InitHooks() |
| 1972 | 2033 | ||
| 1973 | def _InitHooks(self): | 2034 | def _InitHooks(self): |
| 1974 | hooks = self._gitdir_path('hooks') | 2035 | hooks = os.path.realpath(self._gitdir_path('hooks')) |
| 1975 | if not os.path.exists(hooks): | 2036 | if not os.path.exists(hooks): |
| 1976 | os.makedirs(hooks) | 2037 | os.makedirs(hooks) |
| 1977 | for stock_hook in _ProjectHooks(): | 2038 | for stock_hook in _ProjectHooks(): |
