Chromium Code Reviews| Index: git_cache.py |
| diff --git a/git_cache.py b/git_cache.py |
| index 52e42c59274781f580491428b67afa4d6bf66280..aeb3105dd3a4296ed76bf4b83e26d10196770c25 100755 |
| --- a/git_cache.py |
| +++ b/git_cache.py |
| @@ -10,6 +10,7 @@ import errno |
| import logging |
| import optparse |
| import os |
| +import re |
| import tempfile |
| import time |
| import subprocess |
| @@ -151,6 +152,10 @@ class Mirror(object): |
| self.mirror_path = os.path.join(self.GetCachePath(), self.basedir) |
| self.print = print_func or print |
| + @classmethod |
| + def FromPath(cls, path): |
|
Ryan Tseng
2014/05/13 21:05:28
This looks like dead code, whats this for?
szager1
2014/05/13 21:12:38
It's actually new code, along with CacheDirToUrl()
|
| + return cls(cls.CacheDirToUrl(path)) |
| + |
| @staticmethod |
| def UrlToCacheDir(url): |
| """Convert a git url to a normalized form for the cache dir path.""" |
| @@ -161,6 +166,12 @@ class Mirror(object): |
| return norm_url.replace('-', '--').replace('/', '-').lower() |
| @staticmethod |
| + def CacheDirToUrl(path): |
| + """Convert a cache dir path to its corresponding url.""" |
| + netpath = re.sub(r'\b-\b', '/', os.path.basename(path)).replace('--', '-') |
| + return 'https://%s' % netpath |
| + |
| + @staticmethod |
| def FindExecutable(executable): |
| """This mimics the "which" utility.""" |
| path_folders = os.environ.get('PATH').split(os.pathsep) |
| @@ -346,12 +357,42 @@ class Mirror(object): |
| gsutil.call('cp', tmp_zipfile, dest_name) |
| os.remove(tmp_zipfile) |
| + |
| + @staticmethod |
| + def BreakLocks(path): |
| + did_unlock = False |
| + lf = Lockfile(path) |
| + if lf.break_lock(): |
| + did_unlock = True |
| + # Look for lock files that might have been left behind by an interrupted |
| + # git process. |
| + for git_lock_file in ('config',): |
|
Ryan Tseng
2014/05/13 21:05:28
Also "index"
szager1
2014/05/13 21:12:38
That one is debatable, I think. A left-over index
Ryan Tseng
2014/05/13 21:17:45
Fair enough. I've see that a couple of times, but
|
| + lf = os.path.join(path, '%s.lock' % git_lock_file) |
| + if os.path.exists(lf): |
| + os.remove(lf) |
| + did_unlock = True |
| + return did_unlock |
| + |
| def unlock(self): |
| - lf = Lockfile(self.mirror_path) |
| - config_lock = os.path.join(self.mirror_path, 'config.lock') |
| - if os.path.exists(config_lock): |
| - os.remove(config_lock) |
| - lf.break_lock() |
| + return self.BreakLocks(self.mirror_path) |
| + |
| + @classmethod |
| + def UnlockAll(cls): |
| + cachepath = cls.GetCachePath() |
| + dirlist = os.listdir(cachepath) |
| + repo_dirs = set([os.path.join(cachepath, path) for path in dirlist |
| + if os.path.isdir(os.path.join(cachepath, path))]) |
| + for dirent in dirlist: |
| + if (dirent.endswith('.lock') and |
| + os.path.isfile(os.path.join(cachepath, dirent))): |
| + repo_dirs.add(os.path.join(cachepath, dirent[:-5])) |
| + |
| + unlocked_repos = [] |
| + for repo_dir in repo_dirs: |
| + if cls.BreakLocks(repo_dir): |
| + unlocked_repos.append(repo_dir) |
| + |
| + return unlocked_repos |
| @subcommand.usage('[url of repo to check for caching]') |
| def CMDexists(parser, args): |
| @@ -427,54 +468,26 @@ def CMDunlock(parser, args): |
| if len(args) > 1 or (len(args) == 0 and not options.all): |
| parser.error('git cache unlock takes exactly one repo url, or --all') |
| - repo_dirs = [] |
| - if not options.all: |
| - url = args[0] |
| - repo_dirs.append(Mirror(url).mirror_path) |
| - else: |
| + if not options.force: |
| cachepath = Mirror.GetCachePath() |
| - repo_dirs = [os.path.join(cachepath, path) |
| + lockfiles = [os.path.join(cachepath, path) |
| for path in os.listdir(cachepath) |
| - if os.path.isdir(os.path.join(cachepath, path))] |
| - repo_dirs.extend([os.path.join(cachepath, |
| - lockfile.replace('.lock', '')) |
| - for lockfile in os.listdir(cachepath) |
| - if os.path.isfile(os.path.join(cachepath, |
| - lockfile)) |
| - and lockfile.endswith('.lock') |
| - and os.path.join(cachepath, lockfile) |
| - not in repo_dirs]) |
| - lockfiles = [repo_dir + '.lock' for repo_dir in repo_dirs |
| - if os.path.exists(repo_dir + '.lock')] |
| - |
| - if not options.force: |
| + if path.endswith('.lock') and os.path.isfile(path)] |
| parser.error('git cache unlock requires -f|--force to do anything. ' |
| 'Refusing to unlock the following repo caches: ' |
| ', '.join(lockfiles)) |
| unlocked_repos = [] |
| - untouched_repos = [] |
| - for repo_dir in repo_dirs: |
| - lf = Lockfile(repo_dir) |
| - config_lock = os.path.join(repo_dir, 'config.lock') |
| - unlocked = False |
| - if os.path.exists(config_lock): |
| - os.remove(config_lock) |
| - unlocked = True |
| - if lf.break_lock(): |
| - unlocked = True |
| - |
| - if unlocked: |
| - unlocked_repos.append(repo_dir) |
| - else: |
| - untouched_repos.append(repo_dir) |
| + if options.all: |
| + unlocked_repos.extend(Mirror.UnlockAll()) |
| + else: |
| + m = Mirror(args[0]) |
| + if m.unlock(): |
| + unlocked_repos.append(m.mirror_path) |
| if unlocked_repos: |
| logging.info('Broke locks on these caches:\n %s' % '\n '.join( |
| unlocked_repos)) |
| - if untouched_repos: |
| - logging.debug('Did not touch these caches:\n %s' % '\n '.join( |
| - untouched_repos)) |
| class OptionParser(optparse.OptionParser): |