Beispiel #1
0
def pre_commit():
    """
    This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes no parameter, and is
    invoked before obtaining the proposed commit log message and making a commit.
    Exiting with non-zero status from this script causes the git commit to abort.
    """

    repository = git.Repo()

    user_configuration = config.UserConfiguration()

    logger = output.get_root_logger('pre-commit')
    logger.setLevel(user_configuration.verbosity)
    logger.debug('Starting Pre-Commit Hook')
    logger.debug('Repository Working Dir: %s', repository.working_dir)

    try:
        repository_configuration = config.load_repository_configuration(repository.working_dir)
    except ValueError as e:
        logger.error(e)
        raise click.Abort
    logger.debug('Loaded repository configuration: %s', repository_configuration['CONFIG_FILE'])

    staging_area = staging.StagingArea(repository)
    logger.debug('Changed Files: %d', len(staging_area.changes))

    failed_checks = checks.run_checks('pre_commit', user_configuration, repository_configuration, staging_area)

    if failed_checks:
        s = '' if failed_checks == 1 else 's'
        logger.error('%d check%s failed', failed_checks, s)

    sys.exit(failed_checks)
Beispiel #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)
Beispiel #3
0
def commit_msg(message_file_path):
    """
    This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes a single parameter,
    the name of the file that holds the proposed commit log message.
    Exiting with non-zero status causes the git commit to abort.

    :param message_file_path: the name of the file that holds the proposed commit log message
    :type message_file_path: string
    """

    repository = git.Repo()
    branch = repository.active_branch.name

    user_configuration = config.UserConfiguration()
    logger = output.get_root_logger('commit-msg')
    logger.setLevel(user_configuration.verbosity)

    logger.debug('Starting Commit-Msg Hook')
    logger.debug('Path to commit message file: %s', message_file_path)

    logger.debug('Repository Working Dir: %s', repository.working_dir)
    logger.debug('Current branch: %s', branch)

    try:
        repository_configuration = config.load_repository_configuration(
            repository.working_dir)
    except ValueError as e:
        logger.error(str(e))
        raise click.Abort
    logger.debug('Loaded repository configuration: %s',
                 repository_configuration['CONFIG_FILE'])

    logger.debug('Opening commit message file')
    try:
        with open(message_file_path) as message_file:
            str_commit_message = message_file.read()
    except IOError:
        logger.error('Commit message file (%s) not found', message_file_path)
        raise click.Abort
    logger.debug('Commit Message: %s', str_commit_message)

    commit_message = message.CommitMessage(branch, str_commit_message)

    failed_checks = checks.run_checks('commit_msg', user_configuration,
                                      repository_configuration, commit_message)

    if failed_checks:
        s = '' if failed_checks == 1 else 's'
        logger.error('%d check%s failed', failed_checks, s)

    sys.exit(failed_checks)
Beispiel #4
0
def commit_msg(message_file_path):
    """
    This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes a single parameter,
    the name of the file that holds the proposed commit log message.
    Exiting with non-zero status causes the git commit to abort.

    :param message_file_path: the name of the file that holds the proposed commit log message
    :type message_file_path: string
    """

    repository = git.Repo()
    branch = repository.active_branch.name

    user_configuration = config.UserConfiguration()
    logger = output.get_root_logger('commit-msg')
    logger.setLevel(user_configuration.verbosity)

    logger.debug('Starting Commit-Msg Hook')
    logger.debug('Path to commit message file: %s', message_file_path)

    logger.debug('Repository Working Dir: %s', repository.working_dir)
    logger.debug('Current branch: %s', branch)

    try:
        repository_configuration = config.load_repository_configuration(repository.working_dir)
    except ValueError as e:
        logger.error(str(e))
        raise click.Abort
    logger.debug('Loaded repository configuration: %s', repository_configuration['CONFIG_FILE'])

    logger.debug('Opening commit message file')
    try:
        with open(message_file_path) as message_file:
            str_commit_message = message_file.read()
    except IOError:
        logger.error('Commit message file (%s) not found', message_file_path)
        raise click.Abort
    logger.debug('Commit Message: %s', str_commit_message)

    commit_message = message.CommitMessage(branch, str_commit_message)

    failed_checks = checks.run_checks('commit_msg', user_configuration, repository_configuration, commit_message)

    if failed_checks:
        s = '' if failed_checks == 1 else 's'
        logger.error('%d check%s failed', failed_checks, s)

    sys.exit(failed_checks)
Beispiel #5
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
Beispiel #6
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)
def pre_commit():
    """
    This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes no parameter, and is
    invoked before obtaining the proposed commit log message and making a commit.
    Exiting with non-zero status from this script causes the git commit to abort.
    """

    repository = git.Repo()

    user_configuration = config.UserConfiguration()

    logger = output.get_root_logger('pre-commit')
    logger.setLevel(user_configuration.verbosity)
    logger.debug('Starting Pre-Commit Hook')
    logger.debug('Repository Working Dir: %s', repository.working_dir)

    try:
        repository_configuration = config.load_repository_configuration(
            repository.working_dir)
    except ValueError as e:
        logger.error(e)
        raise click.Abort
    logger.debug('Loaded repository configuration: %s',
                 repository_configuration['CONFIG_FILE'])

    staging_area = staging.StagingArea(repository)
    logger.debug('Changed Files: %d', len(staging_area.changes))

    failed_checks = checks.run_checks('pre_commit', user_configuration,
                                      repository_configuration, staging_area)

    if failed_checks:
        s = '' if failed_checks == 1 else 's'
        logger.error('%d check%s failed', failed_checks, s)

    sys.exit(failed_checks)
Beispiel #8
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