| LEFT | RIGHT |
| 1 # This file is part of Adblock Plus <https://adblockplus.org/>, | 1 # This file is part of Adblock Plus <https://adblockplus.org/>, |
| 2 # Copyright (C) 2006-present eyeo GmbH | 2 # Copyright (C) 2006-present eyeo GmbH |
| 3 # | 3 # |
| 4 # Adblock Plus is free software: you can redistribute it and/or modify | 4 # Adblock Plus is free software: you can redistribute it and/or modify |
| 5 # it under the terms of the GNU General Public License version 3 as | 5 # it under the terms of the GNU General Public License version 3 as |
| 6 # published by the Free Software Foundation. | 6 # published by the Free Software Foundation. |
| 7 # | 7 # |
| 8 # Adblock Plus is distributed in the hope that it will be useful, | 8 # Adblock Plus is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 return self | 62 return self |
| 63 | 63 |
| 64 def __exit__(self, exc_type, exc_value, traceback): | 64 def __exit__(self, exc_type, exc_value, traceback): |
| 65 """Exit the object'c context and delete any temporary data.""" | 65 """Exit the object'c context and delete any temporary data.""" |
| 66 if self._clean_up: | 66 if self._clean_up: |
| 67 shutil.rmtree(self._cwd) | 67 shutil.rmtree(self._cwd) |
| 68 | 68 |
| 69 @classmethod | 69 @classmethod |
| 70 def is_vcs_for_repo(cls, path): | 70 def is_vcs_for_repo(cls, path): |
| 71 """Assert if cls is a suitable VCS for the given (repository-) path.""" | 71 """Assert if cls is a suitable VCS for the given (repository-) path.""" |
| 72 return os.path.exists(os.path.join(path, cls.VCS_REQUIREMENT)) | 72 try: |
| 73 subprocess.check_output([cls.EXECUTABLE, 'status'], cwd=path, |
| 74 stderr=subprocess.STDOUT) |
| 75 return True |
| 76 except subprocess.CalledProcessError: |
| 77 return False |
| 73 | 78 |
| 74 def run_cmd(self, *args, **kwargs): | 79 def run_cmd(self, *args, **kwargs): |
| 75 """Run the vcs with the given commands.""" | 80 """Run the vcs with the given commands.""" |
| 76 cmd = self.BASE_CMD + args | 81 cmd = self.BASE_CMD + args |
| 77 try: | 82 try: |
| 78 return subprocess.check_output( | 83 return subprocess.check_output( |
| 79 cmd, | 84 cmd, |
| 80 cwd=os.path.join(self._cwd), | 85 cwd=os.path.join(self._cwd), |
| 81 stderr=subprocess.STDOUT, | 86 stderr=subprocess.STDOUT, |
| 82 ).decode('utf-8') | 87 ).decode('utf-8') |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 188 |
| 184 if obj is None: | 189 if obj is None: |
| 185 raise Vcs.VcsException('No valid VCS found for ' + location) | 190 raise Vcs.VcsException('No valid VCS found for ' + location) |
| 186 return obj | 191 return obj |
| 187 | 192 |
| 188 | 193 |
| 189 class Mercurial(Vcs): | 194 class Mercurial(Vcs): |
| 190 """Mercurial specialization of VCS.""" | 195 """Mercurial specialization of VCS.""" |
| 191 | 196 |
| 192 EXECUTABLE = 'hg' | 197 EXECUTABLE = 'hg' |
| 193 VCS_REQUIREMENT = '.hg' | |
| 194 BASE_CMD = (EXECUTABLE, '--config', 'defaults.log=', '--config', | 198 BASE_CMD = (EXECUTABLE, '--config', 'defaults.log=', '--config', |
| 195 'defaults.pull=', '--config', 'defaults.diff=') | 199 'defaults.pull=', '--config', 'defaults.diff=') |
| 196 UPDATE_LOCAL_HISTORY = 'pull' | 200 UPDATE_LOCAL_HISTORY = 'pull' |
| 197 LOG_TEMLATE = ('\\{"hash":"{node|short}","author":"{author|person}",' | 201 LOG_TEMLATE = ('\\{"hash":"{node|short}","author":"{author|person}",' |
| 198 '"date":"{date|rfc822date}","message":"{desc|strip|' | 202 '"date":"{date|rfc822date}","message":"{desc|strip|' |
| 199 'firstline}"}\n') | 203 'firstline}"}\n') |
| 200 DEFAULT_NEW_REVISION = 'master' | 204 DEFAULT_NEW_REVISION = 'master' |
| 201 | 205 |
| 202 REVISION_URL = 'https://hg.adblockplus.org/{repository}/rev/{revision}' | 206 REVISION_URL = 'https://hg.adblockplus.org/{repository}/rev/{revision}' |
| 203 | 207 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 def repo_is_clean(self): | 256 def repo_is_clean(self): |
| 253 """Check whether the current repository is clean.""" | 257 """Check whether the current repository is clean.""" |
| 254 buff = self.run_cmd('status') | 258 buff = self.run_cmd('status') |
| 255 return len(buff) == 0 | 259 return len(buff) == 0 |
| 256 | 260 |
| 257 | 261 |
| 258 class Git(Vcs): | 262 class Git(Vcs): |
| 259 """Git specialization of Vcs.""" | 263 """Git specialization of Vcs.""" |
| 260 | 264 |
| 261 EXECUTABLE = 'git' | 265 EXECUTABLE = 'git' |
| 262 VCS_REQUIREMENT = '.git' | |
| 263 BASE_CMD = (EXECUTABLE,) | 266 BASE_CMD = (EXECUTABLE,) |
| 264 UPDATE_LOCAL_HISTORY = 'fetch' | 267 UPDATE_LOCAL_HISTORY = 'fetch' |
| 265 LOG_TEMLATE = '{"hash":"%h","author":"%an","date":"%aD","message":"%s"}' | 268 LOG_TEMLATE = '{"hash":"%h","author":"%an","date":"%aD","message":"%s"}' |
| 266 DEFAULT_NEW_REVISION = 'origin/master' | 269 DEFAULT_NEW_REVISION = 'origin/master' |
| 267 | 270 |
| 268 REVISION_URL = ('https://www.github.com/adblockplus/{repository}/commit/' | 271 REVISION_URL = ('https://www.github.com/adblockplus/{repository}/commit/' |
| 269 '{revision}') | 272 '{revision}') |
| 270 | 273 |
| 271 def __init__(self, *args): | 274 def __init__(self, *args): |
| 272 """Construct a Git object and specify Mercurial as the mirror class.""" | 275 """Construct a Git object and specify Mercurial as the mirror class.""" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 self.run_cmd('checkout', '.') | 318 self.run_cmd('checkout', '.') |
| 316 | 319 |
| 317 def repo_is_clean(self): | 320 def repo_is_clean(self): |
| 318 """Check whether the current repository is clean.""" | 321 """Check whether the current repository is clean.""" |
| 319 # unstaged changes | 322 # unstaged changes |
| 320 no_uncommited = len(self.run_cmd('diff-index', 'HEAD', '--')) == 0 | 323 no_uncommited = len(self.run_cmd('diff-index', 'HEAD', '--')) == 0 |
| 321 # untracked changes | 324 # untracked changes |
| 322 no_untracked = len(self.run_cmd('ls-files', '-o', '-d', | 325 no_untracked = len(self.run_cmd('ls-files', '-o', '-d', |
| 323 '--exclude-standard')) == 0 | 326 '--exclude-standard')) == 0 |
| 324 return no_uncommited and no_untracked | 327 return no_uncommited and no_untracked |
| LEFT | RIGHT |