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

pre-commit hook doesn't run on just staged files #385

Closed
msabramo opened this issue Oct 31, 2023 · 2 comments · Fixed by #386
Closed

pre-commit hook doesn't run on just staged files #385

msabramo opened this issue Oct 31, 2023 · 2 comments · Fixed by #386
Assignees

Comments

@msabramo
Copy link
Contributor

Describe the bug
The pre-commit hook doesn't run on only files that are staged and being committed. The output will flag undeclared dependencies in files that haven't even been git added.

To Reproduce

git clone https://github.com/msabramo/fawltydeps-demo1
cd fawltydeps-demo1
pre-commit install
cat > main.py
import requests
import pandas
^D
cat > another.py
import sqlite
^D
git add main.py
git status
# Observe that `main.py` is staged and `another.py` is untracked
git commit

The output of git commit is:

$ git commit
FawltyDeps...............................................................Failed
- hook id: check
- exit code: 3

These imports appear to be undeclared dependencies:
- 'pandas' imported at:
    main.py:2
- 'sqlite' imported at:
    another.py:1

This is incorrect because it mentions the undeclared dependency in another.py which hasn't even been added to the project yet.

Expected behavior
It should've only mentioned the undeclared dependency in main.py; not in another.py, since I'm not committing that. It doesn't even exist in git at all yet, as we've never added it.

Environment

  • OS name + version: Mac OS X 12.6.8
  • Version of the code: main branch

Additional context
Add any other context about the problem here.

msabramo added a commit to msabramo/FawltyDeps that referenced this issue Oct 31, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: tweagGH-385
msabramo added a commit to msabramo/FawltyDeps that referenced this issue Oct 31, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: tweagGH-385
@msabramo
Copy link
Contributor Author

#386 is my attempt at fixing this.

@jherland
Copy link
Member

Thanks for your report! I agree that the pre-commit hook should run FawltyDeps on the staged changes only. We'll look into this as soon as time permits.

msabramo added a commit to msabramo/FawltyDeps that referenced this issue Oct 31, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: tweagGH-385
@mknorps mknorps self-assigned this Nov 2, 2023
jherland pushed a commit to msabramo/FawltyDeps that referenced this issue Nov 15, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: tweagGH-385
jherland pushed a commit that referenced this issue Nov 15, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: GH-385
mknorps pushed a commit that referenced this issue Nov 15, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: GH-385
mknorps pushed a commit that referenced this issue Dec 21, 2023
The `check-undeclared` hook runs only on files being committed.

Fixes: GH-385
mknorps added a commit that referenced this issue Dec 21, 2023
…o latest

Test of 'nul' for Windows checks

Copilot assisted fix for running subprocess on Windows machine

Bump version to 0.13.2 (#389)

packages: Expose decision to use current env to resolve packages

Until now, LocalPackageResolver has defaulted to only using the current
Python environment (aka. sys.path, the one in which FawltyDeps is
currently running) in the case where LocalPackageResolver is initialized
with zero package dirs.

We want to use the current env _in addition to_ other Python
environments in some scenarios, so move this decision out of
LocalPackageResolver, forward it via setup_resolvers(), and allow the
caller of setup_resolvers() to set this flag separately.

For now the observed behavior stays the same: Analysis.resolved_deps
still looks at whether or not any other Python environment were found
when setting use_current_env.

packages: Start separating handling of project pyenvs from current env

Use separate LocalPackageResolvers instances for Python environments
found inside the project vs. the _current_ Python environment in which
FawltyDeps is running (aka. sys.path).

We're about to make current env a mandatory part of the resolver stack,
and it therefore makes sense to start separating it from the other
local envs. This will also enable a future refactoring of
LocalPackageResolver into two separate classes.

Always include current env in the package resolver stack

This fixes issue #392 by making sure that in the case where there are
only _irrelevant_ venvs located inside the project, we will still find
at least _one_ Python environment where we can have some hope of finding
relevant dependencies installed.

In fact, this is partially a return to our pre v0.7 behavior where we
would always (then: only) find packages in sys.path. Since v0.7 we
allowed --pyenv to override this, and since v0.12, we also started
searching for pyenvs under --pyenv or basepaths given on the command
line. The result of this is that by now, the current environment is only
consulted in the fallback where no other environment is possibly found.

The change here is minimal (due to the preparations in previous
commits), and the existing tests are also compatible with this change,
except for the self_test Nox target, which can now be simplified to no
longer pass a --pyenv option, due to fixing this exact issue.

Most of the diff here is simply updating the relevant documentation to
reflect and clarify our new policy.

In the future, in the unlikely event that including sys.path in the
resolver stack introduces any regression, we might consider adding a
user-visible option to disable this again.

packages: Split SysPathPackageResolver out of LocalPackageResolver

Also introduce an InstalledPackageResolver base class to collect the
common parts shared between LocalPackageResolver and the new
SysPathPackageResolver.

Separate check-undeclared, check-unused pre-commit hooks

The `check-undeclared` hook runs only on files being committed.

Fixes: GH-385

Apply Maria's suggestions from code review

Co-authored-by: Maria Knorps <[email protected]>

Apply Johan's suggestions from code review

Pre-commit hooks: Update README and use --detailed by default

Update `README` instructions to reflect the new organization of the
pre-commit hooks offered by FawltyDeps. Also call --detailed from the
default `entry` as `args` is now reserved for `--code` and `--deps`,
respectively.

tests/utils.py: Better output when assert_unordered_equivalence fails

DirectoryTraversal: Allow attaching multiple data items in .add()

Instead of having to call traversal.add(dir, ...) multiple times in
order to attach multiple data items to the same 'dir', allow all data
items to be passed as *args to the .add() method.

Move DirectoryTraversal into its own module

In preparation for adding functionality for ignoring files/dirs in the
project.

dir_traversal: Rename .ignore() to .skip_dir()

We're about to introduce more functionality for ignoring files/dirs in a
directory structure via .gitignore-style patterns.

However, we're already using the term "ignore" to mean something
slightly different in DirectoryTraversal: The .ignore() method is used
to tell the traversal that some directory should _not_ be traversed.

Rename this method to .skip_dir() (and adjust members and comments
accordingly). This is more accurate to what this method actually does,
and it frees up the "ignore" term to be used in future commits.

dir_traversal: Refactor data on each traversal step into its own class

Introduce a TraversalStep class to hold the information that is being
passed from the DirecotryTraversal object at each step in the traversal
process. This is more self-documenting than yielding a os.walk() style
tuple, and allows more easily for future extension.

test_dir_traversal: Make use of ExpectedTraverseStep self-documenting

Each DirectoryTraversalVector encapsulate a test case for
DirectoryTraversal, and contains a list of steps that we expect
DirectoryTraversal to perform for that test case, aka. an
ExpectedTraverseStep.

These were initialized by passing four positional arguments to the
constructor (most of which are lists in their own right). The result
was that it was hard to read an ExpectedTraverseStep initialization and
immediate see what information was expected at this traversal step
(without constantly cross-referencing with the ExpectedTraverseStep
class definition).

Instead, make all ExpectedTraverseStep members (except the mandatory
.dir) optional (defaulting to empty lists), and use _named_ arguments
when intializing them. This makes reading the test cases more
straightforward: Instead of

  ExpectedTraverseStep("a/b/c", ["d"], [], [456, 123])

(meaning that we expect the traversal of "a/b/c" to list a single subdir
"d", no filenames, and passing [456, 123] as the attached data)
we now get

  ExpectedTraverseStep("a/b/c", subdirs=["d"], attached=[456, 123])

test_dir_traversal: Document the .add() calls set up in test vectors

traverse_project: Stricter typing for attached data

Bump version to v0.13.3

ADD discord shield to the README

Add message in the readme to join Discord

Declare that we support Python v3.12

Progress from Alpha to Beta quality :-)

Expand matrix of tested systems by windows and macos, change ubuntu to latest

Test of 'nul' for Windows checks

Use sys Python to execute FawltyDeps

WIP adjust tests to work on windows

ADD support for finding virtual environments on Windows

Fix more tests

Fix rendering of messages for Windows

Adjust command line tests to work on Windows

WIP fix more tests

Expand matrix of tested systems by windows and macos, change ubuntu to latest

Test of 'nul' for Windows checks

WIP adjust tests to work on windows

Fix more tests

Fix rendering of messages for Windows

Adjust command line tests to work on Windows

WIP fix more tests

FIX tests for Linux

Skip tests for symlinks on Windows - only administrator can create symlinks there

FIX after rebase

Use available os.devnull object and not a custoom function

Adjust NamedTemporaryFile to work with Windows. See documentation https://docs.python.org/3/library/tempfile.html

Fix temporary virtual environment creation

Adjust testdata in test_types for Windows

Fix temporary virtual environment creation

Fix last issues with the Windows paths representations

Skip tests meant only for Windows in other systems

Fix linters and formatters

Fixup for type of path representation in tests

Adjust integration tests for Windows

For testing resolver, use deadline of test dependent on install_deps flag.

Withouth that test report incosistency errors - it is much faster to run the test with instaling deps for the second time, as the dependencies are already there.

Allow for more than 15 local variables for linter

Use sys.executable for  upgrading pip and installing dependencies in project_helpers

Do not quote requirements for Windows

Fix formatting

For libraries to be accessable after install, we need to instal it with specific pip binary, not with 'python -m pip instal...'

Use deadline only for non install_deps runs of resolver tests

Otherwise rely on a github runner timeout mechanism

Split venv_script_lines from project_helpers to Windows and Linux-related

Fix with Copilot attempt 1

Experiments with real world projects

The problem is that the resolver falls back to the global resolver in tests, maybe run on the fresh runner instead of a local PC will help.

Parse requirements for windows real project tests

Enclose requirements in double quotes for Windows

Test with a single quote marker
mknorps added a commit that referenced this issue Dec 21, 2023
…o latest

Test of 'nul' for Windows checks

Copilot assisted fix for running subprocess on Windows machine

Bump version to 0.13.2 (#389)

packages: Expose decision to use current env to resolve packages

Until now, LocalPackageResolver has defaulted to only using the current
Python environment (aka. sys.path, the one in which FawltyDeps is
currently running) in the case where LocalPackageResolver is initialized
with zero package dirs.

We want to use the current env _in addition to_ other Python
environments in some scenarios, so move this decision out of
LocalPackageResolver, forward it via setup_resolvers(), and allow the
caller of setup_resolvers() to set this flag separately.

For now the observed behavior stays the same: Analysis.resolved_deps
still looks at whether or not any other Python environment were found
when setting use_current_env.

packages: Start separating handling of project pyenvs from current env

Use separate LocalPackageResolvers instances for Python environments
found inside the project vs. the _current_ Python environment in which
FawltyDeps is running (aka. sys.path).

We're about to make current env a mandatory part of the resolver stack,
and it therefore makes sense to start separating it from the other
local envs. This will also enable a future refactoring of
LocalPackageResolver into two separate classes.

Always include current env in the package resolver stack

This fixes issue #392 by making sure that in the case where there are
only _irrelevant_ venvs located inside the project, we will still find
at least _one_ Python environment where we can have some hope of finding
relevant dependencies installed.

In fact, this is partially a return to our pre v0.7 behavior where we
would always (then: only) find packages in sys.path. Since v0.7 we
allowed --pyenv to override this, and since v0.12, we also started
searching for pyenvs under --pyenv or basepaths given on the command
line. The result of this is that by now, the current environment is only
consulted in the fallback where no other environment is possibly found.

The change here is minimal (due to the preparations in previous
commits), and the existing tests are also compatible with this change,
except for the self_test Nox target, which can now be simplified to no
longer pass a --pyenv option, due to fixing this exact issue.

Most of the diff here is simply updating the relevant documentation to
reflect and clarify our new policy.

In the future, in the unlikely event that including sys.path in the
resolver stack introduces any regression, we might consider adding a
user-visible option to disable this again.

packages: Split SysPathPackageResolver out of LocalPackageResolver

Also introduce an InstalledPackageResolver base class to collect the
common parts shared between LocalPackageResolver and the new
SysPathPackageResolver.

Separate check-undeclared, check-unused pre-commit hooks

The `check-undeclared` hook runs only on files being committed.

Fixes: GH-385

Apply Maria's suggestions from code review

Co-authored-by: Maria Knorps <[email protected]>

Apply Johan's suggestions from code review

Pre-commit hooks: Update README and use --detailed by default

Update `README` instructions to reflect the new organization of the
pre-commit hooks offered by FawltyDeps. Also call --detailed from the
default `entry` as `args` is now reserved for `--code` and `--deps`,
respectively.

tests/utils.py: Better output when assert_unordered_equivalence fails

DirectoryTraversal: Allow attaching multiple data items in .add()

Instead of having to call traversal.add(dir, ...) multiple times in
order to attach multiple data items to the same 'dir', allow all data
items to be passed as *args to the .add() method.

Move DirectoryTraversal into its own module

In preparation for adding functionality for ignoring files/dirs in the
project.

dir_traversal: Rename .ignore() to .skip_dir()

We're about to introduce more functionality for ignoring files/dirs in a
directory structure via .gitignore-style patterns.

However, we're already using the term "ignore" to mean something
slightly different in DirectoryTraversal: The .ignore() method is used
to tell the traversal that some directory should _not_ be traversed.

Rename this method to .skip_dir() (and adjust members and comments
accordingly). This is more accurate to what this method actually does,
and it frees up the "ignore" term to be used in future commits.

dir_traversal: Refactor data on each traversal step into its own class

Introduce a TraversalStep class to hold the information that is being
passed from the DirecotryTraversal object at each step in the traversal
process. This is more self-documenting than yielding a os.walk() style
tuple, and allows more easily for future extension.

test_dir_traversal: Make use of ExpectedTraverseStep self-documenting

Each DirectoryTraversalVector encapsulate a test case for
DirectoryTraversal, and contains a list of steps that we expect
DirectoryTraversal to perform for that test case, aka. an
ExpectedTraverseStep.

These were initialized by passing four positional arguments to the
constructor (most of which are lists in their own right). The result
was that it was hard to read an ExpectedTraverseStep initialization and
immediate see what information was expected at this traversal step
(without constantly cross-referencing with the ExpectedTraverseStep
class definition).

Instead, make all ExpectedTraverseStep members (except the mandatory
.dir) optional (defaulting to empty lists), and use _named_ arguments
when intializing them. This makes reading the test cases more
straightforward: Instead of

  ExpectedTraverseStep("a/b/c", ["d"], [], [456, 123])

(meaning that we expect the traversal of "a/b/c" to list a single subdir
"d", no filenames, and passing [456, 123] as the attached data)
we now get

  ExpectedTraverseStep("a/b/c", subdirs=["d"], attached=[456, 123])

test_dir_traversal: Document the .add() calls set up in test vectors

traverse_project: Stricter typing for attached data

Bump version to v0.13.3

ADD discord shield to the README

Add message in the readme to join Discord

Declare that we support Python v3.12

Progress from Alpha to Beta quality :-)

Expand matrix of tested systems by windows and macos, change ubuntu to latest

Test of 'nul' for Windows checks

Use sys Python to execute FawltyDeps

WIP adjust tests to work on windows

ADD support for finding virtual environments on Windows

Fix more tests

Fix rendering of messages for Windows

Adjust command line tests to work on Windows

WIP fix more tests

Expand matrix of tested systems by windows and macos, change ubuntu to latest

Test of 'nul' for Windows checks

WIP adjust tests to work on windows

Fix more tests

Fix rendering of messages for Windows

Adjust command line tests to work on Windows

WIP fix more tests

FIX tests for Linux

Skip tests for symlinks on Windows - only administrator can create symlinks there

FIX after rebase

Use available os.devnull object and not a custoom function

Adjust NamedTemporaryFile to work with Windows. See documentation https://docs.python.org/3/library/tempfile.html

Fix temporary virtual environment creation

Adjust testdata in test_types for Windows

Fix temporary virtual environment creation

Fix last issues with the Windows paths representations

Skip tests meant only for Windows in other systems

Fix linters and formatters

Fixup for type of path representation in tests

Adjust integration tests for Windows

For testing resolver, use deadline of test dependent on install_deps flag.

Withouth that test report incosistency errors - it is much faster to run the test with instaling deps for the second time, as the dependencies are already there.

Allow for more than 15 local variables for linter

Use sys.executable for  upgrading pip and installing dependencies in project_helpers

Do not quote requirements for Windows

Fix formatting

For libraries to be accessable after install, we need to instal it with specific pip binary, not with 'python -m pip instal...'

Use deadline only for non install_deps runs of resolver tests

Otherwise rely on a github runner timeout mechanism

Split venv_script_lines from project_helpers to Windows and Linux-related

Fix with Copilot attempt 1

Experiments with real world projects

The problem is that the resolver falls back to the global resolver in tests, maybe run on the fresh runner instead of a local PC will help.

Parse requirements for windows real project tests

Enclose requirements in double quotes for Windows

Test with a single quote marker
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 a pull request may close this issue.

3 participants