-
-
Notifications
You must be signed in to change notification settings - Fork 804
/
Copy pathlinter.R
132 lines (101 loc) · 5.17 KB
/
linter.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env Rscript
#
# @license Apache-2.0
#
# Copyright (c) 2017 The Stdlib Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Lints a list of R files.
#
# The script is called with one or more arguments, where each argument is a
# filepath. Note that each provided filepath is resolved relative to the current
# working directory of the calling process.
#
# [1]: https://github.com/jimhester/lintr
# Ensure that the `lintr` package is installed...
if ( !require( "lintr", quietly = TRUE, character.only = TRUE ) ) {
install.packages( "lintr", repos = "http://lib.stat.cmu.edu/R/CRAN/", quiet = TRUE );
}
# Get only the trailing command-line arguments:
args <- commandArgs( trailingOnly = TRUE );
# Check that at least one filepath has been provided...
n <- length( args );
if ( n == 0 ) {
stop( "Must provide at least one file to lint.", call. = FALSE );
}
# Specify which linters to use...
linters <- lintr::linters_with_defaults( defaults = default_linters,
# Check that no absolute paths are used:
absolute_path_linter = lintr::absolute_path_linter(),
# Always use `<-` for assignment:
assignment_linter = lintr::assignment_linter(),
# Commas must always be followed by spaces, but never have spaces before them:
commas_linter = lintr::commas_linter(),
# Allow commented code outside roxygen blocks:
commented_code_linter = NULL, # lintr::commented_code_linter,
# Require the `[[` operator is used when extracting a single element from an object, not `[` (subsetting) or `$` (interactive use):
extraction_operator_linter = lintr::extraction_operator_linter(),
# Require that integers are explicitly typed using the form `1L` instead of `1`:
implicit_integer_linter = lintr::implicit_integer_linter(),
# Require that all infix operators have spaces around them:
infix_spaces_linter = NULL, # lintr::infix_spaces_linter,
# Require that line length of both comments and code is less than a specified length:
line_length_linter = lintr::line_length_linter( 200L ),
# Allow tabs:
no_tab_linter = NULL, # lintr::no_tab_linter(),
# Require that `file.path()` is used to construct safe and portable paths:
nonportable_path_linter = lintr::nonportable_path_linter(),
# Limit the length of function and variable names (characters):
object_length_linter = lintr::object_length_linter( 30L ),
# Require that object names conform to a single naming style (e.g., snake_case or lowerCamelCase):
object_name_linter = lintr::object_name_linter( "snake_case"),
# Require that closures have the proper usage using `checkUsage`:
object_usage_linter = lintr::object_usage_linter(),
# Various style checks related to placement and spacing of curly braces:
brace_linter = lintr::brace_linter( allow_single_line = FALSE ),
# Require that each step in a pipeline is on a new line, except when the entire pipe fits on one line:
pipe_continuation_linter = lintr::pipe_continuation_linter(),
# Allow semicolons to terminate statements:
semicolon_linter = lintr::semicolon_linter( allow_trailing = TRUE ),
# Require that only single quotes be used to delimit strings:
single_quotes_linter = lintr::single_quotes_linter(),
# Allow spaces directly inside parentheses and square brackets:
spaces_inside_linter = NULL, # lintr::spaces_inside_linter(),
# Require that all left parentheses have a space before them, except for function calls: (disabled as not reliable)
spaces_left_parentheses_linter = NULL, # lintr::spaces_left_parentheses_linter(),
# Ensure that source code does not contain TODO comments (case-insensitive):
todo_comment_linter = lintr::todo_comment_linter(),
# Never allow trailing blank lines:
trailing_blank_lines_linter = lintr::trailing_blank_lines_linter(),
# Never allow trailing whitespace characters:
trailing_whitespace_linter = lintr::trailing_whitespace_linter(),
# Avoid the symbols `T` and `F` for `TRUE` and `FALSE`, respectively:
T_and_F_symbol_linter = lintr::T_and_F_symbol_linter(),
# Report the use of undesirable functions (e.g., `attach` or `sapply`) and suggest an alternative:
undesirable_function_linter = lintr::undesirable_function_linter( fun = within( default_undesirable_functions, rm( options ) ) ),
# Report the use of undesirable operators (e.g., `:::` or `<<-`) and suggest an alternative:
undesirable_operator_linter = lintr::undesirable_operator_linter(),
# Ensure that the `c` function is not used without arguments or with a single constant:
unneeded_concatenation_linter = lintr::unneeded_concatenation_linter()
);
# Lint each file...
status <- 0;
for ( i in 1:n ) {
results <- lintr::lint( args[ i ], linters = linters );
if ( length( results ) > 0 ) {
status <- 1;
print( results );
}
}
# Quit with a non-zero exit code if lint errors:
quit( status = status );