-
Notifications
You must be signed in to change notification settings - Fork 192
[WIP] - Exclude files by relative path (lint_[package|dir]) #439
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
Conversation
When calling lint_package(path), any excluded-files specified in a .lintr file were originally handled relative to the working directory. This meant ~~~ lint_package("myPackage") # from the parent of myPackage lint_package(".") # from inside myPackage ~~~ gave different results for excluded files (the former including files that were supposed to be excluded). A couple of tests were added. These set up a temporary package with lint-containing source files, run lint_package() from outside and inside the temp package (+/- exclusions). Exclusions of the form list(filename = lines_to_omit) and list(filename) are both included in the test.
`normalize_exclusions` is used to specify filepaths of the excluded files; When running lint_dir or lint_package, the directory / package-root is now passed to normalize_exclusions & excluded files are pinned relative to this.
`read_settings` was modified: when it is passed a directory, any excluded files that are specified in a user config are now specified relative to the directory (eg, the package root), rather relative to the current working directory
Failure appears to be due to the use of |
I would suggest you make the dummy package in the |
names(x) <- file.path(dir_prefix, names(x)) | ||
} | ||
if (normalize_path) { | ||
x <- x[file.exists(names(x))] # remove exclusions for non-existing files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be best if
x <- x[file.exists(names(x))]
were outside the if
statement.
Thank you for tackling this issue @russHyde ! I'd also like to point out that the use of Finally, in |
.lintr files in test-subdirs cause problems in R CMD check (and can't be added to .RbuildIgnore because they are needed during tests)
Wasn't able to include .lintr files in a dummy-package in a subdir of `tests/`. Instead, during tests we copy a dummy package from `tests/testthat/dummy_packages/<pkgName>` into a temp-dir and add a .lintr file to the temp package during the test.
Would you welcome another PR that allows exclusion of all elements in a directory? This doesn't seem to be covered at present |
R/settings.R
Outdated
# - `filename` means exclude all lines in `filename` | ||
# normalise_exclusions needs to know which directory the excluded-files | ||
# are pinned against | ||
dir_prefix <- if (is_directory(filename)) filename else NULL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, the behavior is still ambiguous if filename
is not NULL
and points to a file.
Could we use dirname
in that case? Or would we want to assign value <- NULL
in that case?
Let me know if that should not be thought of in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure what the problem is. I've strived not to affect how linting works when lint()
is called on single files.
But yeah, if lint() is called on a single file, then any exclusions defined in the config may not apply; so I guess syntastic, or similar, might flag lints when you're looking at a file that 'should be' excluded from linting. (but if files other than the file-of-interest are present in the exclusion list, there doesn't seem much point to NULL those out of the exlcusions list (given that you aren't linting them))
(Sorry if I missed your point)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is due to the fact that lint(filename)
looks at the configurations in a .lintr
file in the same folder of filename
.
So, if filename
is an actual path (e.g. inst/example/bad.R
), then read_settings
might extract exclusions: list("bad.R")
(assume we create a file inst/example/.lintr
with that content) and, in this situation, the results of
> lint("bad.R")
and
> lint("inst/example/bad.R")
will be different (assume the commands are run with the right workdirs).
Looking at this part of the code in both executions we see that dir_prefix = NULL
and value = list("bad.R")
. Then, since the workdirs are different, the function normalize_exclusions
will find the file bad.R
in one case and not in the other, and the outputs will be different.
My suggestion, would be to make dir_prefix
equal to the path to the folder containing filename
. E.g. one could change it to (or something nicer)
dir_prefix <- if (is_directory(filename)) filename else {if (is.null(filename)) NULL else dirname(filename)}
EDIT:
After reading your comment with more attention it seems to me that value
should be made equal to NULL
or empty list()
.
In my opinion, the changes look good. |
Rather than copying the whole temporary package, maybe just create the needed |
Thanks @jimhester I hadn't considered that. I'm in two minds about this pr. Though I'll update the tests, please don't merge it yet. |
`assignmentLinter` is a more informative package name for the dummy package used in lint_package integration tests.
When running tests on dummy packages, rather than optionally adding .lintr configs to a temp-copy of the package, add the config to the existing package and remove it `on.exit()`.
…subdirectory (vs pkg-root / outside package)
Packages have a prescribed structure.
It makes sense for the lintr-config to list excluded files with-respect-to the package root (and the code I've modified allows this) The changes made here might cause confusion for more general directories / project structures. As a simple example:
Assignment lints in "R/abc.R" are flagged (despite the .lintr file having excluded that file) if:
lint("R/abc.R") does not flag lints when called from the package root If a .lintr is specified (in a package, R-project or more general directory structure), it might be better to parse exclusions with respect to the directory in which the .lintr is found (than wrt the current working dir, as present; or an assumed package structure, as I've tried to implement here) |
…ing dir and of position of .lintr
I've pushed up a few (currently failing) tests:
|
Hi @russHyde I'll submit a draft PR later as well just to try to get my idea across better. |
I don't see why the working directory has any relation to my second point. The excluded files should be encoded in .lintr consistent with their position relative to .lintr. My second point is illustrated below. If I have
It should give the same results as this:
... and in both cases, the results should be independent of the working directory. |
…to the .lintr-containing directory
So, I've modified the code again. Now any exclusions that are specified in a .lintr file are handled relative to the directory that contains .lintr (so the .lintr-specified exclusions should be independent of the working directory and also be insensitive to the .lintr being specified in the source-file-directory or the project-root) An issue has arisen though: when a user calls So, this would not exclude the first line from "/scripts/excluded.R", yet.
I haven't attempted to handle .lintr files in the user's home directory yet |
[I don't understand why the tests have passed on Travis. There are a number of tests in |
I got the same thing @russHyde . Amongst others, it's showing an failure at line 192 of Then, I removed |
I figured why the tests were not passing. Turns out I wasn't completely right, when I said that This is my interpretation from reading the functions I would suggest eliminating Finally, I did a PR to the PR branch with my suggestions. Please, let me know what you think @russHyde , @jimhester EDIT: if we want to allow search for a configuration file in parent folders, then |
Closing this since the feature was implemented in #539 and AFAIK all salvageable code from this (namely, the tests) has been merged. |
fix #438 - pin exclusions relative to dir/pkg in lint_[package|dir]
When calling lint_package(path), any excluded-files specified in a
.lintr file were originally handled relative to the working directory.
This meant
gave different results for excluded files (the former including files
that were supposed to be excluded).
read_settings
handles exclusions when passed a directoryread_settings
was modified: when it is passed a directory, anyexcluded files that are specified in a user config are now specified
relative to the directory (eg, the package root), rather relative to the
current working directory
normalize_exclusions
is used to specify filepaths of the excludedfiles; When running lint_dir or lint_package, the directory /
package-root is now passed to normalize_exclusions & excluded files are
pinned relative to this.
A couple of tests were added. These set up a temporary package with
lint-containing source files, run lint_package() from outside and
inside the temp package (+/- exclusions).
Exclusions of the form list(filename = lines_to_omit) and list(filename)
are both included in the test.