-
Notifications
You must be signed in to change notification settings - Fork 187
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
Upstreaming linters from Google's internal linting suite #884
Comments
I think it would be great to include these in the 3.0 release. It would also give people more incentive to upgrade. It might also be worthwhile to package these as a separate object, so it would be easy to use them all as As to which of them should be on by default I leave that to others to discuss. |
That sounds really great! I also like the idea of adding To decide on the defaults, it will probably help to look at the concrete implementations. Curious side question regarding x <- c(NA, "a", "b", "c", NA)
x == "a" # c(NA, TRUE, FALSE, FALSE, NA)
x %in% "a" # c(FALSE, TRUE, FALSE, FALSE, FALSE) -- much safer for e.g. indexing |
no, it's a known false positive of the linter. we decided it's better for readability to treat NA handling explicitly, if so intended, and put that caveat in the lint message:
|
@AshesITR with #958 we'll finish up the current set of 13 I think now is a good time to think if we want to triage the prep for lintr 3.0.0 -- have have O(100) linters ready for upstreaming, which would put us at about June to finish, assuming we keep up the current (quite high) pace of new PRs. Should we prioritize instead? Pick some set of particularly neat/high-impact linters to include in the 3.0.0 release, then focus on tidying up 3.0.0 and putting it on CRAN before returning to new google linters? |
Sounds good to me. |
@MichaelChirico I edited your OP with a checklist and linked all PRs / issues I was aware of. |
Hello! I am interested in applying the Google R Style Guide to one of our packages. Thus, I am thrilled to see that you consider supplying a |
there are a slew already added -- see #962 |
Hi Michael and thank you for the quick reply. As far as I understand, #962 contains a list of Google linters already added to lintr. Jim Hester suggested above that available Google linters could be packaged in a separate object:
Has this already been done or would I have to include all of the linters in #962 one-by-one? |
With #2321, that's it! Special shout-out to @AshesITR and @IndrajeetPatil for your time and insights during the review process! The suite is now much better thanks to you! Thanks also to others who have filed follow-ups/tested the new linters on your own projects. |
Internally at Google we use
lintr
to power our in-editor and CI-based R linting tools. Over the last year+ (in addition to working directly onlintr
) we have been building out a set of linters that extends the suite offered bylintr
. Currently, the package has >60 such linters, almost all of which we think are widely relevant. They have all been test on & applied to existing internal R code at Google.We are happy to contribute any subset of these to
lintr
. Here is a brief summary of all of them; I can elaborate more as needed:AnyDuplicatedLinter
- Require usage of anyDuplicated() > 0 over any(duplicated(.))AnyIsNALinter
- Require usage of anyNA over any(is.na(.))ApplyAnonymousLinter
- Block usage of anonymous functions in *apply functions when unnecessary New unnecessary_lambda_linter #1541BaseOverwriteLinter
- Block assigning any variables whose name clashes with a 'base' R function New object_overwrite_linter #2307BooleanArithmeticLinter
New boolean_arithmetic_linter #1579CharacterOnlyLinter
- Enforce library calls using symbols Extend library_call_linter for character.only usage #2279ClassEqualsLinter
- Block comparison of class with ==ComparisonNegationLinter
New comparison_negation_linter #2272ConsecutiveMutateLinter
New consecutive_mutate_linter #2305ConsecutiveSuppressionLinter
New consecutive_suppression_linter #2306ElseSameLineLinter
- Require else to come on the same line asEmptyAssignmentLinter
- Block assignment of {} New empty_assignment_linter #1637ExpectComparisonLinter
- Require usage of expect_gt(x, y) over expect_true(x > y) (and similar) Expect comparison #955ExpectIdenticalLinter
- Require usage of expect_identical(x, y) where appropriate New expect_identical_linter #958ExpectIsLinter
- Redirect away from deprecated testthat::expect_is() expect_is_linter, or just use undesirable_function_linter? #946ExpectLengthLinter
- Require usage of expect_length(x, n) over expect_equal(length(x), n) New expect_length_linter #950ExpectNamedLinter
- Require usage of expect_named(x, n) over expect_equal(names(x), n) New expect_named_linter #949ExpectNotLinter
- Require usage of expect_false(.) over expect_true(!.) New expect_not_linter #945ExpectNullLinter
- Require usage of expect_null(x) over expect_equal(x, NULL) and similar expect_null_linter #887ExpectS3ClassLinter
- Require usage of expect_s3_class() or expect_s4_class() where appropriate. expect_s3_class_linter and expect_s4_class_linter #943ExpectS4ClassLinter
- Require usage of expect_s4_class(x, k) over expect_true(is(x, k)) expect_s3_class_linter and expect_s4_class_linter #943ExpectTrueFalseAndConditionLinter
- Force && conditions in expect_true(), expect_false() to be written separately New conjunct_expecation_linter #948ExpectTrueFalseLinter
- Require usage of expect_true(x) over expect_equal(x, TRUE) New expect_true_false_linter #947ExpectTypeLinter
- Require usage of expect_type(x, type) over expect_equal(typeof(x), type) expect_type_linter #924ExplicitReturnLinter
Linter for explicit/implicit returns #2271FilterAndConditionLinter
extend conjunct_test_linter for dplyr::filter() #2077FixedRegexLinter
- Require usage of 'fixed=TRUE' in regular expressions where appropriate New fixed_regex_linter #1021ForLoopIndexLinter
- Block usage of for loops directly overwriting the indexing variable New for_loop_index_linter #1629FunctionBraceLinter
- Require multi-line functions to use bracesGrepSubsetLinter
- Require usage of grep(value = TRUE) over xgrep(x)IfelseCensorLinter
- Block usage of ifelse where pmin or pmax is more appropriateIfElseMatchBracesLinter
- Require both or neither if/else branches to use curly bracesIfNotElseLinter
if_not_else_linter() for "double negation" in if statements #2071IfSwitchLinter
- Require usage of switch() over repeated if/else blocks New if_switch_linter #2304ImplicitElseReturnLinter
New allow_implicit_else argument for return_linter #2321InnerCombineLinter
- Require c() to be applied before relatively expensive vectorized functionsInnerComparisonLinter
- Require == to be used outside of sapply() when comparing to a constant Extend unnecessary_lambda_linter to look for "inner comparisons" #2300IsNumericLinter
- Redirect is.numeric(x) || is.integer(x) to just use is.numeric(x) New is_numeric_linter #1635KeywordQuoteLinter
- Block unnecessary quoting in calls keyword_quote_linter for unnecessary quoting #2030LengthLevelsLinter
- Require usage of nlevels over length(levels(.)) length_levels_linter() for length(levels(x)) --> nlevels(x) #2051LengthsLinter
New lengths_linter #1568ListComparisonLinter
New list_comparison_linter #2293LiteralCoercionLinter
- Require usage of correctly-typed literals over literal coercionsMagrittrDotLinter
New unnecessary_placeholder_linter #1656MultipleStopifnotLinter
- Force consecutive stopifnot() calls into just oneNestedIfelseLinter
- Block usage of nested ifelse() callsNestedPipeLinter
New nested_pipe_linter #2301NrowSubsetLinter
New nrow_subset_linter #2298NumericLeadingZeroLinter
- Require usage of a leading zero in all fractional numericsOneCallPipeLinter
New one_call_pipe_linter #2294OuterNegationLinter
- Require usage of !any(.) over all(!.), !all(.) over any(!.)PasteFilePathLinter
- Block usage of paste() with sep='/' file path detection in paste_linter #2074PasteSepLinter
- Block usage of paste() with sep=''PasteStrrepLinter
- Require usage of strrep('.', n) over paste(rep('.', n), collapse = '') extend paste_linter() for strrep() equivalents #1652PasteToStringLinter
- Block usage of paste() with collapse=', 'PipeCallLinter
- Force explicit calls in magrittr pipes New pipe_call_linter enforcing calls (not symbols) in magrittr pipes #801PipeReturnLinter
New pipe_return_linter #2299RedundantEqualsLinter
New redundant_equals_linter #1556RedundantIfelseLinter
- Prevent ifelse() from being used to produce TRUE/FALSERepLenLinter
New rep_len_linter #2286ReturnAssignmentLinter
Newfunction_return_linter()
#1569RequireNzcharLinter
- Require usage of nzchar where appropriate New nzchar_linter #2275RoutineRegistrationLinter
- Identify .Call usage to unregistered routines New routine_registration_linter #1669SampleIntLinter
- Require usage of sample.int(n, m, ...) over sample(1:n, m, ...) New sample_int_linter #2274ScalarInLinter
- Block usage like x %in% 'a' scalar_in_linter() for x %in% 1 #2084StopifnotAllLinter
New stopifnot_all_linter #2273StopifnotAndConditionLinter
- Force && conditions in stopifnot() to be written separatelyStopPasteLinter
- Block usage of paste() and paste0() with messaging functions using ...StringsAsFactorsLinter
- Identify cases where stringsAsFactors should be supplied explicitlySystemFileLinter
- Block usage of file.path() with system.file()TerminalCloseLinter
- Prohibit close() from terminating a function definition New terminal_close_linter #2276UnnecessaryNestingLinter
New unnecessary_nesting_linter #2302UnreachableCodeLinter
- Block unreachable code and comments following return statementsVectorLogicLinter
- Enforce usage of scalar && in conditional statementsWhichGreplLinter
- Require usage of grep over which(grepl(.)) New which_grepl_linter #2281YodaTestLinter
- Block obvious 'yoda tests' New yoda_test_linter #957What do you think is the best way to decide about which are in/out of scope for
lintr
? Does it make sense to delay this until 3.0 is released, or push to include with the major version bump?The text was updated successfully, but these errors were encountered: