Пример #1
0
def IsInternalRepoCheckout(root):
    """Returns whether root houses an internal 'repo' checkout."""
    manifest_dir = os.path.join(root, '.repo', 'manifests')
    manifest_url = git.RunGit(manifest_dir,
                              ['config', 'remote.origin.url']).output.strip()
    return (os.path.splitext(
        os.path.basename(manifest_url))[0] == os.path.splitext(
            os.path.basename(constants.MANIFEST_INT_URL))[0])
Пример #2
0
def ListRemoteBranches():
    """Get a list of all remote branches for the chromite repository.

  Returns:
    List of branch names as strings.
  """
    ret = git.RunGit(constants.CHROMITE_DIR, ['branch', '-lr'])
    return [l.strip() for l in ret.output.splitlines()]
Пример #3
0
def _DoWeHaveLocalCommits(stable_branch, tracking_branch, cwd):
    """Returns true if there are local commits."""
    current_branch = git.GetCurrentBranch(cwd)

    if current_branch != stable_branch:
        return False
    output = git.RunGit(cwd,
                        ['rev-parse', 'HEAD', tracking_branch]).output.split()
    return output[0] != output[1]
 def Checkout(self, branch=None):
     """Function used to check out to another GitBranch."""
     if not branch:
         branch = self.branch_name
     if branch == self.tracking_branch or self.Exists(branch):
         git.RunGit(self.cwd, ['checkout', '-f', branch], quiet=True)
     else:
         repo = repo_util.Repository.MustFind(self.cwd)
         repo.StartBranch(branch, projects=['.'], cwd=self.cwd)
Пример #5
0
def CommitIfChanged(ebuild_dir, message):
  """If there are changes to ebuild or Manifest, commit them.

  Args:
    ebuild_dir: the path to the directory of ebuild in the chroot
    message: commit message
  """
  # Check if anything changed compared to the previous version.
  modifications = git.RunGit(
      ebuild_dir, ['status', '--porcelain', '-uno'],
      capture_output=True,
      print_cmd=True).output
  if not modifications:
    logging.info('AFDO info for the ebuilds did not change. '
                 'Nothing to commit')
    return

  git.RunGit(ebuild_dir, ['commit', '-a', '-m', message], print_cmd=True)
Пример #6
0
  def _PushConfig(self, workdir, testjob, dryrun, current_time):
    """Pushes the tryjob config to Git as a file.

    Args:
      workdir: see Submit()
      testjob: see Submit()
      dryrun: see Submit()
      current_time: the current time as a string represention of the time since
        unix epoch.
    """
    push_branch = manifest_version.PUSH_BRANCH

    remote_branch = None
    if testjob:
      remote_branch = git.RemoteRef('origin', 'refs/remotes/origin/test')
    git.CreatePushBranch(push_branch, workdir, sync=False,
                         remote_push_branch=remote_branch)
    file_name = '%s.%s' % (self.user, current_time)
    user_dir = os.path.join(workdir, self.user)
    if not os.path.isdir(user_dir):
      os.mkdir(user_dir)

    fullpath = os.path.join(user_dir, file_name)
    with open(fullpath, 'w+') as job_desc_file:
      json.dump(self.values, job_desc_file)

    git.RunGit(workdir, ['add', fullpath])
    extra_env = {
        # The committer field makes sure the creds match what the remote
        # gerrit instance expects while the author field allows lookup
        # on the console to work.  http://crosbug.com/27939
        'GIT_COMMITTER_EMAIL' : self.user_email,
        'GIT_AUTHOR_EMAIL'    : self.user_email,
    }
    git.RunGit(workdir, ['commit', '-m', self.description],
               extra_env=extra_env)

    try:
      git.PushWithRetry(push_branch, workdir, retries=3, dryrun=dryrun)
    except cros_build_lib.RunCommandError:
      logging.error(
          'Failed to submit tryjob.  This could be due to too many '
          'submission requests by users.  Please try again.')
      raise
Пример #7
0
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    options.Freeze()

    overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
    android_package_dir = os.path.join(overlay_dir, constants.ANDROID_CP)
    version_to_uprev = None

    (unstable_ebuild,
     stable_ebuilds) = FindAndroidCandidates(android_package_dir)
    acls = MakeAclDict(android_package_dir)
    # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
    version_to_uprev = MirrorArtifacts(options.android_bucket_url,
                                       options.android_build_branch,
                                       options.arc_bucket_url, acls,
                                       constants.ANDROID_BUILD_TARGETS,
                                       options.force_version)

    # Mirror GTS.
    MirrorArtifacts(options.android_bucket_url,
                    options.android_gts_build_branch, options.arc_bucket_url,
                    acls, constants.ANDROID_GTS_BUILD_TARGETS)

    stable_candidate = portage_util.BestEBuild(stable_ebuilds)

    if stable_candidate:
        logging.info('Stable candidate found %s' % stable_candidate.version)
    else:
        logging.info('No stable candidate found.')

    tracking_branch = 'remotes/m/%s' % os.path.basename(
        options.tracking_branch)
    existing_branch = git.GetCurrentBranch(android_package_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch,
                                                android_package_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        git.RunGit(overlay_dir, ['rebase', existing_branch])

    android_version_atom = MarkAndroidEBuildAsStable(
        stable_candidate, unstable_ebuild, constants.ANDROID_PN,
        version_to_uprev, android_package_dir, options.android_build_branch,
        options.arc_bucket_url)
    if android_version_atom:
        if options.boards:
            cros_mark_as_stable.CleanStalePackages(options.srcroot,
                                                   options.boards.split(':'),
                                                   [android_version_atom])

        # Explicit print to communicate to caller.
        print('ANDROID_VERSION_ATOM=%s' % android_version_atom)
Пример #8
0
def PushChange(stable_branch, tracking_branch, dryrun, cwd):
    """Pushes commits in the stable_branch to the remote git repository.

  Pushes local commits from calls to CommitChange to the remote git
  repository specified by current working directory. If changes are
  found to commit, they will be merged to the merge branch and pushed.
  In that case, the local repository will be left on the merge branch.

  Args:
    stable_branch: The local branch with commits we want to push.
    tracking_branch: The tracking branch of the local branch.
    dryrun: Use git push --dryrun to emulate a push.
    cwd: The directory to run commands in.
  Raises:
      OSError: Error occurred while pushing.
  """
    if not _DoWeHaveLocalCommits(stable_branch, tracking_branch, cwd):
        cros_build_lib.Info('No work found to push in %s.  Exiting', cwd)
        return

    # For the commit queue, our local branch may contain commits that were
    # just tested and pushed during the CommitQueueCompletion stage. Sync
    # and rebase our local branch on top of the remote commits.
    remote, push_branch = git.GetTrackingBranch(cwd, for_push=True)
    git.SyncPushBranch(cwd, remote, push_branch)

    # Check whether any local changes remain after the sync.
    if not _DoWeHaveLocalCommits(stable_branch, push_branch, cwd):
        cros_build_lib.Info('All changes already pushed for %s. Exiting', cwd)
        return

    description = cros_build_lib.RunCommandCaptureOutput([
        'git', 'log', '--format=format:%s%n%n%b',
        '%s..%s' % (push_branch, stable_branch)
    ],
                                                         cwd=cwd).output
    description = 'Marking set of ebuilds as stable\n\n%s' % description
    cros_build_lib.Info('For %s, using description %s', cwd, description)
    git.CreatePushBranch(constants.MERGE_BRANCH, cwd)
    git.RunGit(cwd, ['merge', '--squash', stable_branch])
    git.RunGit(cwd, ['commit', '-m', description])
    git.RunGit(cwd, ['config', 'push.default', 'tracking'])
    git.PushWithRetry(constants.MERGE_BRANCH, cwd, dryrun=dryrun)
    def _UpdateLuciProject(self):
        chromite_source_file = os.path.join(constants.CHROMITE_DIR, 'config',
                                            'luci-scheduler.cfg')
        generated_source_file = os.path.join(self.project_dir, 'generated',
                                             'luci-scheduler.cfg')

        target_file = os.path.join(self.project_dir, 'luci',
                                   'luci-scheduler.cfg')

        concatenated_content = (osutils.ReadFile(chromite_source_file) +
                                '\n\n' +
                                osutils.ReadFile(generated_source_file))

        if concatenated_content == osutils.ReadFile(target_file):
            logging.PrintBuildbotStepText(
                'luci-scheduler.cfg current: No Update.')
            return

        chromite_rev = git.RunGit(
            constants.CHROMITE_DIR,
            ['rev-parse', 'HEAD:config/luci-scheduler.cfg']).output.rstrip()

        message = textwrap.dedent("""\
      luci-scheduler.cfg: Chromite %s

      Auto update to match generated file in chromite and luci config.
      """ % chromite_rev)

        with open(target_file, 'w') as f:
            f.write(concatenated_content)

        git.RunGit(self.project_dir, ['add', '-A'])
        git.RunGit(self.project_dir, ['commit', '-m', message])

        push_to = git.RemoteRef('origin', self.PROJECT_BRANCH)
        logging.info('Pushing to branch (%s) with message: %s %s', push_to,
                     message, ' (dryrun)' if self._run.options.debug else '')
        git.RunGit(self.project_dir, ['config', 'push.default', 'tracking'],
                   print_cmd=True)
        git.PushBranch(self.PROJECT_BRANCH,
                       self.project_dir,
                       dryrun=self._run.options.debug)
        logging.PrintBuildbotStepText('luci-scheduler.cfg: Updated.')
Пример #10
0
 def _SetMirrorVersion(self, version, only_if_missing=False):
     for path in (self.ext_mirror, self.int_mirror):
         vpath = os.path.join(path,
                              remote_try.RemoteTryJob.TRYJOB_FORMAT_FILE)
         if os.path.exists(vpath) and only_if_missing:
             continue
         # Get ourselves a working dir.
         tmp_repo = os.path.join(self.tempdir, 'tmp-repo')
         git.RunGit(self.tempdir, ['clone', path, tmp_repo])
         vpath = os.path.join(tmp_repo,
                              remote_try.RemoteTryJob.TRYJOB_FORMAT_FILE)
         with open(vpath, 'w') as f:
             f.write(str(version))
         git.RunGit(tmp_repo, ['add', vpath])
         git.RunGit(tmp_repo,
                    ['commit', '-m',
                     'setting version to %s' % version])
         git.RunGit(tmp_repo, ['push', path, 'master:master'])
         shutil.rmtree(tmp_repo)
Пример #11
0
 def GetLatestSHA1ForBranch(self, project, branch):
   """Return the git hash at the tip of a branch."""
   url = '%s://%s/%s' % (gob_util.GIT_PROTOCOL, self.host, project)
   cmd = ['ls-remote', url, 'refs/heads/%s' % branch]
   try:
     result = git.RunGit('.', cmd, print_cmd=self.print_cmd)
     if result:
       return result.output.split()[0]
   except cros_build_lib.RunCommandError:
     logging.error('Command "%s" failed.', cros_build_lib.CmdToStr(cmd),
                   exc_info=True)
Пример #12
0
  def _PerformStageInTempDir(self):
    # The plan for the builders is to use master branch to bootstrap other
    # branches. Now, if we wanted to test patches for both the bootstrap code
    # (on master) and the branched chromite (say, R20), we need to filter the
    # patches by branch.
    filter_branch = self._run.manifest_branch
    if self._run.options.test_bootstrap:
      filter_branch = 'master'

    # Filter all requested patches for the branch.
    branch_pool = self.patch_pool.FilterBranch(filter_branch)

    # Checkout the new version of chromite, and patch it.
    chromite_dir = os.path.join(self.tempdir, 'chromite')
    reference_repo = os.path.join(constants.CHROMITE_DIR, '.git')
    git.Clone(chromite_dir, constants.CHROMITE_URL, reference=reference_repo)
    git.RunGit(chromite_dir, ['checkout', filter_branch])

    chromite_pool = branch_pool.Filter(project=constants.CHROMITE_PROJECT)
    if chromite_pool:
      patches = patch_series.PatchSeries.WorkOnSingleRepo(
          chromite_dir, filter_branch)
      self._ApplyPatchSeries(patches, chromite_pool)

    # Re-exec into new instance of cbuildbot, with proper command line args.
    cbuildbot_path = constants.PATH_TO_CBUILDBOT
    if not os.path.exists(os.path.join(self.tempdir, cbuildbot_path)):
      cbuildbot_path = 'chromite/cbuildbot/cbuildbot'
    cmd = self.FilterArgsForTargetCbuildbot(self.tempdir, cbuildbot_path,
                                            self._run.options)

    extra_params = ['--sourceroot', self._run.options.sourceroot]
    extra_params.extend(self._run.options.bootstrap_args)
    if self._run.options.test_bootstrap:
      # We don't want re-executed instance to see this.
      cmd = [a for a in cmd if a != '--test-bootstrap']
    else:
      # If we've already done the desired number of bootstraps, disable
      # bootstrapping for the next execution.  Also pass in the patched manifest
      # repository.
      extra_params.append('--nobootstrap')
      if self._run.config.internal:
        manifest_pool = branch_pool.FilterIntManifest()
      else:
        manifest_pool = branch_pool.FilterExtManifest()

      if manifest_pool:
        manifest_dir = self._ApplyManifestPatches(manifest_pool)
        extra_params.extend(['--manifest-repo-url', manifest_dir])

    cmd += extra_params
    result_obj = cros_build_lib.run(
        cmd, cwd=self.tempdir, kill_timeout=30, error_code_ok=True)
    self.returncode = result_obj.returncode
Пример #13
0
    def _Transaction(self, commits):
        """ContextManager used to rollback changes to a build root if necessary.

    Specifically, if an unhandled non system exception occurs, this context
    manager will roll back all relevant modifications to the git repos
    involved.

    Args:
      commits: A sequence of cros_patch.GitRepoPatch instances that compromise
        this transaction- this is used to identify exactly what may be changed,
        thus what needs to be tracked and rolled back if the transaction fails.
    """
        # First, the book keeping code; gather required data so we know what
        # to rollback to should this transaction fail.  Specifically, we track
        # what was checked out for each involved repo, and if it was a branch,
        # the sha1 of the branch; that information is enough to rewind us back
        # to the original repo state.
        project_state = set(
            map(functools.partial(self.GetGitRepoForChange, strict=True),
                commits))
        resets = []
        for project_dir in project_state:
            current_sha1 = git.RunGit(
                project_dir, ['rev-list', '-n1', 'HEAD']).output.strip()
            resets.append((project_dir, current_sha1))
            assert current_sha1

        committed_cache = self._committed_cache.copy()

        try:
            yield
        except Exception:
            logging.info("Rewinding transaction: failed changes: %s .",
                         ', '.join(map(str, commits)),
                         exc_info=True)

            for project_dir, sha1 in resets:
                git.RunGit(project_dir, ['reset', '--hard', sha1])

            self._committed_cache = committed_cache
            raise
Пример #14
0
 def testGitRepoHasChanges(self):
   """Tests that GitRepoHasChanges works correctly."""
   git.RunGit(self.tempdir,
              ['clone', '--depth=1', constants.CHROMITE_DIR, self.tempdir])
   # No changes yet as we just cloned the repo.
   self.assertFalse(portage_util.EBuild.GitRepoHasChanges(self.tempdir))
   # Update metadata but no real changes.
   osutils.Touch(os.path.join(self.tempdir, 'LICENSE'))
   self.assertFalse(portage_util.EBuild.GitRepoHasChanges(self.tempdir))
   # A real change.
   osutils.WriteFile(os.path.join(self.tempdir, 'LICENSE'), 'hi')
   self.assertTrue(portage_util.EBuild.GitRepoHasChanges(self.tempdir))
Пример #15
0
        def _Reset(checkout):
            path = checkout.GetPath()

            # There is no need to reset the branch if it doesn't exist.
            if not git.DoesCommitExistInRepo(path, branch):
                return

            if fetch:
                git.RunGit(path, ['fetch', '--all'])

            def _LogBranch():
                branches = git.RunGit(path,
                                      ['branch', '-vv']).output.splitlines()
                branch_line = [b for b in branches if branch in b]
                logging.info(branch_line)

            _LogBranch()
            git.RunGit(path, ['checkout', '-f', branch])
            logging.info('Resetting to %s', checkout['tracking_branch'])
            git.RunGit(path, ['reset', checkout['tracking_branch'], '--hard'])
            _LogBranch()
Пример #16
0
  def setUp(self):
    self.manifest_dir = os.path.join(self.tempdir, '.repo', 'manifests')

    # Initialize a repo instance here.
    local_repo = os.path.join(constants.SOURCE_ROOT, '.repo/repo/.git')

    # TODO(evanhernandez): This is a hack. Find a way to simplify this test.
    # We used to use the current checkout's manifests.git, but that caused
    # problems in production environemnts.
    remote_manifests = os.path.join(self.tempdir, 'remote', 'manifests.git')
    osutils.SafeMakedirs(remote_manifests)
    git.Init(remote_manifests)
    default_manifest = os.path.join(remote_manifests, 'default.xml')
    osutils.WriteFile(
        default_manifest,
        '<?xml version="1.0" encoding="UTF-8"?><manifest></manifest>')
    git.AddPath(default_manifest)
    git.Commit(remote_manifests, 'dummy commit', allow_empty=True)
    git.CreateBranch(remote_manifests, 'default')
    git.CreateBranch(remote_manifests, 'release-R23-2913.B')
    git.CreateBranch(remote_manifests, 'release-R23-2913.B-suffix')
    git.CreateBranch(remote_manifests, 'firmware-link-')

    # Create a copy of our existing manifests.git, but rewrite it so it
    # looks like a remote manifests.git.  This is to avoid hitting the
    # network, and speeds things up in general.
    local_manifests = 'file://%s' % remote_manifests
    temp_manifests = os.path.join(self.tempdir, 'manifests.git')
    git.RunGit(self.tempdir, ['clone', '-n', '--bare', local_manifests])
    git.RunGit(temp_manifests,
               ['fetch', '-f', '-u', local_manifests,
                'refs/remotes/origin/*:refs/heads/*'])
    git.RunGit(temp_manifests, ['branch', '-D', 'default'])
    repo = repository.RepoRepository(
        temp_manifests, self.tempdir,
        repo_url='file://%s' % local_repo, repo_branch='default')
    repo.Initialize()

    self.active_manifest = os.path.realpath(
        os.path.join(self.tempdir, '.repo', 'manifest.xml'))
Пример #17
0
    def Upload(self):
        """Uploads the change to gerrit."""
        logging.info('Uploading commit.')

        try:
            # Run 'git cl upload' with --bypass-hooks to skip running scripts that are
            # not part of the shallow checkout, -f to skip editing the CL message,
            upload_args = self._git_committer_args + [
                'cl', 'upload', '-v', '-m', self._commit_msg, '--bypass-hooks',
                '-f', '--tbrs', constants.CHROME_GARDENER_REVIEW_EMAIL
            ]
            # Marks CL as ready.
            upload_args += ['--send-mail']
            if self._dryrun:
                upload_args += ['--dry-run']
            git.RunGit(self._checkout_dir,
                       upload_args,
                       print_cmd=True,
                       redirect_stderr=True,
                       capture_output=False)

            # Flip the CQ commit bit.
            submit_args = ['cl', 'set-commit', '-v']
            if self._dryrun:
                submit_args += ['--dry-run']
            git.RunGit(self._checkout_dir,
                       submit_args,
                       print_cmd=True,
                       redirect_stderr=True,
                       capture_output=False)
        except cros_build_lib.RunCommandError as e:
            # Log the change for debugging.
            git.RunGit(self._checkout_dir,
                       ['--no-pager', 'log', '--pretty=full'],
                       capture_output=False)
            raise CommitError('Could not submit: %r' % e)

        logging.info('Submitted to CQ.')
Пример #18
0
  def Git(self, command):
    """Wrapper of git.RunGit.

    It passes self.repo_dir as git_repo to git.RunGit. Also, it
    sets error_code_ok=True so when git encounters an error, instead of
    raising RunCommandError, it returns CommandResult with non-zero return code.

    Args:
      command: git command.

    Returns:
      A CommandResult object.
    """
    return git.RunGit(self.repo_dir, command, error_code_ok=True)
Пример #19
0
 def testGetDiffStatus(self):
   git1, _, patch1 = self._CommonGitSetup()
   # Ensure that it can work on the first commit, even if it
   # doesn't report anything (no delta; it's the first files).
   patch1 = self._MkPatch(git1, self._GetSha1(git1, self.DEFAULT_TRACKING))
   self.assertEqual({}, patch1.GetDiffStatus(git1))
   patch2 = self.CommitFile(git1, 'monkeys', 'blah')
   self.assertEqual({'monkeys': 'M'}, patch2.GetDiffStatus(git1))
   git.RunGit(git1, ['mv', 'monkeys', 'monkeys2'])
   patch3 = self._MkPatch(git1, self._MakeCommit(git1, commit='mv'))
   self.assertEqual({'monkeys': 'D', 'monkeys2': 'A'},
                    patch3.GetDiffStatus(git1))
   patch4 = self.CommitFile(git1, 'monkey2', 'blah')
   self.assertEqual({'monkey2': 'A'}, patch4.GetDiffStatus(git1))
Пример #20
0
    def testBranchSpecifiedNoChanges(self):
        """Test when no changes on the branch specified by user."""
        output_obj = self.mox.CreateMock(cros_build_lib.CommandResult)
        output_obj.output = ''
        self.manifest.GetProjectPath('my/project', True).AndReturn('mydir')
        self.manifest.GetProjectsLocalRevision('my/project').AndReturn(
            'm/master')
        self.manifest.GetAttributeForProject('my/project',
                                             'remote').AndReturn('cros')
        git.RunGit('mydir', mox.In('m/master..mybranch')).AndReturn(output_obj)
        self.mox.ReplayAll()

        self.assertRaises(SystemExit, cros_patch.PrepareLocalPatches,
                          self.manifest, self.patches)
    def testPushChange(self):
        git_log = 'Marking test_one as stable\nMarking test_two as stable\n'
        fake_description = 'Marking set of ebuilds as stable\n\n%s' % git_log
        self.mox.StubOutWithMock(cros_mark_as_stable, '_DoWeHaveLocalCommits')
        self.mox.StubOutWithMock(cros_mark_as_stable.GitBranch, 'CreateBranch')
        self.mox.StubOutWithMock(cros_mark_as_stable.GitBranch, 'Exists')
        self.mox.StubOutWithMock(git, 'PushWithRetry')
        self.mox.StubOutWithMock(git, 'GetTrackingBranch')
        self.mox.StubOutWithMock(git, 'SyncPushBranch')
        self.mox.StubOutWithMock(git, 'CreatePushBranch')
        self.mox.StubOutWithMock(git, 'RunGit')

        cros_mark_as_stable._DoWeHaveLocalCommits(self._branch,
                                                  self._target_manifest_branch,
                                                  '.').AndReturn(True)
        git.GetTrackingBranch('.', for_push=True).AndReturn(
            ['gerrit', 'refs/remotes/gerrit/master'])
        git.SyncPushBranch('.', 'gerrit', 'refs/remotes/gerrit/master')
        cros_mark_as_stable._DoWeHaveLocalCommits(
            self._branch, 'refs/remotes/gerrit/master', '.').AndReturn(True)
        result = cros_build_lib.CommandResult(output=git_log)
        cros_build_lib.RunCommandCaptureOutput([
            'git', 'log', '--format=format:%s%n%n%b',
            'refs/remotes/gerrit/master..%s' % self._branch
        ],
                                               cwd='.').AndReturn(result)
        git.CreatePushBranch('merge_branch', '.')
        git.RunGit('.', ['merge', '--squash', self._branch])
        git.RunGit('.', ['commit', '-m', fake_description])
        git.RunGit('.', ['config', 'push.default', 'tracking'])
        git.PushWithRetry('merge_branch', '.', dryrun=False)
        self.mox.ReplayAll()
        cros_mark_as_stable.PushChange(self._branch,
                                       self._target_manifest_branch, False,
                                       '.')
        self.mox.VerifyAll()
def GetActiveProjects():
    """Return the list of active projects."""
    # Look at all the paths (files & dirs) in the top of the git repo.  This way
    # we ignore local directories devs created that aren't actually committed.
    cmd = ['ls-tree', '--name-only', '-z', 'HEAD']
    result = git.RunGit(TOP_DIR, cmd)

    # Split the output on NULs to avoid whitespace/etc... issues.
    paths = result.stdout.split('\0')

    # ls-tree -z will include a trailing NUL on all entries, not just seperation,
    # so filter it out if found (in case ls-tree behavior changes on us).
    for path in [Path(x) for x in paths if x]:
        if (TOP_DIR / path).is_dir():
            yield path
    def _CreateConfigPatch(self):
        """Create and return a diff patch file for config changes."""
        config_change_patch = os.path.join(self.chromite_dir,
                                           'config_change.patch')
        try:
            os.remove(config_change_patch)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise

        result = git.RunGit(self.chromite_dir, ['diff'] + self.config_paths,
                            print_cmd=True)
        with open(config_change_patch, 'w') as f:
            f.write(result.output)

        return config_change_patch
    def _ContainsConfigUpdates(self):
        """Check if updates exist and requires a push.

    Returns:
      True if updates exist; otherwise False.
    """
        modifications = git.RunGit(self.chromite_dir,
                                   ['status', '--porcelain', '--'] +
                                   self.config_paths,
                                   capture_output=True,
                                   print_cmd=True).output
        if modifications:
            logging.info('Changed files: %s ', modifications)
            return True
        else:
            return False
def _SetupWorkDirectoryForPatch(work_dir, patch, branch, manifest, email):
    """Set up local dir for uploading changes to the given patch's project."""
    logging.notice('Setting up dir %s for uploading changes to %s', work_dir,
                   patch.project_url)

    # Clone the git repo from reference if we have a pointer to a
    # ManifestCheckout object.
    reference = None
    if manifest:
        # Get the path to the first checkout associated with this change. Since
        # all of the checkouts share git objects, it doesn't matter which checkout
        # we pick.
        path = manifest.FindCheckouts(patch.project,
                                      only_patchable=True)[0]['path']

        reference = os.path.join(constants.SOURCE_ROOT, path)
        if not os.path.isdir(reference):
            logging.error('Unable to locate git checkout: %s', reference)
            logging.error('Did you mean to use --nomirror?')
            # This will do an "raise OSError" with the right values.
            os.open(reference, os.O_DIRECTORY)
        # Use the email if email wasn't specified.
        if not email:
            email = git.GetProjectUserEmail(reference)

    repository.CloneGitRepo(work_dir, patch.project_url, reference=reference)

    # Set the git committer.
    git.RunGit(work_dir, ['config', '--replace-all', 'user.email', email])

    mbranch = git.MatchSingleBranchName(work_dir,
                                        branch,
                                        namespace='refs/remotes/origin/')
    if branch != mbranch:
        logging.notice('Auto resolved branch name "%s" to "%s"', branch,
                       mbranch)
    branch = mbranch

    # Finally, create a local branch for uploading changes to the given remote
    # branch.
    git.CreatePushBranch(constants.PATCH_BRANCH,
                         work_dir,
                         sync=False,
                         remote_push_branch=git.RemoteRef(
                             'ignore', 'origin/%s' % branch))

    return branch
Пример #26
0
    def __init__(self, ebuild_dir, before=None):
        """Construct a Chrome uprev object

    Args:
      ebuild_dir: Path to the directory with the chrome ebuild in it.
      before: CL to work backwards from.
    """
        # Format includes the hash, commit body including subject, and author date.
        cmd = [
            'log', '-n', '1', '--author', 'chrome-bot', '--grep',
            cros_mark_as_stable.GIT_COMMIT_SUBJECT,
            '--format=format:%H%n%aD%n%B'
        ]
        if before:
            cmd.append(str(before) + '~')
        cmd.append('.')
        log = git.RunGit(ebuild_dir, cmd).output
        if not log.strip():
            raise UprevNotFound('No uprev CL was found')

        self.sha, _, log = log.partition('\n')
        self.date, _, message = log.partition('\n')
        self.conf_files = [m.group('conf') for m in CONF_RE.finditer(message)]

        entries = git.RawDiff(ebuild_dir, '%s^!' % self.sha)
        for entry in entries:
            if entry.status != 'R':
                continue

            from_path = entry.src_file
            to_path = entry.dst_file

            if (os.path.splitext(from_path)[1] != '.ebuild'
                    or os.path.splitext(to_path)[1] != '.ebuild'):
                continue

            self.from_parts = SplitPVPath(from_path)
            self.to_parts = SplitPVPath(to_path)
            if (self.from_parts.package != 'chromeos-chrome'
                    or self.to_parts.package != 'chromeos-chrome'):
                continue

            break
        else:
            raise Exception('Failed to find chromeos-chrome uprev in CL %s' %
                            self.sha)
Пример #27
0
def WalkReferences(repo_root, max_depth=5, suppress=()):
    """Given a repo checkout root, find the repo's it references up to max_depth.

  Args:
    repo_root: The root of a repo checkout to start from
    max_depth: Git internally limits the max alternates depth to 5;
      this option exists to adjust how deep we're willing to look.
    suppress: List of repos already seen (and so to ignore).

  Returns:
    List of repository roots required for this repo_root.
  """

    original_root = repo_root
    seen = set(os.path.abspath(x) for x in suppress)

    for _x in xrange(0, max_depth):
        repo_root = os.path.abspath(repo_root)

        if repo_root in seen:
            # Cyclic reference graph; break out of it, if someone induced this the
            # necessary objects should be in place.  If they aren't, really isn't
            # much that can be done.
            return

        yield repo_root
        seen.add(repo_root)
        base = os.path.join(repo_root, '.repo', 'manifests.git')
        result = git.RunGit(base, ['config', 'repo.reference'],
                            error_code_ok=True)

        if result.returncode not in (0, 1):
            raise Failed('Unexpected returncode %i from examining %s git '
                         'repo.reference configuration' %
                         (result.returncode, base))

        repo_root = result.output.strip()
        if not repo_root:
            break

    else:
        raise Failed(
            'While tracing out the references of %s, we recursed more '
            'than the allowed %i times ending at %s' %
            (original_root, max_depth, repo_root))
Пример #28
0
  def testDeleteEbuildTwice(self):
    """Test that double-deletes of ebuilds are flagged as conflicts."""
    # Create monkeys.ebuild for testing.
    git1 = self._MakeRepo('git1', self.source)
    patch1 = self.CommitFile(git1, 'monkeys.ebuild', 'rule')
    git.RunGit(git1, ['rm', 'monkeys.ebuild'])
    patch2 = self._MkPatch(git1, self._MakeCommit(git1, commit='rm'))

    # Delete an ebuild that does not exist in TOT.
    check_attrs = {'inflight': False, 'files': ('monkeys.ebuild',)}
    self.assertRaises2(cros_patch.EbuildConflict, patch2.Apply, git1,
                       self.DEFAULT_TRACKING, check_attrs=check_attrs)

    # Delete an ebuild that exists in TOT, but does not exist in the current
    # patch series.
    check_attrs['inflight'] = True
    self.assertRaises2(cros_patch.EbuildConflict, patch2.Apply, git1,
                       patch1.sha1, check_attrs=check_attrs)
Пример #29
0
def _FetchChangesForRepo(fetched_changes, by_repo, repo):
    """Fetch the changes for a given `repo`.

  Args:
    fetched_changes: A dict from change ids to changes which is updated by
      this method.
    by_repo: A mapping from repositories to changes.
    repo: The repository we should fetch the changes for.
  """
    changes = by_repo[repo]
    refs = set(c.ref for c in changes if not c.HasBeenFetched(repo))
    cmd = ['fetch', '-f', changes[0].project_url] + list(refs)
    git.RunGit(repo, cmd, print_cmd=True)

    for change in changes:
        sha1 = change.HasBeenFetched(repo) or change.sha1
        change.UpdateMetadataFromRepo(repo, sha1=sha1)
        fetched_changes[change.id] = change
Пример #30
0
    def _EnsureMirroring(self, post_sync=False):
        """Ensure git is usable from w/in the chroot if --references is enabled

    repo init --references hardcodes the abspath to parent; this pathway
    however isn't usable from the chroot (it doesn't exist).  As such the
    pathway is rewritten to use relative pathways pointing at the root of
    the repo, which via I84988630 enter_chroot sets up a helper bind mount
    allowing git/repo to access the actual referenced repo.

    This has to be invoked prior to a repo sync of the target trybot to
    fix any pathways that may have been broken by the parent repo moving
    on disk, and needs to be invoked after the sync has completed to rewrite
    any new project's abspath to relative.
    """
        if not self._referenced_repo:
            return

        proj_root = os.path.join(self.directory, '.repo', 'project-objects')
        if not os.path.exists(proj_root):
            # Not yet synced, nothing to be done.
            return

        rewrite_git_alternates.RebuildRepoCheckout(self.directory,
                                                   self._referenced_repo)

        if post_sync:
            chroot_path = os.path.join(self._referenced_repo, '.repo',
                                       'chroot', 'external')
            chroot_path = path_util.ToChrootPath(chroot_path)
            rewrite_git_alternates.RebuildRepoCheckout(self.directory,
                                                       self._referenced_repo,
                                                       chroot_path)

        # Finally, force the git config marker that enter_chroot looks for
        # to know when to do bind mounting trickery; this normally will exist,
        # but if we're converting a pre-existing repo checkout, it's possible
        # that it was invoked w/out the reference arg.  Note this must be
        # an absolute path to the source repo- enter_chroot uses that to know
        # what to bind mount into the chroot.
        cmd = [
            'config', '--file', self._ManifestConfig, 'repo.reference',
            self._referenced_repo
        ]
        git.RunGit('.', cmd)