| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -35,6 +35,9 @@ except NameError:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  class WinErr(Exception):
 | 
					 | 
					 | 
					 | 
					  class WinErr(Exception):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pass
 | 
					 | 
					 | 
					 | 
					    pass
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					class LockError(Exception):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  pass
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class ClobberNeeded(Exception):
 | 
					 | 
					 | 
					 | 
					class ClobberNeeded(Exception):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  pass
 | 
					 | 
					 | 
					 | 
					  pass
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -74,11 +77,122 @@ def exponential_backoff_retry(fn, excs=(Exception,), name=None, count=10,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      sleep_time *= 2
 | 
					 | 
					 | 
					 | 
					      sleep_time *= 2
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					class Lockfile(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  """Class to represent a cross-platform process-specific lockfile."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def __init__(self, path, timeout=0):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.path = os.path.abspath(path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.timeout = timeout
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.lockfile = self.path + ".lock"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pid = os.getpid()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _read_pid(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Read the pid stored in the lockfile.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    Note: This method is potentially racy. By the time it returns the lockfile
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    may have been unlocked, removed, or stolen by some other process.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    try:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      with open(self.lockfile, 'r') as f:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        pid = int(f.readline().strip())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    except (IOError, ValueError):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      pid = None
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return pid
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _make_lockfile(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Safely creates a lockfile containing the current pid."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    fd = os.open(self.lockfile, open_flags, 0o644)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    f = os.fdopen(fd, 'w')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    print(self.pid, file=f)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    f.close()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _remove_lockfile(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Delete the lockfile. Complains (implicitly) if it doesn't exist.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    See gclient_utils.py:rmtree docstring for more explanation on the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    windows case.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if sys.platform == 'win32':
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      lockfile = os.path.normcase(self.lockfile)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      def delete():
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        exitcode = subprocess.call(['cmd.exe', '/c',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                    'del', '/f', '/q', lockfile])
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if exitcode != 0:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          raise LockError('Failed to remove lock: %s' % (lockfile,))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      exponential_backoff_retry(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          delete,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          excs=(LockError,),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          name='del [%s]' % (lockfile,))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    else:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      os.remove(self.lockfile)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def lock(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Acquire the lock.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    This will block with a deadline of self.timeout seconds.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    elapsed = 0
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    while True:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      try:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self._make_lockfile()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      except OSError as e:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if elapsed < self.timeout:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          sleep_time = max(10, min(3, self.timeout - elapsed))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          logging.info('Could not create git cache lockfile; '
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                       'will retry after sleep(%d).', sleep_time);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          elapsed += sleep_time
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          time.sleep(sleep_time)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          continue
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if e.errno == errno.EEXIST:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          raise LockError("%s is already locked" % self.path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        else:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          raise LockError("Failed to create %s (err %s)" % (self.path, e.errno))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def unlock(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Release the lock."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    try:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if not self.is_locked():
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        raise LockError("%s is not locked" % self.path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if not self.i_am_locking():
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        raise LockError("%s is locked, but not by me" % self.path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      self._remove_lockfile()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    except WinErr:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      # Windows is unreliable when it comes to file locking.  YMMV.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      pass
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def break_lock(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Remove the lock, even if it was created by someone else."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    try:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      self._remove_lockfile()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return True
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    except OSError as exc:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if exc.errno == errno.ENOENT:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return False
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      else:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        raise
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def is_locked(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Test if the file is locked by anyone.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    Note: This method is potentially racy. By the time it returns the lockfile
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    may have been unlocked, removed, or stolen by some other process.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return os.path.exists(self.lockfile)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def i_am_locking(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    """Test if the file is locked by this process."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return self.is_locked() and self.pid == self._read_pid()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class Mirror(object):
 | 
					 | 
					 | 
					 | 
					class Mirror(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  git_exe = 'git.bat' if sys.platform.startswith('win') else 'git'
 | 
					 | 
					 | 
					 | 
					  git_exe = 'git.bat' if sys.platform.startswith('win') else 'git'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  gsutil_exe = os.path.join(
 | 
					 | 
					 | 
					 | 
					  gsutil_exe = os.path.join(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    os.path.dirname(os.path.abspath(__file__)), 'gsutil.py')
 | 
					 | 
					 | 
					 | 
					    os.path.dirname(os.path.abspath(__file__)), 'gsutil.py')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  cachepath_lock = threading.Lock()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @staticmethod
 | 
					 | 
					 | 
					 | 
					  @staticmethod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def parse_fetch_spec(spec):
 | 
					 | 
					 | 
					 | 
					  def parse_fetch_spec(spec):
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -140,21 +254,23 @@ class Mirror(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @classmethod
 | 
					 | 
					 | 
					 | 
					  @classmethod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def SetCachePath(cls, cachepath):
 | 
					 | 
					 | 
					 | 
					  def SetCachePath(cls, cachepath):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    setattr(cls, 'cachepath', cachepath)
 | 
					 | 
					 | 
					 | 
					    with cls.cachepath_lock:
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      setattr(cls, 'cachepath', cachepath)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @classmethod
 | 
					 | 
					 | 
					 | 
					  @classmethod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def GetCachePath(cls):
 | 
					 | 
					 | 
					 | 
					  def GetCachePath(cls):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if not hasattr(cls, 'cachepath'):
 | 
					 | 
					 | 
					 | 
					    with cls.cachepath_lock:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      try:
 | 
					 | 
					 | 
					 | 
					      if not hasattr(cls, 'cachepath'):
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        cachepath = subprocess.check_output(
 | 
					 | 
					 | 
					 | 
					        try:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            [cls.git_exe, 'config', '--global', 'cache.cachepath']).strip()
 | 
					 | 
					 | 
					 | 
					          cachepath = subprocess.check_output(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      except subprocess.CalledProcessError:
 | 
					 | 
					 | 
					 | 
					              [cls.git_exe, 'config', '--global', 'cache.cachepath']).strip()
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        cachepath = None
 | 
					 | 
					 | 
					 | 
					        except subprocess.CalledProcessError:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if not cachepath:
 | 
					 | 
					 | 
					 | 
					          cachepath = None
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        raise RuntimeError(
 | 
					 | 
					 | 
					 | 
					        if not cachepath:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            'No global cache.cachepath git configuration found.')
 | 
					 | 
					 | 
					 | 
					          raise RuntimeError(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      setattr(cls, 'cachepath', cachepath)
 | 
					 | 
					 | 
					 | 
					              'No global cache.cachepath git configuration found.')
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return getattr(cls, 'cachepath')
 | 
					 | 
					 | 
					 | 
					        setattr(cls, 'cachepath', cachepath)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return getattr(cls, 'cachepath')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def Rename(self, src, dst):
 | 
					 | 
					 | 
					 | 
					  def Rename(self, src, dst):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # This is somehow racy on Windows.
 | 
					 | 
					 | 
					 | 
					    # This is somehow racy on Windows.
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -371,12 +487,17 @@ class Mirror(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          raise ClobberNeeded()  # Corrupted cache.
 | 
					 | 
					 | 
					 | 
					          raise ClobberNeeded()  # Corrupted cache.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        logging.warn('Fetch of %s failed' % spec)
 | 
					 | 
					 | 
					 | 
					        logging.warn('Fetch of %s failed' % spec)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def populate(self, depth=None, shallow=False, bootstrap=False, verbose=False):
 | 
					 | 
					 | 
					 | 
					  def populate(self, depth=None, shallow=False, bootstrap=False,
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					               verbose=False, ignore_lock=False, lock_timeout=0):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    assert self.GetCachePath()
 | 
					 | 
					 | 
					 | 
					    assert self.GetCachePath()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if shallow and not depth:
 | 
					 | 
					 | 
					 | 
					    if shallow and not depth:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      depth = 10000
 | 
					 | 
					 | 
					 | 
					      depth = 10000
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    gclient_utils.safe_makedirs(self.GetCachePath())
 | 
					 | 
					 | 
					 | 
					    gclient_utils.safe_makedirs(self.GetCachePath())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    lockfile = Lockfile(self.mirror_path, lock_timeout)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if not ignore_lock:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      lockfile.lock()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    tempdir = None
 | 
					 | 
					 | 
					 | 
					    tempdir = None
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    try:
 | 
					 | 
					 | 
					 | 
					    try:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      tempdir = self._ensure_bootstrapped(depth, bootstrap)
 | 
					 | 
					 | 
					 | 
					      tempdir = self._ensure_bootstrapped(depth, bootstrap)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -394,6 +515,8 @@ class Mirror(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if os.path.exists(self.mirror_path):
 | 
					 | 
					 | 
					 | 
					        if os.path.exists(self.mirror_path):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          gclient_utils.rmtree(self.mirror_path)
 | 
					 | 
					 | 
					 | 
					          gclient_utils.rmtree(self.mirror_path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.Rename(tempdir, self.mirror_path)
 | 
					 | 
					 | 
					 | 
					        self.Rename(tempdir, self.mirror_path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if not ignore_lock:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        lockfile.unlock()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def update_bootstrap(self, prune=False):
 | 
					 | 
					 | 
					 | 
					  def update_bootstrap(self, prune=False):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # The files are named <git number>.zip
 | 
					 | 
					 | 
					 | 
					    # The files are named <git number>.zip
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -434,6 +557,45 @@ class Mirror(object):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      except OSError:
 | 
					 | 
					 | 
					 | 
					      except OSError:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        logging.warn('Unable to delete temporary pack file %s' % f)
 | 
					 | 
					 | 
					 | 
					        logging.warn('Unable to delete temporary pack file %s' % f)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  @classmethod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def BreakLocks(cls, 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
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    cls.DeleteTmpPackFiles(path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return did_unlock
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def unlock(self):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return self.BreakLocks(self.mirror_path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  @classmethod
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def UnlockAll(cls):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    cachepath = cls.GetCachePath()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if not cachepath:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    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.startswith('_cache_tmp') or dirent.startswith('tmp'):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        gclient_utils.rm_file_or_tree(os.path.join(cachepath, dirent))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      elif (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):
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -485,6 +647,9 @@ def CMDpopulate(parser, args):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  parser.add_option('--no_bootstrap', '--no-bootstrap',
 | 
					 | 
					 | 
					 | 
					  parser.add_option('--no_bootstrap', '--no-bootstrap',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    action='store_true',
 | 
					 | 
					 | 
					 | 
					                    action='store_true',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    help='Don\'t bootstrap from Google Storage')
 | 
					 | 
					 | 
					 | 
					                    help='Don\'t bootstrap from Google Storage')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  parser.add_option('--ignore_locks', '--ignore-locks',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    action='store_true',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    help='Don\'t try to lock repository')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  options, args = parser.parse_args(args)
 | 
					 | 
					 | 
					 | 
					  options, args = parser.parse_args(args)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if not len(args) == 1:
 | 
					 | 
					 | 
					 | 
					  if not len(args) == 1:
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -496,6 +661,8 @@ def CMDpopulate(parser, args):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'verbose': options.verbose,
 | 
					 | 
					 | 
					 | 
					      'verbose': options.verbose,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'shallow': options.shallow,
 | 
					 | 
					 | 
					 | 
					      'shallow': options.shallow,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      'bootstrap': not options.no_bootstrap,
 | 
					 | 
					 | 
					 | 
					      'bootstrap': not options.no_bootstrap,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      'ignore_lock': options.ignore_locks,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      'lock_timeout': options.timeout,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if options.depth:
 | 
					 | 
					 | 
					 | 
					  if options.depth:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    kwargs['depth'] = options.depth
 | 
					 | 
					 | 
					 | 
					    kwargs['depth'] = options.depth
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -540,7 +707,7 @@ def CMDfetch(parser, args):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if git_dir.startswith(cachepath):
 | 
					 | 
					 | 
					 | 
					  if git_dir.startswith(cachepath):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    mirror = Mirror.FromPath(git_dir)
 | 
					 | 
					 | 
					 | 
					    mirror = Mirror.FromPath(git_dir)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    mirror.populate(
 | 
					 | 
					 | 
					 | 
					    mirror.populate(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bootstrap=not options.no_bootstrap,)
 | 
					 | 
					 | 
					 | 
					        bootstrap=not options.no_bootstrap, lock_timeout=options.timeout)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return 0
 | 
					 | 
					 | 
					 | 
					    return 0
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  for remote in remotes:
 | 
					 | 
					 | 
					 | 
					  for remote in remotes:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    remote_url = subprocess.check_output(
 | 
					 | 
					 | 
					 | 
					    remote_url = subprocess.check_output(
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -550,11 +717,44 @@ def CMDfetch(parser, args):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      mirror.print = lambda *args: None
 | 
					 | 
					 | 
					 | 
					      mirror.print = lambda *args: None
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      print('Updating git cache...')
 | 
					 | 
					 | 
					 | 
					      print('Updating git cache...')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      mirror.populate(
 | 
					 | 
					 | 
					 | 
					      mirror.populate(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bootstrap=not options.no_bootstrap)
 | 
					 | 
					 | 
					 | 
					          bootstrap=not options.no_bootstrap, lock_timeout=options.timeout)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    subprocess.check_call([Mirror.git_exe, 'fetch', remote])
 | 
					 | 
					 | 
					 | 
					    subprocess.check_call([Mirror.git_exe, 'fetch', remote])
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return 0
 | 
					 | 
					 | 
					 | 
					  return 0
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					@subcommand.usage('[url of repo to unlock, or -a|--all]')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					def CMDunlock(parser, args):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  """Unlock one or all repos if their lock files are still around."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  parser.add_option('--force', '-f', action='store_true',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    help='Actually perform the action')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  parser.add_option('--all', '-a', action='store_true',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    help='Unlock all repository caches')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  options, args = parser.parse_args(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')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  if not options.force:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    cachepath = Mirror.GetCachePath()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    lockfiles = [os.path.join(cachepath, path)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                 for path in os.listdir(cachepath)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                 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 = []
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  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))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class OptionParser(optparse.OptionParser):
 | 
					 | 
					 | 
					 | 
					class OptionParser(optparse.OptionParser):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  """Wrapper class for OptionParser to handle global options."""
 | 
					 | 
					 | 
					 | 
					  """Wrapper class for OptionParser to handle global options."""
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -566,6 +766,8 @@ class OptionParser(optparse.OptionParser):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    help='Increase verbosity (can be passed multiple times)')
 | 
					 | 
					 | 
					 | 
					                    help='Increase verbosity (can be passed multiple times)')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.add_option('-q', '--quiet', action='store_true',
 | 
					 | 
					 | 
					 | 
					    self.add_option('-q', '--quiet', action='store_true',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    help='Suppress all extraneous output')
 | 
					 | 
					 | 
					 | 
					                    help='Suppress all extraneous output')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.add_option('--timeout', type='int', default=0,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    help='Timeout for acquiring cache lock, in seconds')
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def parse_args(self, args=None, values=None):
 | 
					 | 
					 | 
					 | 
					  def parse_args(self, args=None, values=None):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    options, args = optparse.OptionParser.parse_args(self, args, values)
 | 
					 | 
					 | 
					 | 
					    options, args = optparse.OptionParser.parse_args(self, args, values)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |