Commit 174766fb authored by szager@chromium.org's avatar szager@chromium.org

Added Mirror.UnlockAll with logic fixes.

BUG=

Review URL: https://codereview.chromium.org/278103002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@270205 0039d316-1c4b-4281-b951-d872f2087c98
parent 359bb643
...@@ -10,6 +10,7 @@ import errno ...@@ -10,6 +10,7 @@ import errno
import logging import logging
import optparse import optparse
import os import os
import re
import tempfile import tempfile
import time import time
import subprocess import subprocess
...@@ -151,6 +152,10 @@ class Mirror(object): ...@@ -151,6 +152,10 @@ class Mirror(object):
self.mirror_path = os.path.join(self.GetCachePath(), self.basedir) self.mirror_path = os.path.join(self.GetCachePath(), self.basedir)
self.print = print_func or print self.print = print_func or print
@classmethod
def FromPath(cls, path):
return cls(cls.CacheDirToUrl(path))
@staticmethod @staticmethod
def UrlToCacheDir(url): def UrlToCacheDir(url):
"""Convert a git url to a normalized form for the cache dir path.""" """Convert a git url to a normalized form for the cache dir path."""
...@@ -160,6 +165,12 @@ class Mirror(object): ...@@ -160,6 +165,12 @@ class Mirror(object):
norm_url = norm_url[:-len('.git')] norm_url = norm_url[:-len('.git')]
return norm_url.replace('-', '--').replace('/', '-').lower() 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 @staticmethod
def FindExecutable(executable): def FindExecutable(executable):
"""This mimics the "which" utility.""" """This mimics the "which" utility."""
...@@ -346,12 +357,41 @@ class Mirror(object): ...@@ -346,12 +357,41 @@ class Mirror(object):
gsutil.call('cp', tmp_zipfile, dest_name) gsutil.call('cp', tmp_zipfile, dest_name)
os.remove(tmp_zipfile) 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.
lf = os.path.join(path, 'config.lock')
if os.path.exists(lf):
os.remove(lf)
did_unlock = True
return did_unlock
def unlock(self): def unlock(self):
lf = Lockfile(self.mirror_path) return self.BreakLocks(self.mirror_path)
config_lock = os.path.join(self.mirror_path, 'config.lock')
if os.path.exists(config_lock): @classmethod
os.remove(config_lock) def UnlockAll(cls):
lf.break_lock() 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]') @subcommand.usage('[url of repo to check for caching]')
def CMDexists(parser, args): def CMDexists(parser, args):
...@@ -427,54 +467,26 @@ def CMDunlock(parser, args): ...@@ -427,54 +467,26 @@ def CMDunlock(parser, args):
if len(args) > 1 or (len(args) == 0 and not options.all): if len(args) > 1 or (len(args) == 0 and not options.all):
parser.error('git cache unlock takes exactly one repo url, or --all') parser.error('git cache unlock takes exactly one repo url, or --all')
repo_dirs = [] if not options.force:
if not options.all:
url = args[0]
repo_dirs.append(Mirror(url).mirror_path)
else:
cachepath = Mirror.GetCachePath() cachepath = Mirror.GetCachePath()
repo_dirs = [os.path.join(cachepath, path) lockfiles = [os.path.join(cachepath, path)
for path in os.listdir(cachepath) for path in os.listdir(cachepath)
if os.path.isdir(os.path.join(cachepath, path))] if path.endswith('.lock') and os.path.isfile(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:
parser.error('git cache unlock requires -f|--force to do anything. ' parser.error('git cache unlock requires -f|--force to do anything. '
'Refusing to unlock the following repo caches: ' 'Refusing to unlock the following repo caches: '
', '.join(lockfiles)) ', '.join(lockfiles))
unlocked_repos = [] unlocked_repos = []
untouched_repos = [] if options.all:
for repo_dir in repo_dirs: unlocked_repos.extend(Mirror.UnlockAll())
lf = Lockfile(repo_dir) else:
config_lock = os.path.join(repo_dir, 'config.lock') m = Mirror(args[0])
unlocked = False if m.unlock():
if os.path.exists(config_lock): unlocked_repos.append(m.mirror_path)
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 unlocked_repos: if unlocked_repos:
logging.info('Broke locks on these caches:\n %s' % '\n '.join( logging.info('Broke locks on these caches:\n %s' % '\n '.join(
unlocked_repos)) unlocked_repos))
if untouched_repos:
logging.debug('Did not touch these caches:\n %s' % '\n '.join(
untouched_repos))
class OptionParser(optparse.OptionParser): class OptionParser(optparse.OptionParser):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment