1# lintr 2[![Travis-CI Build Status](https://travis-ci.org/jimhester/lintr.svg?branch=master)](https://travis-ci.org/jimhester/lintr) 3[![codecov.io](https://codecov.io/github/jimhester/lintr/coverage.svg?branch=master)](https://codecov.io/github/jimhester/lintr?branch=master) 4[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/lintr)](https://cran.r-project.org/package=lintr) [![Join the chat at https://gitter.im/jimhester-lintr/Lobby](https://badges.gitter.im/jimhester-lintr/Lobby.svg)](https://gitter.im/jimhester-lintr/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 6## Static code analysis for R ## 7 8`lintr` is an R package offering [static code analysis for R](https://en.wikipedia.org/wiki/Static_program_analysis). It checks adherence to a given style, syntax errors and possible semantic issues, see the animation below. In this README find out 9 10* [what linters i.e. checks are supported](#available-linters); 11 12* [how to configure the project to e.g. tweak checks and ignore files](#project-configuration); 13 14* [how to setup `lintr` for on-the-fly checking in different editors](#editors-setup); 15 16* [how to use `lintr` in combination with continuous integration](#continuous-integration); 17 18![lintr](http://i.imgur.com/acV27NV.gif "lintr") 19 20### What to do with `lintr` output? 21 22If you need a bit automatic help for re-styling your code, have a look at [the `styler` package](https://github.com/r-lib/styler) 23 24## Available linters ## 25 26* `Syntax errors`: reported by [parse](https://www.rdocumentation.org/packages/base/versions/3.4.0/topics/parse). 27* `object_usage_linter`: check that closures have the proper usage using 28 [codetools::checkUsage()](https://www.rdocumentation.org/packages/codetools/versions/0.2-15/topics/checkUsage). Note this runs 29 [base::eval()](https://www.rdocumentation.org/packages/base/versions/3.4.0/topics/eval) on the code, so do not use with untrusted code. 30* `absolute_path_linter`: check that no absolute paths are used (e.g. "/var", "C:\\System", "~/docs"). 31* `nonportable_path_linter`: check that file.path() is used to construct safe and portable paths. 32* `pipe_continuation_linter`: Check that each step in a pipeline is on a new 33 line, or the entire pipe fits on one line. 34* `assignment_linter`: check that `<-` is always used for assignment 35* `camel_case_linter`: check that objects are not in camelCase. 36* `closed_curly_linter`: check that closed curly braces should always be on their 37 own line unless they are followed by an else. 38* `commas_linter`: check that all commas are followed by spaces, but do not 39 have spaces before them. 40* `commented_code_linter`: check that there is no commented code outside of roxygen comments. 41* `cyclocomp_linter`: check for overly complicated expressions. 42* `equals_na_linter`: check for x == NA 43* `extraction_operator_linter`: check that the `[[` operator is used when extracting a single 44 element from an object, not `[` (subsetting) nor `$` (interactive use). 45* `function_left_parentheses_linter`: check that all left parentheses in a 46 function call do not have spaces before them. 47* `implicit_integer_linter`: check that integers are explicitly typed using the form `1L` instead of `1`. 48* `infix_spaces_linter`: check that all infix operators have spaces around them. 49* `line_length_linter`: check the line length of both comments and code is less than 50 length. 51* `no_tab_linter`: check that only spaces are used, never tabs. 52* `object_length_linter`: check that function and variable names are not more than `length` characters. 53* `object_name_linter`: check that object names conform to a single naming 54 style, e.g. CamelCase, camelCase, snake_case, dotted.case, lowercase, 55 or UPPERCASE. 56* `open_curly_linter`: check that opening curly braces are never on their own 57 line and are always followed by a newline. 58* `paren_brace_linter`: check that there is a space between right parenthesis and an opening curly brace. 59* `semicolon_terminator_linter`: check that no semicolons terminate statements. 60* `seq_linter`: check for `1:length(...)`, `1:nrow(...)`, `1:ncol(...)`, 61 `1:NROW(...)`, and `1:NCOL(...)` expressions. These often cause bugs when the 62 right hand side is zero. It is safer to use `seq_len()` or `seq_along()` 63 instead. 64* `single_quotes_linter`: check that only single quotes are used to delimit 65 string constants. 66* `spaces_inside_linter`: check that parentheses and square brackets do not have 67 spaces directly inside them. 68* `spaces_left_parentheses_linter`: check that all left parentheses have a space before them 69 unless they are in a function call. 70* `todo_comment_linter`: check that the source contains no TODO comments (case-insensitive). 71* `trailing_blank_lines_linter`: check there are no trailing blank lines. 72* `trailing_whitespace_linter`: check there are no trailing whitespace characters. 73* `T_and_F_symbol_linter`: avoid the symbols `T` and `F` (for `TRUE` and `FALSE`). 74* `undesirable_function_linter`: report the use of undesirable functions, e.g. `options` or `sapply` and suggest an alternative. 75* `undesirable_operator_linter`: report the use of undesirable operators, e.g. `:::` or `<<-` and 76 suggest an alternative. 77* `unneeded_concatenation_linter`: check that the `c` function is not used without arguments nor 78 with a single constant. 79 80### References ### 81Most of the default linters are based on [Hadley Wickham's R Style Guide](http://r-pkgs.had.co.nz/style.html). 82 83## Project Configuration ## 84 85Lintr supports per-project configuration of the following fields. 86The config file (default file name: `.lintr`) is in [Debian Control Field Format](https://www.debian.org/doc/debian-policy/#document-ch-controlfields). 87 88- `linters` - see `?with_defaults` for example of specifying only a few non-default linters. 89- `exclusions` - a list of filenames to exclude from linting. You can use a 90 named item to exclude only certain lines from a file. 91- `exclude` - a regex pattern for lines to exclude from linting. Default is "# nolint" 92- `exclude_start` - a regex pattern to start exclusion range. Default is "# nolint start" 93- `exclude_end` - a regex pattern to end exclusion range. Default is "# nolint end" 94 95An example file that uses 120 character line lengths, excludes a couple of 96files and sets different default exclude regexs follows. 97``` 98linters: with_defaults(line_length_linter(120)) 99exclusions: list("inst/doc/creating_linters.R" = 1, "inst/example/bad.R", "tests/testthat/exclusions-test") 100exclude: "# Exclude Linting" 101exclude_start: "# Begin Exclude Linting" 102exclude_end: "# End Exclude Linting" 103``` 104 105With the following command, you can create a configuration file for `lintr` that ignores all linters that show at least one error: 106 107```r 108# Create configuration file for lintr 109# Source this file in package root directory 110 111# List here files to exclude from lint checking, as a character vector 112excluded_files <- c( 113 list.files("data", recursive = TRUE, full.names = TRUE), 114 list.files("docs", recursive = TRUE, full.names = TRUE), 115 list.files("inst/doc", recursive = TRUE, full.names = TRUE), 116 list.files("man", recursive = TRUE, full.names = TRUE), 117 list.files("vignettes", recursive = TRUE, full.names = TRUE) 118) 119 120### Do not edit after this line ### 121 122library(magrittr) 123library(dplyr) 124 125# Make sure we start fresh 126if (file.exists(".lintr")) { file.remove(".lintr") } 127 128# List current lints 129lintr::lint_package() %>% 130 as.data.frame %>% 131 group_by(linter) %>% 132 tally(sort = TRUE) %$% 133 sprintf("linters: with_defaults(\n %s\n dummy_linter = NULL\n )\n", 134 paste0(linter, " = NULL, # ", n, collapse = "\n ")) %>% 135 cat(file = ".lintr") 136 137sprintf("exclusions: list(\n %s\n )\n", 138 paste0('"', excluded_files, '"', collapse = ",\n ")) %>% 139 cat(file = ".lintr", append = TRUE) 140 141# Clean up workspace 142remove(excluded_files) 143``` 144 145The resulting configuration will contain each currently failing linter and the corresponding number of hits as a comment. Proceed by successively enabling linters, starting with those with the least number of hits. Note that this requires `lintr` 0.3.0.9001 or later. 146 147If you are developing a package, you can add `^\.lintr$` to your `.Rbuildignore` file using `usethis::use_build_ignore(".lintr")`. 148 149## Continuous integration ## 150If you want to run `lintr` on [Travis-CI](https://travis-ci.org) in order to check that commits and pull requests don't deteriorate code style, you will need 151to have Travis install the package first. This can be done by adding the 152following line to your `.travis.yml` 153 154```yaml 155r_github_packages: 156 - jimhester/lintr 157``` 158 159We recommend running `lintr::lint_package()` as an [after_success step in your build process](#non-failing-lints)] 160 161[lintr-bot](https://github.com/lintr-bot) will then add comments 162to the commit or pull request with the lints found and they will also be 163printed on Travis-CI. If you want to disable the commenting you can 164set the environment variable `LINTR_COMMENT_BOT=false`. 165 166### Non-failing Lints ### 167```yaml 168after_success: 169 - R CMD INSTALL $PKG_TARBALL 170 - Rscript -e 'lintr::lint_package()' 171``` 172 173Live example of a package using this setup: [`hibpwned`](https://github.com/lockedata/HIBPwned/blob/master/.travis.yml), [lintr-bot commenting on a PR](https://github.com/lockedata/HIBPwned/pull/30). 174 175## Installation of development version ## 176To install the latest development version of lintr from GitHub 177 178```r 179devtools::install_github("jimhester/lintr") 180``` 181 182 183## Editors setup ## 184 185### RStudio ### 186lintr lints are automatically displayed in the RStudio Markers pane, Rstudio versions (> v0.99.206). 187![RStudio Example](http://i.imgur.com/PIKnpbn.png "Rstudio Example") 188 189#### Installation #### 190Install lintr, type `install.packages("lintr")` in the Console. 191 192In order to show the "Markers" pane in RStudio: 193Menu "Tools" -> "Global Options...", a window with title "Options" will pop up. In that window: Click "Code" on the left; Click "Diagnostics" tab; check "Show diagnostics for R". 194 195To lint a source file `test.R` type in the Console `lintr::lint("test.R")` and look at the result in the "Markers" pane. 196 197This package also includes two addins for linting the current source and package. 198To bind the addin to a keyboard shortcut navigate to Tools > addins > 199Browse Addins > Keyboard Shortcuts. It's recommended to use Alt+Shift+L for 200linting the current source code and Ctrl+Shift+Alt+L to code the package. 201These are easy to remember as you are Alt+Shift+L(int) ;) 202 203### Emacs ### 204lintr has [built-in integration](http://www.flycheck.org/en/latest/languages.html#r) with [flycheck](https://github.com/flycheck/flycheck) versions greater than `0.23`. 205![Emacs Example](http://i.imgur.com/vquPht3.gif "Emacs Example") 206 207#### Installation #### 208lintr is fully integrated into flycheck when using [ESS](http://ess.r-project.org/). See the 209installalation documentation for those packages for more information. 210 211#### Configuration #### 212You can also configure what linters are used. e.g. using a different line length cutoff. 213- `M-x customize-option` -> `flycheck-lintr-linters` -> `with_defaults(line_length_linter(120))` 214 215### Vim 216lintr can be integrated with 217[syntastic](https://github.com/scrooloose/syntastic) for on the fly linting. 218 219![Vim Example](http://i.imgur.com/fR6Os5M.gif "Vim Example") 220 221#### Installation #### 222Put the file [syntastic/lintr.vim](inst/syntastic/lintr.vim) 223in `syntastic/syntax_checkers/r`. If you are using 224[pathogen](https://github.com/tpope/vim-pathogen) this directory is 225`~/.vim/bundles/syntastic/syntax_checkers/r`. 226 227You will also need to add the following lines to your `.vimrc`. 228```vim 229let g:syntastic_enable_r_lintr_checker = 1 230let g:syntastic_r_checkers = ['lintr'] 231``` 232#### Configuration #### 233You can also configure what linters are used. e.g. using a different line length cutoff. 234```vim 235let g:syntastic_r_lintr_linters = "with_defaults(line_length_linter(120))" 236``` 237 238### Sublime Text 3 ### 239lintr can be integrated with 240[Sublime Linter](https://github.com/SublimeLinter/SublimeLinter3) for on the fly linting. 241 242![Sublime Example](http://i.imgur.com/3pua2yz.gif "Sublime Example") 243 244#### Installation #### 245Simply install `sublimeLinter-contrib-lintr` using [Package Control](https://packagecontrol.io/). 246 247For more information see [Sublime Linter Docs](http://sublimelinter.readthedocs.org/en/latest/installation.html#installing-via-pc) 248 249#### Configuration #### 250You can also configure what linters are used. e.g. disabling the assignment linter and using a different line length cutoff. 251In the SublimeLinter User Settings 252``` 253{ 254 "linters": { 255 "lintr": { 256 "linters": "with_defaults(assignment_linter = NULL, line_length_linter(120))" 257 } 258 } 259} 260``` 261 262### Atom ### 263lintr can be integrated with 264[Linter](https://github.com/atom-community/linter) for on the fly linting. 265 266![Atom Example](http://i.imgur.com/E1Isi4T.png "Atom Example") 267 268#### Installation #### 269Simply install `linter-lintr` from within Atom or on the command line with: 270```bash 271apm install linter-lintr 272``` 273 274For more information and bug reports see [Atom linter-lintr](https://github.com/AtomLinter/linter-lintr). 275