Example #1
0
def _Main(argv):
    result = 0

    signal.signal(signal.SIGTERM, portable.terminateHandle)

    opt = optparse.OptionParser(usage="repo wrapperinfo -- ...")
    opt.add_option("--repo-dir", dest="repodir", help="path to .repo/")
    opt.add_option("--wrapper-version",
                   dest="wrapper_version",
                   help="version of the wrapper script")
    opt.add_option("--wrapper-path",
                   dest="wrapper_path",
                   help="location of the wrapper script")

    _PruneOptions(argv, opt)
    opt, argv = opt.parse_args(argv)

    _CheckWrapperVersion(opt.wrapper_version, opt.wrapper_path)
    _CheckRepoDir(opt.repodir)

    Version.wrapper_version = opt.wrapper_version
    Version.wrapper_path = opt.wrapper_path

    repo = _Repo(opt.repodir)
    repo._Config(argv)

    gopts = repo.config[2]
    if gopts.debug:
        print("enter debug mode, host %s" % gopts.debug_host)
        _Debug(gopts.debug_host, gopts.debug_env)

    if gopts.debug:
        if portable.isPosix():
            # deactivate pager on posix systems since forked process cant be debugged
            os.environ['GIT_PAGER'] = ''

    # intercept here if on Windows and Pager is required
    if not portable.isPosix():
        if _WindowsPager(repo):
            # everything was already done; so exit
            return 0

    try:
        try:
            init_ssh()
            init_http()
            result = repo._Run() or 0
        finally:
            close_ssh()
    except KeyboardInterrupt:
        print('aborted by user', file=sys.stderr)
        result = 1
    except ManifestParseError as mpe:
        print('fatal: %s' % mpe, file=sys.stderr)
        result = 1
    except RepoChangedException as rce:
        # If repo changed, re-exec ourselves.
        #
        argv = list(sys.argv)
        argv.extend(rce.extra_args)
        argv = [sys.executable] + argv
        try:
            argv.insert(0, __file__)
            argv.insert(0, sys.executable)
            result = subprocess.call(argv)
        except OSError as e:
            print('fatal: cannot restart repo after upgrade', file=sys.stderr)
            print('fatal: %s' % e, file=sys.stderr)
            result = 128

    return result
Example #2
0
    def Execute(self, opt, args):
        if opt.jobs:
            self.jobs = opt.jobs
        if self.jobs > 1:
            soft_limit, _ = _rlimit_nofile()
            self.jobs = min(self.jobs, (soft_limit - 5) / 3)

        if opt.network_only and opt.detach_head:
            print('error: cannot combine -n and -d', file=sys.stderr)
            sys.exit(1)
        if opt.network_only and opt.local_only:
            print('error: cannot combine -n and -l', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_name and opt.smart_sync:
            print('error: cannot combine -m and -s', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_name and opt.smart_tag:
            print('error: cannot combine -m and -t', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_server_username or opt.manifest_server_password:
            if not (opt.smart_sync or opt.smart_tag):
                print('error: -u and -p may only be combined with -s or -t',
                      file=sys.stderr)
                sys.exit(1)
            if None in [
                    opt.manifest_server_username, opt.manifest_server_password
            ]:
                print('error: both -u and -p must be given', file=sys.stderr)
                sys.exit(1)

        if opt.manifest_name:
            self.manifest.Override(opt.manifest_name)

        if opt.smart_sync or opt.smart_tag:
            if not self.manifest.manifest_server:
                print(
                    'error: cannot smart sync: no manifest server defined in'
                    'manifest',
                    file=sys.stderr)
                sys.exit(1)

            manifest_server = self.manifest.manifest_server

            if not '@' in manifest_server:
                username = None
                password = None
                if opt.manifest_server_username and opt.manifest_server_password:
                    username = opt.manifest_server_username
                    password = opt.manifest_server_password
                else:
                    try:
                        info = netrc.netrc()
                    except IOError:
                        print(
                            '.netrc file does not exist or could not be opened',
                            file=sys.stderr)
                    else:
                        try:
                            parse_result = urllib.parse(manifest_server)
                            if parse_result.hostname:
                                username, _account, password = \
                                    info.authenticators(parse_result.hostname)
                        except TypeError:
                            # TypeError is raised when the given hostname is not present
                            # in the .netrc file.
                            print('No credentials found for %s in .netrc' %
                                  parse_result.hostname,
                                  file=sys.stderr)
                        except netrc.NetrcParseError as e:
                            print('Error parsing .netrc file: %s' % e,
                                  file=sys.stderr)

                if username and password:
                    manifest_server = manifest_server.replace(
                        '://', '://%s:%s@' % (username, password), 1)

            try:
                server = xmlrpc.server(manifest_server)
                if opt.smart_sync:
                    p = self.manifest.manifestProject
                    b = p.GetBranch(p.CurrentBranch)
                    branch = b.merge
                    if branch.startswith(R_HEADS):
                        branch = branch[len(R_HEADS):]

                    env = os.environ.copy()
                    if ('TARGET_PRODUCT' in env
                            and 'TARGET_BUILD_VARIANT' in env):
                        target = '%s-%s' % (env['TARGET_PRODUCT'],
                                            env['TARGET_BUILD_VARIANT'])
                        [success, manifest_str
                         ] = server.GetApprovedManifest(branch, target)
                    else:
                        [success,
                         manifest_str] = server.GetApprovedManifest(branch)
                else:
                    assert (opt.smart_tag)
                    [success, manifest_str] = server.GetManifest(opt.smart_tag)

                if success:
                    manifest_name = "smart_sync_override.xml"
                    manifest_path = os.path.join(
                        self.manifest.manifestProject.worktree, manifest_name)
                    try:
                        f = open(manifest_path, 'w')
                        try:
                            f.write(manifest_str)
                        finally:
                            f.close()
                    except IOError:
                        print('error: cannot write manifest to %s' %
                              manifest_path,
                              file=sys.stderr)
                        sys.exit(1)
                    self.manifest.Override(manifest_name)
                else:
                    print('error in getting manifest: %s' % manifest_str,
                          file=sys.stderr)
                    sys.exit(1)
            except (socket.error, IOError, xmlrpc.client.Fault) as e:
                print('error: cannot connect to manifest server %s:\n%s' %
                      (self.manifest.manifest_server, e),
                      file=sys.stderr)
                sys.exit(1)
            except xmlrpc.client.ProtocolError as e:
                print('error: cannot connect to manifest server %s:\n%d %s' %
                      (self.manifest.manifest_server, e.errcode, e.errmsg),
                      file=sys.stderr)
                sys.exit(1)

        rp = self.manifest.repoProject
        rp.PreSync()

        mp = self.manifest.manifestProject
        mp.PreSync()

        if opt.repo_upgraded:
            _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

        if not opt.local_only:
            mp.Sync_NetworkHalf(quiet=opt.quiet,
                                current_branch_only=opt.current_branch_only)

        if mp.HasChanges:
            syncbuf = SyncBuffer(mp.config)
            mp.Sync_LocalHalf(syncbuf)
            if not syncbuf.Finish():
                sys.exit(1)
            self.manifest._Unload()
            if opt.jobs is None:
                self.jobs = self.manifest.default.sync_j

            if not portable.isPosix():
                # fix broken manifest.xml link
                pass

        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)

        self._fetch_times = _FetchTimes(self.manifest)
        if not opt.local_only:
            to_fetch = []
            now = time.time()
            if _ONE_DAY_S <= (now - rp.LastFetch):
                to_fetch.append(rp)
            to_fetch.extend(all_projects)
            to_fetch.sort(key=self._fetch_times.Get, reverse=True)

            fetched = self._Fetch(to_fetch, opt)
            _PostRepoFetch(rp, opt.no_repo_verify)

            if opt.network_only:
                # bail out now; the rest touches the working tree
                return

            # Iteratively fetch missing and/or nested unregistered submodules
            previously_missing_set = set()
            while True:
                self.manifest._Unload()
                all_projects = self.GetProjects(
                    args, missing_ok=True, submodules_ok=opt.fetch_submodules)
                missing = []
                for project in all_projects:
                    if project.gitdir not in fetched:
                        missing.append(project)
                if not missing:
                    break
                    # Stop us from non-stopped fetching actually-missing repos: If set of
                # missing repos has not been changed from last fetch, we break.
                missing_set = set(p.name for p in missing)
                if previously_missing_set == missing_set:
                    break
                previously_missing_set = missing_set
                fetched.update(self._Fetch(missing, opt))

        if self.manifest.IsMirror:
            # bail out now, we have no working tree
            return

        if self.UpdateProjectList():
            sys.exit(1)

        syncbuf = SyncBuffer(mp.config, detach_head=opt.detach_head)
        pm = Progress('Syncing work tree', len(all_projects))
        for project in all_projects:
            pm.update()
            if project.worktree:
                if opt.report:
                    p = GitCommand(
                        project,
                        ['log', '--pretty=%h %s (%cn, %ar)', 'HEAD..m/master'],
                        capture_stdout=True)
                    if p.Wait() != 0:
                        print("Failed to create report")
                    else:
                        if len(p.stdout):
                            print('\n' + project.name + ':\n')
                            print(portable.stream2str(p.stdout)[:-1])
                            print('\n')
                if not opt.dry_run:
                    project.Sync_LocalHalf(syncbuf)
        pm.end()
        print(file=sys.stderr)
        if not syncbuf.Finish():
            sys.exit(1)

        # If there's a notice that's supposed to print at the end of the sync, print
        # it now...
        if self.manifest.notice:
            print(self.manifest.notice)
Example #3
0
    def Execute(self, opt, args):
        if not opt.command:
            self.Usage()

        cmd = [opt.command[0]]

        shell = True
        if re.compile(r'^[a-z0-9A-Z_/\.-]+$').match(cmd[0]):
            shell = False

        if shell and portable.isPosix():
            cmd.append(cmd[0])
        cmd.extend(opt.command[1:])

        if opt.project_header \
            and not shell \
            and cmd[0] == 'git':
            # If this is a direct git command that can enable colorized
            # output and the user prefers coloring, add --color into the
            # command line because we are going to wrap the command into
            # a pipe and git won't know coloring should activate.
            #
            for cn in cmd[1:]:
                if not cn.startswith('-'):
                    break
            else:
                cn = None
                # pylint: disable=W0631
            if cn and cn in _CAN_COLOR:
                class ColorCmd(Coloring):
                    def __init__(self, config, cmd):
                        Coloring.__init__(self, config, cmd)

                if ColorCmd(self.manifest.manifestProject.config, cn).is_on:
                    cmd.insert(cmd.index(cn) + 1, '--color')
                    # pylint: enable=W0631

        mirror = self.manifest.IsMirror
        out = ForallColoring(self.manifest.manifestProject.config)
        out.redirect(sys.stdout)

        rc = 0
        first = True

        for project in self.GetProjects(args):
            env = os.environ.copy()

            def setenv(name, val):
                if val is None:
                    val = ''
                env[name] = val

            setenv('REPO_PROJECT', project.name)
            setenv('REPO_PATH', project.relpath)
            setenv('REPO_REMOTE', project.remote.name)
            setenv('REPO_LREV', project.GetRevisionId())
            setenv('REPO_RREV', project.revisionExpr)
            for a in project.annotations:
                setenv("REPO__%s" % (a.name), a.value)

            if mirror:
                setenv('GIT_DIR', project.gitdir)
                cwd = project.gitdir
            else:
                cwd = project.worktree

            if not os.path.exists(cwd):
                if (opt.project_header and opt.verbose) \
                    or not opt.project_header:
                    print('skipping %s/' % project.relpath, file=sys.stderr)
                continue

            if opt.project_header:
                stdin = subprocess.PIPE
                stdout = subprocess.PIPE
                stderr = subprocess.PIPE
            else:
                stdin = None
                stdout = None
                stderr = None

            if not portable.isUnix():
                if type(cmd) is list:
                    cmd = " ".join(cmd)

            if IsTrace():
                Trace("execute command: %s" % str(cmd).replace("%", "%%"))
                Trace("environment is: %s" % str(env))

            p = subprocess.Popen(cmd,
                                 cwd=cwd,
                                 shell=shell,
                                 env=env,
                                 stdin=stdin,
                                 stdout=stdout,
                                 stderr=stderr)

            if opt.project_header:
                class sfd(object):
                    def __init__(self, fd, dest):
                        self.fd = fd
                        self.dest = dest

                    def fileno(self):
                        return self.fd.fileno()

                    #        empty = True
                    #        errbuf = ''
                    #
                    #        p.stdin.close()
                    #        s_in = [sfd(p.stdout, sys.stdout),
                    #                sfd(p.stderr, sys.stderr)]
                    #
                    #        for s in s_in:
                    #          flags = fcntl.fcntl(s.fd, fcntl.F_GETFL)
                    #          fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
                    #
                    #        while s_in:
                    #          in_ready, _out_ready, _err_ready = select.select(s_in, [], [])
                    #          for s in in_ready:
                    #            buf = s.fd.read(4096)
                    #            if not buf:
                    #              s.fd.close()
                    #              s_in.remove(s)
                    #              continue
                    #
                    #            if not opt.verbose:
                    #              if s.fd != p.stdout:
                    #                errbuf += buf
                    #                continue
                    #
                    #            if empty:
                    #              if first:
                    #                first = False
                    #              else:
                    #                out.nl()
                    #              out.project('project %s/', project.relpath)
                    #              out.nl()
                    #              out.flush()
                    #              if errbuf:
                    #                sys.stderr.write(errbuf)
                    #                sys.stderr.flush()
                    #                errbuf = ''
                    #              empty = False
                    #
                    #            s.dest.write(buf)
                    #            s.dest.flush()

            r = p.wait()
            if r != 0:
                if r != rc:
                    rc = r
                if opt.abort_on_errors:
                    print("error: %s: Aborting due to previous error" % project.relpath,
                          file=sys.stderr)
                    sys.exit(r)
        if rc != 0:
            sys.exit(rc)