|
| 1 | +#!/usr/bin/env Rscript |
| 2 | +# |
| 3 | +# Lints a list of R files. |
| 4 | +# |
| 5 | +# The script is called with one or more arguments, where each argument is a |
| 6 | +# filepath. Note that each provided filepath is resolved relative to the current |
| 7 | +# working directory of the calling process. |
| 8 | + |
| 9 | +# Get only the trailing command-line arguments: |
| 10 | +args <- commandArgs( trailingOnly = TRUE ); |
| 11 | + |
| 12 | +# Check that at least one filepath has been provided... |
| 13 | +n <- length( args ); |
| 14 | +if ( n == 0 ) { |
| 15 | + stop( "Must provide at least one file to lint.", call. = FALSE ); |
| 16 | +} |
| 17 | +# Specify which linters to use... |
| 18 | +linters <- lintr::with_defaults( default = list(), |
| 19 | + # Check that no absolute paths are used: |
| 20 | + absolute_paths_linter = lintr::absolute_paths_linter, |
| 21 | + |
| 22 | + # Always use `<-` for assignment: |
| 23 | + assignment_linter = lintr::assignment_linter, |
| 24 | + |
| 25 | + # (deprecated) Object names should never be written in camelCase: |
| 26 | + camel_case_linter = lintr::camel_case_linter, |
| 27 | + |
| 28 | + # Closed curly braces should always be on their own line unless they follow an `else`: |
| 29 | + closed_curly_linter = lintr::closed_curly_linter( allow_single_line = FALSE ), |
| 30 | + |
| 31 | + # Commas must always be followed by spaces, but never have spaces before them: |
| 32 | + commas_linter = lintr::commas_linter, |
| 33 | + |
| 34 | + # (deprecated) Allow commented code outside roxygen blocks: |
| 35 | + commented_code_linter = NULL, # lintr::commented_code_linter, |
| 36 | + |
| 37 | + # (pending) Require the `[[` operator is used when extracting a single element from an object, not `[` (subsetting) or `$` (interactive use): |
| 38 | + # extraction_operator_linter = lintr::extraction_operator_linter, |
| 39 | + |
| 40 | + # (pending) Require that integers are explicitly typed using the form `1L` instead of `1`: |
| 41 | + # implicit_integer_linter = lintr::implicit_integer_linter, |
| 42 | + |
| 43 | + # (pending) Require that all infix operators have spaces around them: |
| 44 | + infix_spaces_linter = NULL, # lintr::infix_spaces_linter, |
| 45 | + |
| 46 | + # Require that line length of both comments and code is less than a specified length: |
| 47 | + line_length_linter = lintr::line_length_linter( 120L ), |
| 48 | + |
| 49 | + # (deprecated) Allow objects to have.multiple.dots: |
| 50 | + multiple_dots_linter = NULL, # lintr::multiple_dots_linter, |
| 51 | + |
| 52 | + # Allow tabs: |
| 53 | + no_tab_linter = NULL, # lintr::no_tab_linter, |
| 54 | + |
| 55 | + # (pending) Require that `file.path()` is used to construct safe and portable paths: |
| 56 | + # nonportable_path_linter = lintr::nonportable_path_linter, |
| 57 | + |
| 58 | + # Limit the length of function and variable names (characters): |
| 59 | + object_length_linter = lintr::object_length_linter( 30L ), |
| 60 | + |
| 61 | + # (pending) Require that object names conform to a single naming style (e.g., snake_case or lowerCamelCase): |
| 62 | + # object_name_linter = lintr::object_name_linter( "snake_case"), |
| 63 | + |
| 64 | + # Require that closures have the proper usage using `checkUsage`: |
| 65 | + object_usage_linter = lintr::object_usage_linter, |
| 66 | + |
| 67 | + # Never allow opening curly braces to be on their own line, and require that they are always followed by a newline: |
| 68 | + open_curly_linter = lintr::open_curly_linter( allow_single_line = FALSE ), |
| 69 | + |
| 70 | + # (pending) Require that each step in a pipeline is on a new line, except when the entire pipe fits on one line: |
| 71 | + # pipe_continuation_linter = lintr::pipe_continuation_linter, |
| 72 | + |
| 73 | + # (pending) Allow semicolons to terminate statements: |
| 74 | + # semicolon_terminator_linter = lintr::semicolon_terminator_linter, |
| 75 | + |
| 76 | + # Require that only single quotes be used to delimit strings: |
| 77 | + single_quotes_linter = lintr::single_quotes_linter, |
| 78 | + |
| 79 | + # (deprecated) Allow object names to be written in snake_case: |
| 80 | + snake_case_linter = NULL, # lintr::snake_case_linter, |
| 81 | + |
| 82 | + # Allow spaces directly inside parentheses and square brackets: |
| 83 | + spaces_inside_linter = NULL, # lintr::spaces_inside_linter, |
| 84 | + |
| 85 | + # Require that all left parentheses have a space before them, except for function calls: |
| 86 | + spaces_left_parentheses_linter = lintr::spaces_left_parentheses_linter, |
| 87 | + |
| 88 | + # (pending) Ensure that source code does not contain TODO comments (case-insensitive): |
| 89 | + # todo_comment_linter = lintr::todo_comment_linter, |
| 90 | + |
| 91 | + # Never allow trailing blank lines: |
| 92 | + trailing_blank_lines_linter = lintr::trailing_blank_lines_linter, |
| 93 | + |
| 94 | + # Never allow trailing whitespace characters: |
| 95 | + trailing_whitespace_linter = lintr::trailing_whitespace_linter |
| 96 | + |
| 97 | + # (pending) Avoid the symbols `T` and `F` for `TRUE` and `FALSE`, respectively: |
| 98 | + # T_and_F_symbol_linter = lintr::T_and_F_symbol_linter, |
| 99 | + |
| 100 | + # (pending) Report the use of undesirable functions (e.g., `options` or `sapply`) and suggest an alternative: |
| 101 | + # undesirable_function_linter = lintr::undesirable_function_linter, |
| 102 | + |
| 103 | + # (pending) Report the use of undesirable operators (e.g., `:::` or `<<-`) and suggest an alternative: |
| 104 | + # undesirable_operator_linter = lintr::undesirable_operator_linter, |
| 105 | + |
| 106 | + # (pending) Ensure that the `c` function is not used without arguments or with a single constant: |
| 107 | + # unneeded_concatenation_linter = lintr::unneeded_concatenation_linter, |
| 108 | +); |
| 109 | + |
| 110 | +# Lint each file... |
| 111 | +for ( i in 1:n ) { |
| 112 | + results <- lintr::lint( args[ i ], linters = linters ); |
| 113 | + if ( length( results ) > 0 ) { |
| 114 | + print( results ); |
| 115 | + } |
| 116 | +} |
0 commit comments