Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use pre-commit for Git hooks #3406

Merged
merged 13 commits into from
Mar 16, 2020
Merged

Conversation

andrewhare
Copy link
Contributor

@andrewhare andrewhare commented Feb 25, 2020

Fixes #3271.

NOTE: This is blocked by a pending 2.2.0 release of pre-commit to support post-checkout hooks.

This introduces a new flag to the dvc install command:

$ dvc install --use-pre-commit-tool

Running this command will do several things:

  • Verify that pre-commit is installed on the system
  • Write the existing DVC git hooks bash files to .dvc/tmp/hooks instead of to .git/hooks
  • Build a pre-commit configuration that calls the hook files in .dvc/tmp/hooks.
  • Check the current directory for an existing .pre-commit-config.yaml, if one is found, merge the configuration into it, otherwise dump the configuration to a new .pre-commit-config.yaml.

@efiop
Copy link
Contributor

efiop commented Feb 26, 2020

@andrewhare Looks really good! Thank you so much for the PR!

For the record: We've discussed during the meeting with @andrewwhare, that it might be worth creating those hook files somewhere (e.g. in .dvc/ or .dvc/tmp/) and triggering those from pre-commit config, instead of writing shell wrapper directly into them.

@andrewhare
Copy link
Contributor Author

@efiop Thanks for the feedback!

I like the idea of writing the hook files to disk (possibly reusing/refactoring _install_hook to write to the correct directory) and calling them there.

@andrewhare andrewhare force-pushed the WIP-pre-commit-tool branch from 23dae14 to 7c0792f Compare March 5, 2020 22:50
@andrewhare andrewhare changed the title WIP: Use pre-commit for Git hooks Use pre-commit for Git hooks Mar 5, 2020
@skshetry skshetry self-requested a review March 6, 2020 06:36
@efiop efiop requested review from pared, Suor and gurobokum March 9, 2020 11:29
Comment on lines 314 to 271
if not which("pre-commit"):
raise DvcException("pre-commit is not installed")

Copy link
Contributor

@efiop efiop Mar 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we really need to run pre-commit for the user, maybe config is enough + a hint now run 'pre-commit install' to install git hooks? Just a question.

Comment on lines 323 to 325
conf_yaml = os.path.join(self.root_dir, ".pre-commit-config.yaml")
if not os.path.isfile(conf_yaml):
check_call(["pre-commit", "install"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is needed in case user has .pre-commit-hooks.yaml, but no config? Or am I missing something?

Copy link
Contributor

@pared pared left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider adding test asserting that hooks work.
I tried to check their behavior and upon running this script:

#!/bin/bash

rm -rf repo storage git_repo
mkdir repo git_repo

main=$(pwd)
pushd git_repo
git init --quiet --bare
popd

pushd repo

git init --quiet
dvc init -q
git remote add origin $main/git_repo
dvc remote add -d str $main/storage

dvc install --use-pre-commit-tool

echo data >> data

dvc add data -q

git add -A
git commit -am "something"

I get the following error:

An error has occurred: InvalidConfigError: 
==> File .pre-commit-config.yaml
==> At Config()
==> At key: repos
==> At Repository(repo='local')
==> At key: hooks
==> At Hook(id='dvc-post-checkout')
==> At key: stages
==> At index 0
=====> Expected one of commit, commit-msg, manual, merge-commit, prepare-
commit-msg, push but got: 'checkout'
Check the log at /home/prd/.cache/pre-commit/pre-commit.log

Comment on lines 7 to 31
class TestPreCommitTool(TestCase):
def setUp(self):
self.conf = pre_commit_tool_conf("a", "b", "c")

def test_merge_pre_commit_tool_confs_empty(self):
existing_conf = None
merged_conf = merge_pre_commit_tool_confs(existing_conf, self.conf)
self.assertEqual(self.conf, merged_conf)

def test_merge_pre_commit_tool_confs_invalid_yaml(self):
existing_conf = "some invalid yaml"
merged_conf = merge_pre_commit_tool_confs(existing_conf, self.conf)
self.assertEqual(self.conf, merged_conf)

def test_merge_pre_commit_tool_confs_no_repos(self):
existing_conf = {"foo": [1, 2, 3]}
merged_conf = merge_pre_commit_tool_confs(existing_conf, self.conf)
self.assertEqual(self.conf, merged_conf)

def test_merge_pre_commit_tool_confs(self):
existing_conf = {"repos": [{}]}
merged_conf = merge_pre_commit_tool_confs(existing_conf, self.conf)
# Merging the new conf in should append the new repo to the end of
# the existing repos array on the existing conf.
self.assertEqual(self.conf["repos"][0], merged_conf["repos"][1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some particular reason to use unittest? We re moving towards using pytest, I think it would be good to make it test also pytest-based.

@efiop
Copy link
Contributor

efiop commented Mar 16, 2020

@pared Did you install the latest pre-commit version? As mentioned in the header, it requires 2.2.0

EDIT: can reproduce, looking into it.

@efiop
Copy link
Contributor

efiop commented Mar 16, 2020

For the record: taking over this PR.

@efiop efiop changed the title Use pre-commit for Git hooks [WIP] Use pre-commit for Git hooks Mar 16, 2020
@efiop efiop force-pushed the WIP-pre-commit-tool branch from b226826 to cf2fa6d Compare March 16, 2020 12:09
@efiop
Copy link
Contributor

efiop commented Mar 16, 2020

Currently you need to dvc install --use-pre-commit-tool on each clone, as pre-commit won't have .dvc/tmp/hook/* scripts to run without it. Looks like it would be better to run hooks directly through dvc. Looking into it.

@efiop efiop force-pushed the WIP-pre-commit-tool branch 2 times, most recently from 9891552 to df29cd2 Compare March 16, 2020 15:04
@efiop efiop force-pushed the WIP-pre-commit-tool branch 12 times, most recently from ac7780d to 1490809 Compare March 16, 2020 16:59
@efiop efiop force-pushed the WIP-pre-commit-tool branch from 1490809 to 63fcc66 Compare March 16, 2020 17:12
Comment on lines +34 to +35
repo: https://github.com/andrewhare/dvc
rev: WIP-pre-commit-tool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be fixed after merge.

@efiop efiop changed the title [WIP] Use pre-commit for Git hooks Use pre-commit for Git hooks Mar 16, 2020
@efiop
Copy link
Contributor

efiop commented Mar 16, 2020

Ok, merging to adjust on master. So far works good for me, but it is tied to github repo, so need to try out on our master.

Docs will come separately after.

@efiop efiop merged commit c4164b3 into iterative:master Mar 16, 2020
@shcheklein
Copy link
Member

@efiop do we need adjust any docs because of this change?

@efiop
Copy link
Contributor

efiop commented Mar 16, 2020

@shcheklein Yes, hence "Docs will come separately after."

efiop added a commit to iterative/dvc.org that referenced this pull request Mar 16, 2020
efiop added a commit to iterative/dvc.org that referenced this pull request Mar 16, 2020
shcheklein pushed a commit to iterative/dvc.org that referenced this pull request Mar 16, 2020
@@ -27,4 +27,11 @@ def add_parser(subparsers, parent_parser):
help=INSTALL_HELP,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
install_parser.add_argument(
"--use-pre-commit-tool",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to have --use-pre-commit or just --pre-commit. Tool is kind of redundant here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skshetry Im worried about it being confused with pre-commit hooks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

install: support pre-commit util
5 participants