Exemplo n.º 1
0
def main():
    """Run a git pre-commit lint-check."""
    # If we're a merge, don't try to do a lint-check.
    git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir'])
    if os.path.exists(os.path.join(git_root.strip(), 'MERGE_HEAD')):
        print "Skipping lint on merge..."
        return 0

    commit_message = open(sys.argv[1]).read()
    # Get rid of the comment lines, and leading and trailing whitespace.
    commit_message = _normalized_commit_message(commit_message)

    # If the commit message is empty or unchanged from the template, abort.
    if not commit_message:
        print "Aborting commit, empty commit message"
        return 1

    try:
        with open(os.path.join(git_root.strip(), 'commit_template')) as f:
            template = f.read()
    except (IOError, OSError):  # user doesn't have a commit template
        pass
    else:
        if commit_message == _normalized_commit_message(template):
            print "Aborting commit, commit message unchanged"
            return 1

    # Go through all modified or added files.
    try:
        subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'],
                                stderr=subprocess.STDOUT)
        parent = 'HEAD'
    except subprocess.CalledProcessError:
        parent = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'  # empty repo

    # Look at Added, Modified, and Renamed files.
    files = subprocess.check_output([
        'git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z',
        parent
    ])
    files_to_lint = files.strip('\0').split('\0')  # that's what -z is for
    if not files_to_lint or files_to_lint == ['']:
        return 0

    num_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    # For the phabricator workflow, some people always have the git
    # commit message be 'WIP', and put in the actual message at 'arc
    # diff' time.  We don't require a 'real' commit message in that
    # case.
    if not commit_message.lower().startswith('wip'):
        num_errors += hook_lib.lint_commit_message(commit_message)

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.git', 'commit.save'))
Exemplo n.º 2
0
def main():
    """Run a git pre-commit lint-check."""
    # If we're a merge, don't try to do a lint-check.
    git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir'])
    if os.path.exists(os.path.join(git_root.strip(), 'MERGE_HEAD')):
        print "Skipping lint on merge..."
        return 0

    commit_message = open(sys.argv[1]).read()
    # Get rid of the comment lines, and leading and trailing whitespace.
    commit_message = _normalized_commit_message(commit_message)

    # If the commit message is empty or unchanged from the template, abort.
    if not commit_message:
        print "Aborting commit, empty commit message"
        return 1

    try:
        with open(os.path.join(git_root.strip(), 'commit_template')) as f:
            template = f.read()
    except (IOError, OSError):       # user doesn't have a commit template
        pass
    else:
        if commit_message == _normalized_commit_message(template):
            print "Aborting commit, commit message unchanged"
            return 1

    # Go through all modified or added files.
    try:
        subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'],
                                stderr=subprocess.STDOUT)
        parent = 'HEAD'
    except subprocess.CalledProcessError:
        parent = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'  # empty repo

    # Look at Added, Modified, and Renamed files.
    files = subprocess.check_output(['git', 'diff', '--cached', '--name-only',
                                     '--diff-filter=AMR', '-z', parent])
    files_to_lint = files.strip('\0').split('\0')    # that's what -z is for
    if not files_to_lint or files_to_lint == ['']:
        return 0

    num_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    # For the phabricator workflow, some people always have the git
    # commit message be 'WIP', and put in the actual message at 'arc
    # diff' time.  We don't require a 'real' commit message in that
    # case.
    if not commit_message.lower().startswith('wip'):
        num_errors += hook_lib.lint_commit_message(commit_message)

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.git', 'commit.save'))
Exemplo n.º 3
0
def commit_msg_hook(commit_message_file):
    """Run a git pre-commit lint-check."""
    git_root = subprocess.check_output(['git', 'rev-parse',
                                        '--git-dir']).decode('utf-8')
    # read the commit message contents from the file specified
    commit_message = open(commit_message_file).read()
    # Get rid of the comment lines, and leading and trailing whitespace.
    commit_message = _normalized_commit_message(commit_message)

    # If the commit message is empty or unchanged from the template, abort.
    if not commit_message:
        six.print_("Aborting commit, empty commit message")
        return 1

    try:
        with open(os.path.join(git_root.strip(), 'commit_template')) as f:
            template = f.read()
    except (IOError, OSError):  # user doesn't have a commit template
        pass
    else:
        if commit_message == _normalized_commit_message(template):
            six.print_("Aborting commit, commit message unchanged")
            return 1

    # If we're a merge, don't try to do a lint-check.
    is_merge_commit = os.path.exists(
        os.path.join(git_root.strip(), 'MERGE_HEAD'))

    # Lint the commit message itself!
    # For the phabricator workflow, some people always have the git
    # commit message be 'WIP', and put in the actual message at 'arc
    # diff' time.  We don't require a 'real' commit message in that
    # case.
    num_errors = 0
    if not is_merge_commit and not commit_message.lower().startswith('wip'):
        num_errors += hook_lib.lint_commit_message(commit_message)

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.git', 'commit.save'))
Exemplo n.º 4
0
def main(commit_message_file):
    """Run a git pre-commit lint-check."""
    # If we're a merge, don't try to do a lint-check.
    git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir'])
    # read the commit message contents from the file specified
    commit_message = open(commit_message_file).read()
    # Get rid of the comment lines, and leading and trailing whitespace.
    commit_message = _normalized_commit_message(commit_message)

    # If the commit message is empty or unchanged from the template, abort.
    if not commit_message:
        print "Aborting commit, empty commit message"
        return 1

    try:
        with open(os.path.join(git_root.strip(), 'commit_template')) as f:
            template = f.read()
    except (IOError, OSError):       # user doesn't have a commit template
        pass
    else:
        if commit_message == _normalized_commit_message(template):
            print "Aborting commit, commit message unchanged"
            return 1

    is_merge_commit = os.path.exists(os.path.join(git_root.strip(),
                                                  'MERGE_HEAD'))

    # Go through all modified or added files.  We handle the case
    # separately if we're a merge or a 'normal' commit.  If we're a
    # merge, the pre-commit hook will only trigger if the merge had
    # conflicts; in this case we only care about linting the files
    # that were edited to resolve the conflict.  For a normal commit,
    # we of course care about linting *all* the changes files.
    if is_merge_commit:
        # I used to run
        #    git diff-tree -r --cc --name-only --diff-filter=AMR -z HEAD
        # but this wouldn't catch changes made to resolve conflicts, so
        # I try this other approach instead.  It doesn't properly ignore
        # files that have changed in both branches but the system was
        # able to do an automatic merge though, sadly.
        a_files = subprocess.check_output(['git', 'diff', '--cached',
                                         '--name-only', '--diff-filter=AMR',
                                         '-z', 'ORIG_HEAD'])
        b_files = subprocess.check_output(['git', 'diff', '--cached',
                                         '--name-only', '--diff-filter=AMR',
                                         '-z', 'MERGE_HEAD'])
        a_files = frozenset(a_files.strip('\0').split('\0'))
        b_files = frozenset(b_files.strip('\0').split('\0'))
        files_to_lint = list(a_files & b_files)
    else:
        # Look at Added, Modified, and Renamed files.
        # When no commit is specified, it defaults to HEAD which is
        # what we want.
        files = subprocess.check_output(['git', 'diff', '--cached',
                                         '--name-only', '--diff-filter=AMR',
                                         '-z'])
        files_to_lint = files.strip('\0').split('\0')  # that's what -z is for

    if not files_to_lint or files_to_lint == ['']:
        return 0

    lint_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    # For the phabricator workflow, some people always have the git
    # commit message be 'WIP', and put in the actual message at 'arc
    # diff' time.  We don't require a 'real' commit message in that
    # case.
    msg_errors = 0
    if not is_merge_commit and not commit_message.lower().startswith('wip'):
        msg_errors += hook_lib.lint_commit_message(commit_message)

    num_errors = lint_errors + msg_errors

    if lint_errors:
        recommendation = ('Running `arc lint` may help to autofix the errors.'
                          '\nUse "git recommit -a" when the errors'
                          ' are fixed, to re-use this commit message.')
    elif msg_errors:
        recommendation = ('Use "git commit -a --template .git/commit.save"'
                          ' to commit with a fixed message.')
    else:
        recommendation = None

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.git', 'commit.save'),
                                    recommendation=recommendation)
Exemplo n.º 5
0
def main(commit_message_file):
    """Run a git pre-commit lint-check."""
    # If we're a merge, don't try to do a lint-check.
    git_root = subprocess.check_output(
        ['git', 'rev-parse', '--git-dir']).decode('utf-8')
    # read the commit message contents from the file specified
    commit_message = open(commit_message_file).read()
    # Get rid of the comment lines, and leading and trailing whitespace.
    commit_message = _normalized_commit_message(commit_message)

    # If the commit message is empty or unchanged from the template, abort.
    if not commit_message:
        six.print_("Aborting commit, empty commit message")
        return 1

    try:
        with open(os.path.join(git_root.strip(), 'commit_template')) as f:
            template = f.read()
    except (IOError, OSError):       # user doesn't have a commit template
        pass
    else:
        if commit_message == _normalized_commit_message(template):
            six.print_("Aborting commit, commit message unchanged")
            return 1

    is_merge_commit = os.path.exists(os.path.join(
        git_root.strip(), 'MERGE_HEAD'))

    # Go through all modified or added files.  We handle the case
    # separately if we're a merge or a 'normal' commit.  If we're a
    # merge, the pre-commit hook will only trigger if the merge had
    # conflicts; in this case we only care about linting the files
    # that were edited to resolve the conflict.  For a normal commit,
    # we of course care about linting *all* the changes files.
    if is_merge_commit:
        # I used to run
        #    git diff-tree -r --cc --name-only --diff-filter=AMR -z HEAD
        # but this wouldn't catch changes made to resolve conflicts, so
        # I try this other approach instead.  It doesn't properly ignore
        # files that have changed in both branches but the system was
        # able to do an automatic merge though, sadly.
        a_files = subprocess.check_output(
            ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR',
             '-z', 'ORIG_HEAD']).decode('utf-8')
        b_files = subprocess.check_output(
            ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR',
             '-z', 'MERGE_HEAD']).decode('utf-8')
        a_files = frozenset(a_files.strip('\0').split('\0'))
        b_files = frozenset(b_files.strip('\0').split('\0'))
        files_to_lint = list(a_files & b_files)
    else:
        # Look at Added, Modified, and Renamed files.
        # When no commit is specified, it defaults to HEAD which is
        # what we want.
        files = subprocess.check_output(
            ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR',
             '-z']).decode('utf-8')
        files_to_lint = files.strip('\0').split('\0')  # that's what -z is for

    if not files_to_lint or files_to_lint == ['']:
        return 0

    lint_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    # For the phabricator workflow, some people always have the git
    # commit message be 'WIP', and put in the actual message at 'arc
    # diff' time.  We don't require a 'real' commit message in that
    # case.
    msg_errors = 0
    if not is_merge_commit and not commit_message.lower().startswith('wip'):
        msg_errors += hook_lib.lint_commit_message(commit_message)

    num_errors = lint_errors + msg_errors

    if lint_errors:
        recommendation = ('Running `arc lint` may help to autofix the errors.'
                          '\nUse "git recommit -a" when the errors'
                          ' are fixed, to re-use this commit message.')
    elif msg_errors:
        recommendation = ('Use "git commit -a --template .git/commit.save"'
                          ' to commit with a fixed message.')
    else:
        recommendation = None

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.git', 'commit.save'),
                                    recommendation=recommendation)
Exemplo n.º 6
0
    try:
        status_output = subprocess.check_output(['hg', 'status', '-a', '-m',
                                                 '--change', 'tip'])
    except subprocess.CalledProcessError, e:
        print >> sys.stderr, "Error calling 'hg status':", e
        return 1

    files_to_lint = []
    if status_output:
        for line in status_output.strip().split('\n'):
            # each line has the format "M path/to/filename.js"
            status, filename = line.split(' ', 1)
            files_to_lint.append(filename)

    num_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    commit_message = subprocess.check_output(['hg', 'tip',
                                              '--template', '{desc}'])
    num_errors += hook_lib.lint_commit_message(commit_message)

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.hg', 'commit.save'))


if __name__ == '__main__':
    suppress_lint = os.getenv('FORCE_COMMIT', '')
    if suppress_lint.lower() not in ('1', 'true'):
        sys.exit(main())
Exemplo n.º 7
0
    try:
        status_output = subprocess.check_output(
            ['hg', 'status', '-a', '-m', '--change', 'tip'])
    except subprocess.CalledProcessError, e:
        print >> sys.stderr, "Error calling 'hg status':", e
        return 1

    files_to_lint = []
    if status_output:
        for line in status_output.strip().split('\n'):
            # each line has the format "M path/to/filename.js"
            status, filename = line.split(' ', 1)
            files_to_lint.append(filename)

    num_errors = hook_lib.lint_files(files_to_lint)

    # Lint the commit message itself!
    commit_message = subprocess.check_output(
        ['hg', 'tip', '--template', '{desc}'])
    num_errors += hook_lib.lint_commit_message(commit_message)

    # Report what we found, and exit with the proper status code.
    hook_lib.report_errors_and_exit(num_errors, commit_message,
                                    os.path.join('.hg', 'commit.save'))


if __name__ == '__main__':
    suppress_lint = os.getenv('FORCE_COMMIT', '')
    if suppress_lint.lower() not in ('1', 'true'):
        sys.exit(main())