def macos_extra(c):
    """
    Set up optional MongoDB development utilities on MacOS

    :param c:
    :return:
    """
    print_bold('Installing ninja')
    c.run('brew install --upgrade ninja')

    modules_dir = str(kHome / 'mongo' / 'src' / 'mongo' / 'db' / 'modules')
    c.run(f'mkdir -p {modules_dir}')

    with c.cd(modules_dir):
        # Ignore errors since ninja may already exist.
        c.run(
            'git clone https://github.com/RedBeard0531/mongo_module_ninja ninja',
            warn=True)
    with c.cd(str(kHome / 'mongo')):
        ninja_cmd = 'python buildscripts/scons.py CC=clang CXX=clang++ '
        ninja_cmd += 'CCFLAGS=-Wa,--compress-debug-sections '
        ninja_cmd += 'MONGO_VERSION=\'0.0.0\' MONGO_GIT_HASH=\'unknown\' '
        ninja_cmd += 'VARIANT_DIR=ninja --modules=ninja build.ninja'
        c.run(ninja_cmd)

    print_bold('Installing CLion')

    # Ignore errors since CLion already exists.
    c.run('brew cask install clion', warn=True)
    with c.cd(kPackageDir):
        c.run('cp mongo-cmakelists.txt ~/mongo/CMakeLists.txt')
Exemple #2
0
def commit(c):
    """
    Step 4: Wrapper around git commit to automatically add changes and fill in the ticket number in the commit message.
    """
    init(c)

    commit_num, branch_num = _get_ticket_numbers(c)

    cache = _load_cache(c)

    project = cache.get(branch_num, {}).get('project', 'server')

    c.run('git add -u')

    if project == 'server':
        c.run('git add src/')
        c.run('git add jstests/')

    if commit_num == branch_num:
        c.run('git commit --amend --no-edit')
    else:
        raw_commit_msg = input('Please enter the commit message (without ticket number): ')
        c.run(f'git commit -m "{project.upper()}-{branch_num} {raw_commit_msg}"')

    print_bold('Committed local changes')
Exemple #3
0
def self_update(c):
    """
    Update this tool.
    """
    print_bold('Updating MongoDB Server Commandline Tool...')
    with c.cd(str(kPackageDir)):
        c.run('git fetch', warn=False, hide='both')
        c.run('git rebase', warn=False, hide='both')

        # Ignore failures if we can't install or upgrade with pip3.
        c.run('pip3 install --upgrade .', warn=True)
        _post_update_steps(c)
Exemple #4
0
def open_jira(c, ticket=None):
    """
    Open the Jira link for the ticket you're currently working on.

    :param ticket: ticket number without project name (Default: your current git branch)
    """
    commit_num, branch_num = _get_ticket_numbers(c)

    cache = _load_cache(c)

    project = cache.get(branch_num, {}).get('project', 'server')

    print_bold(f'opening Jira for ticket {project.upper()}-{branch_num}')

    if not ticket:
        ticket = branch_num

    webbrowser.open(f'https://jira.mongodb.org/browse/{project.upper()}-{ticket}')
Exemple #5
0
def get_jira():
    global jira_cli
    if not jira_cli:
        try:
            jira_cli = jira.JIRA(
                options={'server': 'https://jira.mongodb.org'},
                basic_auth=(jira_username, jira_password),
                validate=True,
                logging=False
            )
        except jira.exceptions.JIRAError as e:
            if e.status_code == '403' or e.status_code == 403:
                print('CAPTCHA required, please log out and log back into Jira')
                return None
        except:
            print('Failed to connect to Jira')

    print_bold('Updating ticket in Jira. Please wait...')
    return jira_cli
Exemple #6
0
def new(c, ticket_number, branch='master', project='server'):
    """
    Step 1: Create or switch to the branch for a ticket.

    :param ticket_number: Digits of the Jira ticket.
    :param branch: Base branch for this ticket. Default: master.
    :param project: Jira project. Default: server.
    """
    init(c)
    ticket_number = _strip_proj(ticket_number)

    project = project.lower()

    res = c.run(f'git rev-parse --verify {project}{ticket_number}', warn=True, hide=True)
    if res.return_code == 0:
        c.run(f'git checkout {project}{ticket_number}', hide='both')
    else:
        print_bold(f'Updating {branch} to latest and creating new branch: server{ticket_number}')
        c.run(f'git checkout {branch}')
        _git_refresh(c, branch)
        c.run(f'git checkout -B {project}{ticket_number}', hide='both')

        jirac = get_jira()
        if jirac:
            issue = jirac.issue(f'{project.upper()}-{ticket_number}')
            if issue.fields.status.id == '1':  # '1' = Open
                print_bold(
                    f'Transitioning {project.upper()}-{ticket_number} in Jira to "In Progress"')
                jirac.transition_issue(issue, '4')  # '4' = Start Progress
            else:
                print_bold(
                    f'{project.upper()}-{ticket_number} in Jira is not in "Open" status, not updating Jira')

    cache = _load_cache(c)
    if ticket_number not in cache:
        cache[ticket_number] = {}

    cache[ticket_number]['project'] = project
    _store_cache(c, cache)
def macos(c):
    """
    Set up MongoDB core server development environment on MacOS. Please run this task with "-w"

    set $EDITOR
    clang-format, eslint, pylinter
    git credentials: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
    git checkout optionally enterprise module repos,
    ssh keys
    evergreen credentials (requires manual copy and paste from browser https://evergreen.mongodb.com/settings),
        also turn on email/Slack alerts for patch builds
    evergreen default build variants and tasks, tasks vary by team

    """
    get_passwords(c)

    print_bold('Checking sudo password is correct')
    c.sudo('ls', warn=False, hide='both', password=sudo_password)

    print_bold('Setting Evergreen Configuration')
    _set_evergreen_config(c)

    print_bold('Creating SSH keys')
    _create_ssh_keys(c)

    print_bold(
        f'Checking out the following git repositories: {kRepositoryURLs}')
    for name, url in kRepositoryURLs.items():
        _checkout_repo(c, name,
                       url)  # TODO: allow the user to specify clone location.

    print_bold('Installing git hooks for the mongo repo')
    _install_git_hook(c)

    print_bold(f'Creating /data/db')
    _create_db_dir(c)

    print_bold('Checking HomeBrew is installed')
    # res = c.run('brew --version', hide='both')
    # _check_homebrew_exists(c)

    print_bold('Installing Text Editor')
    _install_editor(c)

    print_bold('Setting Evergreen Configuration')
    _set_evergreen_config(c)

    # TODO: remove this step when the toolchain Python works.
    print_bold('Installing python')
    c.run('brew install --upgrade python3 python2',
          hide='both')  # Ignore errors
    c.run('pip3 install --upgrade pip setuptools', warn=False, hide='both')
    c.run('pip2 install --upgrade pip setuptools', warn=False, hide='both')
    with c.cd(f'{kHome / "mongo"}'):
        c.run('pip3 install -r buildscripts/requirements.txt'
              )  # Ignore permission errors.
        c.run('pip2 install -r buildscripts/requirements.txt'
              )  # Ignore permission errors.
        c.run('pip2 install regex', warn=False)

    print_bold('Installing MongoDB Toolchain')
    _install_binary(c,
                    kToolchainURL,
                    f'toolchain.tar.gz',
                    'mongodbtoolchain',
                    kOptDir,
                    untar=True)

    print_bold('Installing Evergreen Command Line Tool')
    _install_binary(c,
                    kEvgToolURL,
                    'evergreen',
                    'evergreen',
                    pathlib.Path.home() / 'bin',
                    untar=False)
    c.run(f'chmod +x {pathlib.Path.home() / "bin" / "evergreen"}'
          )  # Work around 'evergreen' not executable by default.

    print_bold('Setting configurations and environment variables.')
    _set_env_vars(c)
Exemple #8
0
def finalize(c, push=False, branch='master'):
    """
    Step 7: Finalize your changes. Merge them with the base branch and optionally push upstream.

    :param push: git push your changes (Default: False)
    :param branch: the base branch for your changes. (Default: master)
    """
    init(c)

    commit_num, branch_num = _get_ticket_numbers(c)
    if commit_num != branch_num:
        print('[ERROR] Please commit your local changes before finalizing.')
        sys.exit(1)

    feature_branch = c.run('git rev-parse --abbrev-ref HEAD', hide=True).stdout

    _git_refresh(c, branch)

    res = c.run(f'git rebase {branch}', warn=True)
    if res.return_code != 0:
        print(f'[ERROR] Did not rebase cleanly onto {branch}, please manually run: git rebase {branch}')
        c.run(f'git checkout {feature_branch}')
        sys.exit(1)
    c.run(f'git checkout {branch}')
    c.run(f'git merge {feature_branch}')

    push_cmd = 'git push'
    if not push:
        push_cmd += ' -n'

    res = c.run(push_cmd, warn=True)
    if res.return_code != 0:
        print('[ERROR] git push failed!')
        c.run(f'git checkout {feature_branch}')
        sys.exit(1)

    cache = _load_cache(c)
    project = cache.get(branch_num, {}).get('project', 'server')

    if push:
        if branch_num in cache:
            del cache[branch_num]
            _store_cache(c, cache)

        c.run(f'git branch -d {feature_branch}')

        # TODO: Update Jira and close CR.
        # jirac = get_jira()
        # if jirac:
        #     ticket = get_jira().issue(f'SERVER-{branch_num}')
        #
        #     # Transition Ticket
        #     if ticket.fields.status.id == '10018':  # '10018' = In Code Review.
        #         print_bold(f'Transitioning SERVER-{branch_num} in Jira to "Closed"')
        #         jirac.transition_issue(ticket, '981')  # '981' = Close Issue
        #     else:
        #         print_bold(
        #             f'SERVER-{branch_num} in Jira is not in "In Code Review" status, not updating Jira')
        # else:
        #     print_bold(f'Please manually add a link of your codereview to: '
        #                f'https://jira.mongodb.org/browse/SERVER-{commit_num}')

    print_bold(
        'Please remember to close this issue and add a comment of your patch build link '
        'if you haven\'t already. The comment should have "Developer" visibility')
    print_bold(f'https://jira.mongodb.com/browse/{project}-{branch_num}')

    self_update(c)
Exemple #9
0
def review(c, new_cr=False, browser=True):
    """
    Step 5: Put your code up for code review.

    :param new_cr: whether to create a new code review. Use it if you have multiple CRs for the same ticket. (Default: False)
    :param no_browser: Set it if you're running this script in a ssh terminal.
    """
    init(c)
    commit_num, branch_num = _get_ticket_numbers(c)
    if commit_num != branch_num:
        print( '[ERROR] Please commit your local changes before submitting them for review.')
        sys.exit(1)

    cache = _load_cache(c)
    if commit_num not in cache:
        cache[commit_num] = {}

    issue_number = cache[commit_num].get('cr', None)
    project = cache[commit_num].get('project', 'server')

    commit_msg = c.run('git log --oneline -1 --pretty=%s', hide=True).stdout.strip()

    cmd = f'python2 {kPackageDir / "upload.py"} --rev HEAD~1 --nojira -y '

    if project == 'server':
        cmd += '--git_similarity 90 --check-clang-format --check-eslint'

    if issue_number and not new_cr:
        cmd += f' -i {issue_number}'
    else:
        # New issue, add title.
        cmd += f' -t "{commit_msg}"'

    if not browser:
        cmd += ' --no_oauth2_webbrowser'

    print('Authenticating with OAuth2... If your browser did not open, press enter')
    res = c.run(cmd, hide='stdout')

    match = re.search('Issue created. URL: (.*)', res.stdout)
    if match:
        url = match.group(1)
        issue_number = url.split('/')[-1]

        jirac = get_jira()
        if jirac:
            ticket = get_jira().issue(f'{project.upper()}-{commit_num}')

            # Transition Ticket
            if ticket.fields.status.id == '3':  # '3' = In Progress.
                print_bold(f'Transitioning {project.upper()}-{branch_num} in Jira to "Start Code Review"')
                jirac.transition_issue(ticket, '761')  # '4' = Start Code Review

                # Add comment.
                get_jira().add_comment(
                    ticket,
                    f'CR: {url}',
                    visibility={'type': 'role', 'value': 'Developers'}
                )
            else:
                print_bold(
                    f'SERVER-{branch_num} in Jira is not in "In Progress" status, not updating Jira')
        else:
            print_bold(f'Please manually add a link of your codereview to: '
                       f'https://jira.mongodb.org/browse/{project.upper()}-{commit_num}')

    if not issue_number:
        print('[ERROR] Something went wrong, no CR issue number was found')
        sys.exit(1)

    cache[commit_num]['cr'] = issue_number

    _store_cache(c, cache)

    url = f'https://mongodbcr.appspot.com/{issue_number}'
    print_bold(f'Opening code review page: {url}')
    webbrowser.open(url)