Ejemplo n.º 1
0
def test_get_specification():
    spec = get_specification('something')
    assert not spec.valid

    spec = get_specification('http://spec.url')
    assert spec.scheme == u'http'

    spec = get_specification('https://spec.url')
    assert spec.scheme == u'https'
Ejemplo n.º 2
0
def cmd(verbose, revision_range):
    """
    Verifies if the commit messages in a range of revisions have valid specifications.

    This command takes the same revision ranges as ``git log`` to specify which commits are processed

    When using the verbose mode merge commits are printed otherwise they are simply ignored
    """

    repository = git.get_repository()
    if not repository:
        click.secho('This command must be executed inside a repository.',
                    fg='red',
                    bold=True)
        raise click.Abort
    commits = list(repository.iter_commits(revision_range))
    invalid = 0
    options = config.load_repository_configuration(repository.working_dir).get(
        'specification', {})
    allowed_schemes = options.get('allowed_schemes', ['https', 'offline'])
    allowed_formats = options.get('allowed_formats', {'uri'})

    for commit in commits:
        is_a_merge = len(commit.parents) > 1
        if is_a_merge and not verbose:
            continue
        short_hash = commit.hexsha[:7]
        first_line = commit.message.splitlines()[0]
        # TODO make configurable
        specification = specifications.get_specification(
            commit.message, allowed_formats, allowed_schemes)
        if specification.valid:
            click.secho(' ✔ ', bg='green', fg='white', nl=False)
        elif is_a_merge:
            click.secho('   ', fg='yellow', nl=False)
        else:
            invalid += 1
            click.secho(' ✘ ', bg='red', fg='white', nl=False)
        click.secho(' {} '.format(short_hash),
                    fg='white' if is_a_merge else 'yellow',
                    nl=False,
                    dim=is_a_merge)
        click.secho(first_line, dim=is_a_merge)

    if invalid:
        if invalid == 1:
            message = '1 commit has invalid specification.'
        else:
            message = '{n} commits have invalid specifications.'.format(
                n=invalid)
        click.secho(message, fg='red', bold=True)

    sys.exit(invalid)
Ejemplo n.º 3
0
def cmd(reference='HEAD'):
    """
    Opens the specification for commit
    """

    repository = git.get_repository()
    if not repository:
        click.secho('This command must be executed inside a repository.', fg='red', bold=True)
        raise click.Abort

    options = config.load_repository_configuration(repository.working_dir).get('specification', {})
    allowed_schemes = options.get('allowed_schemes', ['https', 'offline'])
    allowed_formats = options.get('allowed_formats', {'uri'})

    try:
        commit = repository.commit(reference)
    except git.BadName:
        click.secho("'{reference}' is not a valid commit reference.".format(reference=reference), fg='red', bold=True)
        raise click.Abort

    specification = specifications.get_specification(commit.message, allowed_formats, allowed_schemes)
    specification_format = specification.format

    if not specification_format:
        click.secho("That commit doesn't have a valid specification.", fg='red', bold=True)
        raise click.Abort

    if specification_format == 'uri':
        url = specification.identifier
    elif specification_format == 'github':
        origin = repository.remote('origin')  # type: git.remote.Remote
        git_url = origin.config_reader.get('url')
        repository = github.extract_repository_from_url(git_url)
        if repository:
            issue = github.extract_issue_number(specification.identifier)
            url = 'https://github.com/{repository}/issues/{issue}'.format(**locals())
        else:
            click.secho("{} is not a github repository.".format(git_url), fg='red', bold=True)
            raise click.Abort
    else:
        url = None

    if url:
        click.secho('Opening {}'.format(url))
        webbrowser.open(url)
    else:
        click.secho("{} specifications aren't supported yet.".format(specification_format), fg='red', bold=True)
        raise click.Abort
Ejemplo n.º 4
0
def cmd(verbose, revision_range):
    """
    Verifies if the commit messages in a range of revisions have valid specifications.

    This command takes the same revision ranges as ``git log`` to specify which commits are processed

    When using the verbose mode merge commits are printed otherwise they are simply ignored
    """

    repository = git.get_repository()
    if not repository:
        click.secho('This command must be executed inside a repository.', fg='red', bold=True)
        raise click.Abort
    commits = list(repository.iter_commits(revision_range))
    invalid = 0
    options = config.load_repository_configuration(repository.working_dir).get('specification', {})
    allowed_schemes = options.get('allowed_schemes', ['https', 'offline'])
    allowed_formats = options.get('allowed_formats', {'uri'})

    for commit in commits:
        is_a_merge = len(commit.parents) > 1
        if is_a_merge and not verbose:
            continue
        short_hash = commit.hexsha[:7]
        first_line = commit.message.splitlines()[0]
        # TODO make configurable
        specification = specifications.get_specification(commit.message, allowed_formats, allowed_schemes)
        if specification.valid:
            click.secho(' ✔ ', bg='green', fg='white', nl=False)
        elif is_a_merge:
            click.secho('   ', fg='yellow', nl=False)
        else:
            invalid += 1
            click.secho(' ✘ ', bg='red', fg='white', nl=False)
        click.secho(' {} '.format(short_hash), fg='white' if is_a_merge else 'yellow', nl=False, dim=is_a_merge)
        click.secho(first_line, dim=is_a_merge)

    if invalid:
        if invalid == 1:
            message = '1 commit has invalid specification.'
        else:
            message = '{n} commits have invalid specifications.'.format(n=invalid)
        click.secho(message, fg='red', bold=True)

    sys.exit(invalid)
Ejemplo n.º 5
0
def check(user_configuration, repository_configuration, commit_message):
    """
    Check if the specification is valid.

    :param user_configuration: User specific configuration
    :type user_configuration: git_hooks.common.config.UserConfiguration
    :param repository_configuration: Repository specific configuration
    :type repository_configuration: dict
    :param commit_message:
    :type commit_message: git_hooks.models.message.CommitMessage
    :return: If check passed or not
    :rtype: git_hooks.checks.CheckResult
    """

    logger = output.get_sub_logger('commit-msg', 'specification')
    logger.debug('Starting specification check...')
    logger.debug('Commit Message: %s', commit_message.message)

    if commit_message.message.startswith('Merge'):
        logger.debug("Commit is a merge, ignoring.")
        raise checks.CheckIgnore

    check_options = repository_configuration.get('specification', {})
    allowed_schemes = check_options.get('allowed_schemes',
                                        ['https', 'offline'])
    allowed_formats = check_options.get('allowed_formats', {'uri'})
    logger.debug("Allowed schemes: %s", allowed_schemes)

    result = checks.CheckResult()
    specification = specifications.get_specification(commit_message.message,
                                                     allowed_formats,
                                                     allowed_schemes)
    is_valid_uri = specification.valid

    logger.debug('Specification: %s', specification)
    logger.debug("Specification is valid: %s", is_valid_uri)

    result.successful = is_valid_uri
    if not is_valid_uri:
        result.add_detail(
            '{spec} is not a valid specification.'.format(spec=specification))

    return result
Ejemplo n.º 6
0
def check(user_configuration, repository_configuration, commit_message):
    """
    Check if the specification is valid.

    :param user_configuration: User specific configuration
    :type user_configuration: git_hooks.common.config.UserConfiguration
    :param repository_configuration: Repository specific configuration
    :type repository_configuration: dict
    :param commit_message:
    :type commit_message: git_hooks.models.message.CommitMessage
    :return: If check passed or not
    :rtype: git_hooks.checks.CheckResult
    """

    logger = output.get_sub_logger("commit-msg", "specification")
    logger.debug("Starting specification check...")
    logger.debug("Commit Message: %s", commit_message.message)

    if commit_message.message.startswith("Merge"):
        logger.debug("Commit is a merge, ignoring.")
        raise checks.CheckIgnore

    check_options = repository_configuration.get("specification", {})
    allowed_schemes = check_options.get("allowed_schemes", ["https", "offline"])
    allowed_formats = check_options.get("allowed_formats", {"uri"})
    logger.debug("Allowed schemes: %s", allowed_schemes)

    result = checks.CheckResult()
    specification = specifications.get_specification(commit_message.message, allowed_formats, allowed_schemes)
    is_valid_uri = specification.valid

    logger.debug("Specification: %s", specification)
    logger.debug("Specification is valid: %s", is_valid_uri)

    result.successful = is_valid_uri
    if not is_valid_uri:
        result.add_detail("{spec} is not a valid specification.".format(spec=specification))

    return result
Ejemplo n.º 7
0
def cmd(reference='HEAD'):
    """
    Opens the specification for commit
    """

    repository = git.get_repository()
    if not repository:
        click.secho('This command must be executed inside a repository.',
                    fg='red',
                    bold=True)
        raise click.Abort

    options = config.load_repository_configuration(repository.working_dir).get(
        'specification', {})
    allowed_schemes = options.get('allowed_schemes', ['https', 'offline'])
    allowed_formats = options.get('allowed_formats', {'uri'})

    try:
        commit = repository.commit(reference)
    except git.BadName:
        click.secho("'{reference}' is not a valid commit reference.".format(
            reference=reference),
                    fg='red',
                    bold=True)
        raise click.Abort

    specification = specifications.get_specification(commit.message,
                                                     allowed_formats,
                                                     allowed_schemes)
    specification_format = specification.format

    if not specification_format:
        click.secho("That commit doesn't have a valid specification.",
                    fg='red',
                    bold=True)
        raise click.Abort

    if specification_format == 'uri':
        url = specification.identifier
    elif specification_format == 'github':
        origin = repository.remote('origin')  # type: git.remote.Remote
        git_url = origin.config_reader.get('url')
        repository = github.extract_repository_from_url(git_url)
        if repository:
            issue = github.extract_issue_number(specification.identifier)
            url = 'https://github.com/{repository}/issues/{issue}'.format(
                **locals())
        else:
            click.secho("{} is not a github repository.".format(git_url),
                        fg='red',
                        bold=True)
            raise click.Abort
    else:
        url = None

    if url:
        click.secho('Opening {}'.format(url))
        webbrowser.open(url)
    else:
        click.secho("{} specifications aren't supported yet.".format(
            specification_format),
                    fg='red',
                    bold=True)
        raise click.Abort