Beispiel #1
0
def Change(change_info, args):
    """Creates/edits a changelist."""
    silent = FilterFlag(args, "--silent")

    # Verify the user is running the change command from a read-write checkout.
    svn_info = SVN.CaptureInfo('.')
    if not svn_info:
        ErrorExit(
            "Current checkout is unversioned.  Please retry with a versioned "
            "directory.")

    if (len(args) == 1):
        filename = args[0]
        f = open(filename, 'rU')
        override_description = f.read()
        f.close()
    else:
        override_description = None

    if change_info.issue and not change_info.NeedsUpload():
        try:
            description = GetIssueDescription(change_info.issue)
        except urllib2.HTTPError, err:
            if err.code == 404:
                # The user deleted the issue in Rietveld, so forget the old issue id.
                description = change_info.description
                change_info.issue = 0
                change_info.Save()
            else:
                ErrorExit("Error getting the description from Rietveld: " +
                          err)
Beispiel #2
0
def GetRepositoryRoot():
    """Returns the top level directory of the current repository.

  The directory is returned as an absolute path.
  """
    global REPOSITORY_ROOT
    if not REPOSITORY_ROOT:
        infos = SVN.CaptureInfo(os.getcwd(), print_error=False)
        cur_dir_repo_root = infos.get("Repository Root")
        if not cur_dir_repo_root:
            raise gclient_utils.Error("gcl run outside of repository")

        REPOSITORY_ROOT = os.getcwd()
        while True:
            parent = os.path.dirname(REPOSITORY_ROOT)
            if (SVN.CaptureInfo(parent,
                                print_error=False).get("Repository Root") !=
                    cur_dir_repo_root):
                break
            REPOSITORY_ROOT = parent
    return REPOSITORY_ROOT
Beispiel #3
0
def GenerateDiff(files, root=None):
    """Returns a string containing the diff for the given file list.

  The files in the list should either be absolute paths or relative to the
  given root. If no root directory is provided, the repository root will be
  used.
  """
    previous_cwd = os.getcwd()
    if root is None:
        os.chdir(GetRepositoryRoot())
    else:
        os.chdir(root)

    diff = []
    for filename in files:
        # TODO(maruel): Use SVN.DiffItem().
        # Use svn info output instead of os.path.isdir because the latter fails
        # when the file is deleted.
        if SVN.CaptureInfo(filename).get('Node Kind') == 'directory':
            continue
        # If the user specified a custom diff command in their svn config file,
        # then it'll be used when we do svn diff, which we don't want to happen
        # since we want the unified diff.  Using --diff-cmd=diff doesn't always
        # work, since they can have another diff executable in their path that
        # gives different line endings.  So we use a bogus temp directory as the
        # config directory, which gets around these problems.
        if sys.platform.startswith("win"):
            parent_dir = tempfile.gettempdir()
        else:
            parent_dir = sys.path[0]  # tempdir is not secure.
        bogus_dir = os.path.join(parent_dir, "temp_svn_config")
        if not os.path.exists(bogus_dir):
            os.mkdir(bogus_dir)
        output = RunShell(["svn", "diff", "--config-dir", bogus_dir, filename])
        if output:
            diff.append(output)
        elif SVN.IsMoved(filename):
            #  svn diff on a mv/cp'd file outputs nothing.
            # We put in an empty Index entry so upload.py knows about them.
            diff.append("\nIndex: %s\n" % filename)
        else:
            # The file is not modified anymore. It should be removed from the set.
            pass
    os.chdir(previous_cwd)
    return "".join(diff)
Beispiel #4
0
def CMDchange(args):
  """Creates or edits a changelist.

  Only scans the current directory and subdirectories."""
  if len(args) == 0:
    # Generate a random changelist name.
    changename = GenerateChangeName()
  elif args[0] == '--force':
    changename = GenerateChangeName()
  else:
    changename = args[0]
  change_info = ChangeInfo.Load(changename, GetRepositoryRoot(), False, True)
  silent = FilterFlag(args, "--silent")

  # Verify the user is running the change command from a read-write checkout.
  svn_info = SVN.CaptureInfo('.')
  if not svn_info:
    ErrorExit("Current checkout is unversioned.  Please retry with a versioned "
              "directory.")

  if len(args) == 2:
    f = open(args[1], 'rU')
    override_description = f.read()
    f.close()
  else:
    override_description = None

  if change_info.issue and not change_info.NeedsUpload():
    try:
      description = GetIssueDescription(change_info.issue)
    except urllib2.HTTPError, err:
      if err.code == 404:
        # The user deleted the issue in Rietveld, so forget the old issue id.
        description = change_info.description
        change_info.issue = 0
        change_info.Save()
      else:
        ErrorExit("Error getting the description from Rietveld: " + err)
Beispiel #5
0
def GetCachedFile(filename, max_age=60 * 60 * 24 * 3, use_root=False):
    """Retrieves a file from the repository and caches it in GetCacheDir() for
  max_age seconds.

  use_root: If False, look up the arborescence for the first match, otherwise go
            directory to the root repository.

  Note: The cache will be inconsistent if the same file is retrieved with both
        use_root=True and use_root=False. Don't be stupid.
  """
    global FILES_CACHE
    if filename not in FILES_CACHE:
        # Don't try to look up twice.
        FILES_CACHE[filename] = None
        # First we check if we have a cached version.
        try:
            cached_file = os.path.join(GetCacheDir(), filename)
        except gclient_utils.Error:
            return None
        if (not os.path.exists(cached_file)
                or os.stat(cached_file).st_mtime > max_age):
            local_dir = os.path.dirname(os.path.abspath(filename))
            local_base = os.path.basename(filename)
            dir_info = SVN.CaptureInfo(".")
            repo_root = dir_info["Repository Root"]
            if use_root:
                url_path = repo_root
            else:
                url_path = dir_info["URL"]
            content = ""
            while True:
                # First, look for a locally modified version of the file if we can.
                r = ""
                if not use_root:
                    local_path = os.path.join(local_dir, local_base)
                    r = SVN.CaptureStatus((local_path, ))
                rc = -1
                if r:
                    status = r[0][0]
                    rc = 0
                if not rc and status[0] in ('A', 'M'):
                    content = ReadFile(local_path)
                    rc = 0
                else:
                    # Look in the repository if we didn't find something local.
                    svn_path = url_path + "/" + filename
                    content, rc = RunShellWithReturnCode(
                        ["svn", "cat", svn_path])

                if not rc:
                    # Exit the loop if the file was found. Override content.
                    break
                # Make sure to mark settings as empty if not found.
                content = ""
                if url_path == repo_root:
                    # Reached the root. Abandoning search.
                    break
                # Go up one level to try again.
                url_path = os.path.dirname(url_path)
                local_dir = os.path.dirname(local_dir)
            # Write a cached version even if there isn't a file, so we don't try to
            # fetch it each time.
            WriteFile(cached_file, content)
        else:
            content = ReadFile(cached_file)
        # Keep the content cached in memory.
        FILES_CACHE[filename] = content
    return FILES_CACHE[filename]
Beispiel #6
0
def GetCachedFile(filename, max_age=60*60*24*3, use_root=False):
  """Retrieves a file from the repository and caches it in GetCacheDir() for
  max_age seconds.

  use_root: If False, look up the arborescence for the first match, otherwise go
            directory to the root repository.

  Note: The cache will be inconsistent if the same file is retrieved with both
        use_root=True and use_root=False. Don't be stupid.
  """
  if filename not in FILES_CACHE:
    # Don't try to look up twice.
    FILES_CACHE[filename] = None
    # First we check if we have a cached version.
    try:
      cached_file = os.path.join(GetCacheDir(), filename)
    except gclient_utils.Error:
      return None
    if (not os.path.exists(cached_file) or
        (time.time() - os.stat(cached_file).st_mtime) > max_age):
      dir_info = SVN.CaptureInfo('.')
      repo_root = dir_info['Repository Root']
      if use_root:
        url_path = repo_root
      else:
        url_path = dir_info['URL']
      while True:
        # Look in the repository at the current level for the file.
        for _ in range(5):
          content = None
          try:
            # Take advantage of the fact that svn won't output to stderr in case
            # of success but will do in case of failure so don't mind putting
            # stderr into content_array.
            content_array = []
            svn_path = url_path + '/' + filename
            args = ['svn', 'cat', svn_path]
            if sys.platform != 'darwin':
              # MacOSX 10.5.2 has a bug with svn 1.4.4 that will trigger the
              # 'Can\'t get username or password' and can be fixed easily.
              # The fix doesn't work if the user upgraded to svn 1.6.x. Bleh.
              # I don't have time to fix their broken stuff.
              args.append('--non-interactive')
            gclient_utils.CheckCallAndFilter(
                args, cwd='.', filter_fn=content_array.append)
            # Exit the loop if the file was found. Override content.
            content = '\n'.join(content_array)
            break
          except gclient_utils.Error:
            if content_array[0].startswith(
                'svn: Can\'t get username or password'):
              ErrorExit('Your svn credentials expired. Please run svn update '
                        'to fix the cached credentials')
            if content_array[0].startswith('svn: Can\'t get password'):
              ErrorExit('If are using a Mac and svn --version shows 1.4.x, '
                  'please hack gcl.py to remove --non-interactive usage, it\'s'
                  'a bug on your installed copy')
            if not content_array[0].startswith('svn: File not found:'):
              # Try again.
              continue
        if content:
          break
        if url_path == repo_root:
          # Reached the root. Abandoning search.
          break
        # Go up one level to try again.
        url_path = os.path.dirname(url_path)
      if content is not None or filename != CODEREVIEW_SETTINGS_FILE:
        # Write a cached version even if there isn't a file, so we don't try to
        # fetch it each time. codereview.settings must always be present so do
        # not cache negative.
        gclient_utils.FileWrite(cached_file, content or '')
    else:
      content = gclient_utils.FileRead(cached_file, 'r')
    # Keep the content cached in memory.
    FILES_CACHE[filename] = content
  return FILES_CACHE[filename]