def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    options.Freeze()

    if options.command == 'commit':
        if not options.packages and not options.all:
            parser.error('Please specify at least one package (--packages)')
        if options.force and options.all:
            parser.error(
                'Cannot use --force with --all. You must specify a list of '
                'packages you want to force uprev.')

    if not os.path.isdir(options.srcroot):
        parser.error('srcroot is not a valid path: %s' % options.srcroot)

    portage_util.EBuild.VERBOSE = options.verbose

    package_list = None
    if options.packages:
        package_list = options.packages.split(':')

    overlays = []
    if options.overlays:
        for path in options.overlays.split(':'):
            if not os.path.isdir(path):
                cros_build_lib.Die('Cannot find overlay: %s' % path)
            overlays.append(os.path.realpath(path))
    else:
        logging.warning('Missing --overlays argument')
        overlays.extend([
            '%s/private-overlays/chromeos-overlay' % options.srcroot,
            '%s/third_party/chromiumos-overlay' % options.srcroot
        ])

    manifest = git.ManifestCheckout.Cached(options.srcroot)

    # Dict mapping from each overlay to its tracking branch.
    overlay_tracking_branch = {}
    # Dict mapping from each git repository (project) to a list of its overlays.
    git_project_overlays = {}

    for overlay in overlays:
        remote_ref = git.GetTrackingBranchViaManifest(overlay,
                                                      manifest=manifest)
        overlay_tracking_branch[overlay] = remote_ref.ref
        git_project_overlays.setdefault(remote_ref.project_name,
                                        []).append(overlay)

    if options.command == 'push':
        _WorkOnPush(options, overlay_tracking_branch, git_project_overlays)
    elif options.command == 'commit':
        _WorkOnCommit(options, overlays, overlay_tracking_branch,
                      git_project_overlays, manifest, package_list)
def main(argv):
  parser = GetParser()
  options = parser.parse_args(argv)
  options.Freeze()

  if options.command == 'commit':
    if not options.packages and not options.all:
      parser.error('Please specify at least one package (--packages)')
    if options.force and options.all:
      parser.error('Cannot use --force with --all. You must specify a list of '
                   'packages you want to force uprev.')

  if not os.path.isdir(options.srcroot):
    parser.error('srcroot is not a valid path: %s' % options.srcroot)

  portage_util.EBuild.VERBOSE = options.verbose

  package_list = None
  if options.packages:
    package_list = options.packages.split(':')

  if options.overlays:
    overlays = {}
    for path in options.overlays.split(':'):
      if not os.path.isdir(path):
        cros_build_lib.Die('Cannot find overlay: %s' % path)
      overlays[path] = []
  else:
    logging.warning('Missing --overlays argument')
    overlays = {
        '%s/private-overlays/chromeos-overlay' % options.srcroot: [],
        '%s/third_party/chromiumos-overlay' % options.srcroot: [],
    }

  manifest = git.ManifestCheckout.Cached(options.srcroot)

  if options.command == 'commit':
    portage_util.BuildEBuildDictionary(overlays, options.all, package_list,
                                       allow_blacklisted=options.force)

  # Contains the array of packages we actually revved.
  revved_packages = []
  new_package_atoms = []

  for overlay in overlays:
    ebuilds = overlays[overlay]
    if not os.path.isdir(overlay):
      logging.warning('Skipping %s' % overlay)
      continue

    # Note we intentionally work from the non push tracking branch;
    # everything built thus far has been against it (meaning, http mirrors),
    # thus we should honor that.  During the actual push, the code switches
    # to the correct urls, and does an appropriate rebasing.
    tracking_branch = git.GetTrackingBranchViaManifest(
        overlay, manifest=manifest).ref

    if options.command == 'push':
      PushChange(constants.STABLE_EBUILD_BRANCH, tracking_branch,
                 options.dryrun, cwd=overlay,
                 staging_branch=options.staging_branch)
    elif options.command == 'commit':
      existing_commit = git.GetGitRepoRevision(overlay)
      work_branch = GitBranch(constants.STABLE_EBUILD_BRANCH, tracking_branch,
                              cwd=overlay)
      work_branch.CreateBranch()
      if not work_branch.Exists():
        cros_build_lib.Die('Unable to create stabilizing branch in %s' %
                           overlay)

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

      messages = []
      for ebuild in ebuilds:
        if options.verbose:
          logging.info('Working on %s, info %s', ebuild.package,
                       ebuild.cros_workon_vars)
        try:
          new_package = ebuild.RevWorkOnEBuild(options.srcroot, manifest)
          if new_package:
            revved_packages.append(ebuild.package)
            new_package_atoms.append('=%s' % new_package)
            messages.append(_GIT_COMMIT_MESSAGE % ebuild.package)
        except (OSError, IOError):
          logging.warning(
              'Cannot rev %s\n'
              'Note you will have to go into %s '
              'and reset the git repo yourself.' % (ebuild.package, overlay))
          raise

      if messages:
        portage_util.EBuild.CommitChange('\n\n'.join(messages), overlay)

  if options.command == 'commit':
    chroot_path = os.path.join(options.srcroot, constants.DEFAULT_CHROOT_DIR)
    if os.path.exists(chroot_path):
      CleanStalePackages(options.srcroot, options.boards.split(':'),
                         new_package_atoms)
    if options.drop_file:
      osutils.WriteFile(options.drop_file, ' '.join(revved_packages))
def main(_argv):
    parser = optparse.OptionParser('cros_mark_as_stable OPTIONS packages')
    parser.add_option('--all',
                      action='store_true',
                      help='Mark all packages as stable.')
    parser.add_option('-b',
                      '--boards',
                      default='',
                      help='Colon-separated list of boards')
    parser.add_option('--drop_file',
                      help='File to list packages that were revved.')
    parser.add_option('--dryrun',
                      action='store_true',
                      help='Passes dry-run to git push if pushing a change.')
    parser.add_option('-o',
                      '--overlays',
                      help='Colon-separated list of overlays to modify.')
    parser.add_option('-p',
                      '--packages',
                      help='Colon separated list of packages to rev.')
    parser.add_option('-r',
                      '--srcroot',
                      default=os.path.join(constants.SOURCE_ROOT, 'src'),
                      help='Path to root src directory.')
    parser.add_option('--verbose',
                      action='store_true',
                      help='Prints out debug info.')
    (options, args) = parser.parse_args()

    portage_utilities.EBuild.VERBOSE = options.verbose

    if len(args) != 1:
        _PrintUsageAndDie('Must specify a valid command [commit, push]')

    command = args[0]
    package_list = None
    if options.packages:
        package_list = options.packages.split(':')

    _CheckSaneArguments(command, options)
    if options.overlays:
        overlays = {}
        for path in options.overlays.split(':'):
            if not os.path.isdir(path):
                cros_build_lib.Die('Cannot find overlay: %s' % path)
            overlays[path] = []
    else:
        cros_build_lib.Warning('Missing --overlays argument')
        overlays = {
            '%s/private-overlays/chromeos-overlay' % options.srcroot: [],
            '%s/third_party/chromiumos-overlay' % options.srcroot: []
        }

    manifest = git.ManifestCheckout.Cached(options.srcroot)

    if command == 'commit':
        portage_utilities.BuildEBuildDictionary(overlays, options.all,
                                                package_list)

    # Contains the array of packages we actually revved.
    revved_packages = []
    new_package_atoms = []

    # Slight optimization hack: process the chromiumos overlay before any other
    # cros-workon overlay first so we can do background cache generation in it.
    # A perfect solution would walk all the overlays, figure out any dependencies
    # between them (with layout.conf), and then process them in dependency order.
    # However, this operation isn't slow enough to warrant that level of
    # complexity, so we'll just special case the main overlay.
    #
    # Similarly, generate the cache in the portage-stable tree asap.  We know
    # we won't have any cros-workon packages in there, so generating the cache
    # is the only thing it'll be doing.  The chromiumos overlay instead might
    # have revbumping to do before it can generate the cache.
    keys = overlays.keys()
    for overlay in ('/third_party/chromiumos-overlay',
                    '/third_party/portage-stable'):
        for k in keys:
            if k.endswith(overlay):
                keys.remove(k)
                keys.insert(0, k)
                break

    with parallel.BackgroundTaskRunner(portage_utilities.RegenCache) as queue:
        for overlay in keys:
            ebuilds = overlays[overlay]
            if not os.path.isdir(overlay):
                cros_build_lib.Warning("Skipping %s" % overlay)
                continue

            # Note we intentionally work from the non push tracking branch;
            # everything built thus far has been against it (meaning, http mirrors),
            # thus we should honor that.  During the actual push, the code switches
            # to the correct urls, and does an appropriate rebasing.
            tracking_branch = git.GetTrackingBranchViaManifest(
                overlay, manifest=manifest)[1]

            if command == 'push':
                PushChange(constants.STABLE_EBUILD_BRANCH,
                           tracking_branch,
                           options.dryrun,
                           cwd=overlay)
            elif command == 'commit':
                existing_branch = git.GetCurrentBranch(overlay)
                work_branch = GitBranch(constants.STABLE_EBUILD_BRANCH,
                                        tracking_branch,
                                        cwd=overlay)
                work_branch.CreateBranch()
                if not work_branch.Exists():
                    cros_build_lib.Die(
                        'Unable to create stabilizing branch in %s' % overlay)

                # In the case of uprevving overlays that have patches applied to them,
                # include the patched changes in the stabilizing branch.
                if existing_branch:
                    cros_build_lib.RunCommand(
                        ['git', 'rebase', existing_branch],
                        print_cmd=False,
                        cwd=overlay)

                messages = []
                for ebuild in ebuilds:
                    if options.verbose:
                        cros_build_lib.Info('Working on %s', ebuild.package)
                    try:
                        new_package = ebuild.RevWorkOnEBuild(
                            options.srcroot, manifest)
                        if new_package:
                            revved_packages.append(ebuild.package)
                            new_package_atoms.append('=%s' % new_package)
                            messages.append(_GIT_COMMIT_MESSAGE %
                                            ebuild.package)
                    except (OSError, IOError):
                        cros_build_lib.Warning(
                            'Cannot rev %s\n' % ebuild.package +
                            'Note you will have to go into %s '
                            'and reset the git repo yourself.' % overlay)
                        raise

                if messages:
                    portage_utilities.EBuild.CommitChange(
                        '\n\n'.join(messages), overlay)

                if cros_build_lib.IsInsideChroot():
                    # Regenerate caches if need be.  We do this all the time to
                    # catch when users make changes without updating cache files.
                    queue.put([overlay])

    if command == 'commit':
        if cros_build_lib.IsInsideChroot():
            CleanStalePackages(options.boards.split(':'), new_package_atoms)
        if options.drop_file:
            osutils.WriteFile(options.drop_file, ' '.join(revved_packages))