diff --git a/pre_commit/main.py b/pre_commit/main.py index ce16acde..7092a5a8 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -8,6 +8,7 @@ import pkg_resources from pre_commit import color from pre_commit import five +from pre_commit import git from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.clean import clean from pre_commit.commands.install_uninstall import install @@ -110,7 +111,8 @@ def main(argv=None): help='Run on all the files in the repo. Implies --no-stash.', ) run_mutex_group.add_argument( - '--files', nargs='*', help='Specific filenames to run hooks on.', + '--files', nargs='*', default=[], + help='Specific filenames to run hooks on.', ) help = subparsers.add_parser( @@ -122,6 +124,11 @@ def main(argv=None): if len(argv) == 0: argv = ['run'] args = parser.parse_args(argv) + if args.command == 'run': + args.files = [ + os.path.relpath(os.path.abspath(filename), git.get_root()) + for filename in args.files + ] if args.command == 'help': if args.help_cmd: diff --git a/pre_commit/runner.py b/pre_commit/runner.py index 88028939..35ab3427 100644 --- a/pre_commit/runner.py +++ b/pre_commit/runner.py @@ -24,7 +24,7 @@ class Runner(object): def create(cls): """Creates a PreCommitRunner by doing the following: - Finds the root of the current git repository - - chdirs to that directory + - chdir to that directory """ root = git.get_root() os.chdir(root) diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index 363743fb..d4e37f20 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -83,7 +83,8 @@ def _do_run(repo, args, environ={}): runner = Runner(repo) write_mock = mock.Mock() write_fn = functools.partial(sys_stdout_write_wrapper, stream=write_mock) - ret = run(runner, args, write=write_fn, environ=environ) + with cwd(runner.git_root): # replicates Runner.create behaviour + ret = run(runner, args, write=write_fn, environ=environ) printed = get_write_mock_output(write_mock) return ret, printed @@ -595,3 +596,26 @@ def test_unstaged_message_suppressed( args = _get_opts(**opts) ret, printed = _do_run(modified_config_repo, args) assert b'Your .pre-commit-config.yaml is unstaged.' not in printed + + +def test_files_running_subdir( + repo_with_passing_hook, mock_out_store_directory, tempdir_factory, +): + with cwd(repo_with_passing_hook): + install(Runner(repo_with_passing_hook)) + + os.mkdir('subdir') + open('subdir/foo.py', 'w').close() + cmd_output('git', 'add', 'subdir/foo.py') + + with cwd('subdir'): + # Don't want to write to home directory + env = dict(os.environ, PRE_COMMIT_HOME=tempdir_factory.get()) + # Use subprocess to demonstrate behaviour in main + _, stdout, _ = cmd_output( + sys.executable, '-m', 'pre_commit.main', 'run', '-v', + # Files relative to where we are (#339) + '--files', 'foo.py', + env=env, + ) + assert 'subdir/foo.py' in stdout