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

Add library call linter #2027

Merged
merged 13 commits into from
Aug 3, 2023
Merged

Conversation

nicholas-masel
Copy link
Contributor

I've got a use case where I need all library() calls to be at the top of the script so the search path is consistent across the entire script.

I will incorporate this into the linting for the logrx package, but thought others might want this as well, so better in lintr than buried in a logging package. I hope you all agree.

@nicholas-masel
Copy link
Contributor Author

I'm not sure why the lint is returning multiple and causing the tests to fail. When I run this on my side it returns one and everything is running cleanly.

library(lintr)

lint(
  text = c("library(dplyr)", "print('test')", "library(tidyr)"),
  linters = library_call_linter()
)
#> <text>:3:1: warning: [library_call_linter] Move all library calls to the top of the script.
#> library(tidyr)
#> ^~~~~~~

Created on 2023-07-28 with reprex v2.0.2

@AshesITR
Copy link
Collaborator

AFAIK the last() predicate refers to the last element that satisfies a condition within each node.
That means it probably doesn't do anything in the XPath, because all the library calls are contained inside their own expr element.

@nicholas-masel
Copy link
Contributor Author

AFAIK the last() predicate refers to the last element that satisfies a condition within each node. That means it probably doesn't do anything in the XPath, because all the library calls are contained inside their own expr element.

@AshesITR Thanks! I'll try (//element[@name='D'])[last()] as this post suggests to see if that gives me the last node, rather than the last element within each node.

I'm still unclear why it returns the expected result on my end and fails when running through ci/cd here. It makes it so the only way I can test is to push updates and check the actions, which is probably destroying your email inbox with fail messages. Sorry about this.

@MichaelChirico
Copy link
Collaborator

probably destroying your email inbox with fail messages

FWIW I don't get those. only the code coverage bot comments when CI passes.

@nicholas-masel
Copy link
Contributor Author

probably destroying your email inbox with fail messages

FWIW I don't get those. only the code coverage bot comments when CI passes.

Good to know, thanks! Now I don't feel so bad hacking through it this way :)

@MichaelChirico
Copy link
Collaborator

I'm still unclear why it returns the expected result on my end and fails when running through ci/cd here

could be an R version thing? there are subtle differences in the XML structure between versions sometimes. To help, you could add writeLines(as.character(XML)) to facilitate print debugging.

@nicholas-masel
Copy link
Contributor Author

writeLines(as.character(XML))

Great idea! I'm not clear how would I retrieve this from the action? Can I access this somehow after the action is complete?

@nicholas-masel
Copy link
Contributor Author

writeLines(as.character(XML))

Great idea! I'm not clear how would I retrieve this from the action? Can I access this somehow after the action is complete?

@MichaelChirico nvm! This defaults to standard out!

@codecov-commenter
Copy link

codecov-commenter commented Aug 1, 2023

Codecov Report

Merging #2027 (34b899f) into main (37e9c39) will increase coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head 34b899f differs from pull request most recent head 4a0754f. Consider uploading reports for the commit 4a0754f to get more accurate results

@@           Coverage Diff           @@
##             main    #2027   +/-   ##
=======================================
  Coverage   98.55%   98.56%           
=======================================
  Files         113      114    +1     
  Lines        4994     5011   +17     
=======================================
+ Hits         4922     4939   +17     
  Misses         72       72           
Files Changed Coverage Δ
R/library_call_linter.R 100.00% <100.00%> (ø)

R/library_call_linter.R Outdated Show resolved Hide resolved
R/library_call_linter.R Outdated Show resolved Hide resolved
R/library_call_linter.R Outdated Show resolved Hide resolved
tests/testthat/test-library_call_linter.R Outdated Show resolved Hide resolved
tests/testthat/test-library_call_linter.R Show resolved Hide resolved
AshesITR
AshesITR previously approved these changes Aug 2, 2023
@AshesITR
Copy link
Collaborator

AshesITR commented Aug 2, 2023

Good work.
Don't forget to mention yourself in a NEWS bullet.

@@ -42,6 +42,7 @@ infix_spaces_linter,style readability default configurable
inner_combine_linter,efficiency consistency readability
is_numeric_linter,readability best_practices consistency
lengths_linter,efficiency readability best_practices
library_call_linter,style best_practices
Copy link
Collaborator

Choose a reason for hiding this comment

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

this counts as readability to me too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is updated.

Copy link
Collaborator

@MichaelChirico MichaelChirico left a comment

Choose a reason for hiding this comment

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

You might want to add an exception for library() calls inside functions -- e.g. for libraries calling library() on behalf of the user. The current logic seems tailored to scripts, but the linter will end up being used in packages too.

It would also be easy to consider require() the same as library() for this linter.

@nicholas-masel
Copy link
Contributor Author

You might want to add an exception for library() calls inside functions -- e.g. for libraries calling library() on behalf of the user. The current logic seems tailored to scripts, but the linter will end up being used in packages too.

It would also be easy to consider require() the same as library() for this linter.

@MichaelChirico Would you be open to completing this PR as is and adding this as a new issue? I'm happy to continue to work on it to add these features, but it would allow me to get this functionality in so I can have another package use it for it's upcoming release.

@MichaelChirico
Copy link
Collaborator

SGTM, please help to file follow-up issues

@MichaelChirico MichaelChirico merged commit 3e6b862 into r-lib:main Aug 3, 2023
21 checks passed
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.

5 participants