Beispiel #1
0
 def __show_similar_branches(branch, branches):
     if len(branches) > 0:
         info('Did you mean:')
         close_branches = most_similar(branch, branches)[:5]
         for idx in range(len(close_branches)):
             cb = close_branches[idx][0]
             if idx == 0:
                 cb = COLORS.OKGREEN + cb
             else:
                 cb = COLORS.CYAN + cb
             print(' - {}{}'.format(cb, COLORS.ENDC))
Beispiel #2
0
 def __init_submodules():
     r = check_output(['git', '-C', OPENPILOT_PATH, 'submodule', 'status'])
     if len(r.output):
         info('Submodules detected, reinitializing!')
         r0 = check_output([
             'git', '-C', OPENPILOT_PATH, 'submodule', 'deinit', '--all',
             '-f'
         ])
         r1 = check_output([
             'git', '-C', OPENPILOT_PATH, 'submodule', 'update', '--init',
             '--recursive'
         ])
         if not r0.success or not r1.success:
             error('Error reinitializing submodules for this branch!')
         else:
             return True
     return False
Beispiel #3
0
  def _reload():
    info('This will kill the current openpilot tmux session, set up a new one, and relaunch openpilot.')
    info('Confirm you would like to continue')
    if not is_affirmative():
      error('Aborting!')
      return

    r = check_output('tmux kill-session -t comma')
    if r.success:
      info('Killed the current openpilot session')
    else:
      warning('Error killing current openpilot session, continuing...')

    # Command below thanks to mlp
    r = check_output(['tmux', 'new', '-s', 'comma', '-d',
                      "echo $$ > /dev/cpuset/app/tasks;"  # add pid of current shell to app cpuset
                      "echo $PPID > /dev/cpuset/app/tasks;"  # (our parent, tmux, also gets all the cores)
                      "/data/openpilot/launch_openpilot.sh"])
    if r.success:
      success('Succesfully started a new tmux session for openpilot!')
      success('Type {}tmux a{} to attach to it'.format(COLORS.FAIL, COLORS.SUCCESS))
Beispiel #4
0
    def _init(self):
        if os.path.isdir('/data/community/forks'):
            shutil.rmtree('/data/community/forks')  # remove to save space
        if self.fork_params.get('setup_complete'):
            if os.path.exists(OPENPILOT_PATH):
                r = check_output(
                    ['git', '-C', OPENPILOT_PATH, 'remote', 'show'])
                if self.comma_origin_name in r.output.split(
                        '\n'
                ):  # sign that we're set up correctly todo: check all forks exist as remotes
                    return True
            self.fork_params.put(
                'setup_complete', False
            )  # renamed origin -> commaai does not exist, restart setup
            self.fork_params.reset()
            warning(
                'There was an error with your clone of commaai/openpilot, restarting initialization!'
            )

        info(
            'To set up emu fork management we will clone commaai/openpilot into {}'
            .format(OPENPILOT_PATH))
        info('Confirm you would like to continue')
        if not is_affirmative():
            error('Stopping initialization!')
            return

        # backup openpilot here to free up /data/openpilot
        if os.path.exists(OPENPILOT_PATH):
            bak_dir = '{}.bak'.format(OPENPILOT_PATH)
            idx = 0
            while os.path.exists(bak_dir):
                bak_dir = '{}{}'.format(bak_dir, idx)
                idx += 1
            shutil.move(OPENPILOT_PATH, bak_dir)
            success('Backed up your current openpilot install to {}'.format(
                bak_dir))

        info('Cloning commaai/openpilot into {}, please wait...'.format(
            OPENPILOT_PATH))
        r = run([
            'git', 'clone', '-b', self.comma_default_branch, GIT_OPENPILOT_URL,
            OPENPILOT_PATH
        ])  # default to stock/release2 for setup
        if not r:
            error('Error while cloning, please try again')
            return

        # rename origin to commaai so it's easy to switch to stock without any extra logic for url checking, etc
        r = check_output([
            'git', '-C', OPENPILOT_PATH, 'remote', 'rename', 'origin',
            self.comma_origin_name
        ])
        if not r.success:
            error(r.output)
            return

        # rename release2 to commaai_release2 to align with emu fork standards
        r = check_output([
            'git', '-C', OPENPILOT_PATH, 'branch', '-m',
            f'{self.comma_origin_name}_{self.comma_default_branch}'
        ])
        if not r.success:
            error(r.output)
            return

        # set git config push.default to `upstream` to remove differently named remote branch warning when pushing
        check_output([
            'git', '-C', OPENPILOT_PATH, 'config', 'push.default', 'upstream'
        ])  # not game breaking if this fails

        # remember username and password of user for pushing
        check_output([
            'git', '-C', OPENPILOT_PATH, 'config', 'credential.helper',
            'cache --timeout=1440'
        ])  # cache for a day

        success('Fork management set up successfully! You\'re on {}/{}'.format(
            self.comma_origin_name, self.comma_default_branch))
        success(
            'To get started, try running: {}emu fork switch (username) [-b BRANCH]{}'
            .format(COLORS.RED, COLORS.ENDC))
        self.__add_fork(self.comma_origin_name, self.comma_default_branch)
        self.fork_params.put('setup_complete', True)
        self.fork_params.put('current_fork', self.comma_origin_name)
        self.fork_params.put('current_branch', self.comma_default_branch)
        return True
Beispiel #5
0
    def _switch(self):
        if not self._init():
            return
        flags = self.get_flags('switch')
        if flags.username is flags.branch is None:  # since both are non-required we need custom logic to check user supplied sufficient args/flags
            error('You must supply either username or branch or both')
            self._help('switch')
            return

        username = flags.username
        branch = flags.branch
        repo_name = flags.repo
        force_switch = flags.force
        if username is None:  # branch is specified, so use current checked out fork/username
            _current_fork = self.fork_params.get('current_fork')
            if _current_fork is not None:  # ...if available
                info('Assuming current fork for username: {}'.format(
                    COLORS.SUCCESS + _current_fork + COLORS.ENDC))
                username = _current_fork
            else:
                error(
                    'Current fork is unknown, please switch to a fork first before switching between branches!'
                )
                return

        username = username.lower()
        remote_info = self.__get_remote_info(username)
        if remote_info is not None:  # user entered an alias (ex. stock, dragonpilot)
            username = remote_info.username

        installed_forks = self.fork_params.get('installed_forks')
        fork_in_params = True
        if username not in installed_forks:
            fork_in_params = False
            if remote_info is not None:
                remote_url = f'https://github.com/{username}/{remote_info.fork_name}'  # dragonpilot doesn't have a GH redirect
            else:  # for most forks, GH will redirect from /openpilot if user renames fork
                if repo_name is None:
                    repo_name = DEFAULT_REPO_NAME  # openpilot
                remote_url = f'https://github.com/{username}/{repo_name}'

            if not valid_fork_url(remote_url):
                error('Invalid username{}! {} does not exist'.format(
                    '' if flags.repo is None else ' or repository name',
                    remote_url))
                return

            r = check_output([
                'git', '-C', OPENPILOT_PATH, 'remote', 'add', username,
                remote_url
            ])
            if r.success and r.output == '':
                success('Remote added successfully!')
            elif r.success and REMOTE_ALREADY_EXISTS in r.output:
                # remote already added, update params
                info('Fork exists but wasn\'t in params, updating now...')
                self.__add_fork(username)
            else:
                error(r.output)
                return

        # fork has been added as a remote, switch to it
        if fork_in_params:
            info('Fetching {}\'s latest changes...'.format(COLORS.SUCCESS +
                                                           username +
                                                           COLORS.WARNING))
        else:
            info('Fetching {}\'s fork, this may take a sec...'.format(
                COLORS.SUCCESS + username + COLORS.WARNING))

        r = run(['git', '-C', OPENPILOT_PATH, 'fetch', username])
        if not r:
            error('Error while fetching remote, please try again')
            return

        self.__add_fork(username)
        self.__prune_remote_branches(username)
        r = check_output(
            ['git', '-C', OPENPILOT_PATH, 'remote', 'show', username])
        remote_branches, default_remote_branch = self.__get_remote_branches(r)
        if remote_branches is None:
            return

        if DEFAULT_BRANCH_START not in r.output:
            error('Error: Cannot find default branch from fork!')
            return

        if branch is None:  # user hasn't specified a branch, use remote's default branch
            if remote_info is not None:  # there's an overriding default branch specified
                remote_branch = remote_info.default_branch
                local_branch = '{}_{}'.format(remote_info.username,
                                              remote_branch)
            else:
                remote_branch = default_remote_branch  # for command to checkout correct branch from remote, branch is previously None since user didn't specify
                local_branch = '{}_{}'.format(username, default_remote_branch)
        else:
            if branch not in remote_branches:
                close_branches = most_similar(
                    branch, remote_branches
                )  # remote_branches is gauranteed to have at least 1 branch
                if close_branches[0][1] > 0.5:
                    branch = close_branches[0][0]
                    info(
                        'Unknown branch, checking out most similar: {}'.format(
                            COLORS.SUCCESS + branch + COLORS.WARNING))
                else:
                    error('The branch you specified does not exist!')
                    self.__show_similar_branches(
                        branch, remote_branches)  # if possible
                    return
            remote_branch = branch  # branch is now gauranteed to be in remote_branches
            local_branch = f'{username}_{branch}'

        # checkout remote branch and prepend username so we can have multiple forks with same branch names locally
        if remote_branch not in installed_forks[username][
                'installed_branches']:
            info('New branch! Tracking and checking out {} from {}'.format(
                local_branch, f'{username}/{remote_branch}'))
            command = [
                'git', '-C', OPENPILOT_PATH, 'checkout', '--track', '-b',
                local_branch, f'{username}/{remote_branch}'
            ]
        else:  # already installed branch, checking out fork_branch from f'{username}/{branch}'
            command = ['git', '-C', OPENPILOT_PATH, 'checkout', local_branch]

        if force_switch:
            command.append('-f')
        r = run(command)
        if not r:
            error(
                'Error while checking out branch, please try again or use flag --force'
            )
            return
        self.__add_branch(
            username, remote_branch
        )  # we can deduce fork branch from username and original branch f({username}_{branch})

        # reset to remote/branch just to ensure we checked out fully. if remote branch has been force pushed, this will also reset local to remote
        r = check_output([
            'git', '-C', OPENPILOT_PATH, 'reset', '--hard',
            f'{username}/{remote_branch}'
        ])
        if not r.success:
            error(r.output)
            return

        reinit_subs = self.__init_submodules()
        self.fork_params.put('current_fork', username)
        self.fork_params.put('current_branch', remote_branch)
        info('\n✅ Successfully checked out {}/{} as {}'.format(
            COLORS.SUCCESS + username, remote_branch + COLORS.WARNING,
            COLORS.SUCCESS + local_branch))
        if reinit_subs:
            success('✅ Successfully reinitialized submodules!')