Skip to content

Commit fd82399

Browse files
committed
Add tool to lint R source files
1 parent 050246d commit fd82399

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

tools/lint/r/DESCRIPTION

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Package: rlint
2+
Title: Lint R Code
3+
Version: 0.0.0
4+
Authors@R: person("stdlib", "js", role = c("aut","cre"))
5+
Description: Lints R code.
6+
Depends: R (>=3.3.3)
7+
Imports:
8+
lintr
9+
LazyData: true

tools/lint/r/linter.R

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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

Comments
 (0)