https://github.com/etiennebacher/flir
Find and Fix Lints in R Code
https://github.com/etiennebacher/flir
Last synced: 29 days ago
JSON representation
Find and Fix Lints in R Code
- Host: GitHub
- URL: https://github.com/etiennebacher/flir
- Owner: etiennebacher
- License: other
- Created: 2023-08-06T07:23:49.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-25T10:56:57.000Z (about 2 months ago)
- Last Synced: 2025-03-13T14:19:43.183Z (about 1 month ago)
- Language: R
- Homepage: https://flir.etiennebacher.com
- Size: 3.11 MB
- Stars: 52
- Watchers: 1
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.Rmd
- Changelog: NEWS.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - etiennebacher/flint - Find and Fix Lints in R Code (R)
README
---
output: github_document
---```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```# flir
(pronounced "fleer" as in "beer")
[](https://github.com/etiennebacher/flir/actions/workflows/R-CMD-check.yaml)
---
:information_source: Until v0.2.1 (included), this package was named `flint`. In v0.3.0, it was renamed `flir`.
---
`flir` is a small R package to find and replace lints in R code.
* Lints detection with `lint()`
* Automatic replacement of lints with `fix()`
* Compatibility with (some) `{lintr}` rules
* Fast`flir` is powered by [`astgrepr`](https://github.com/etiennebacher/astgrepr/),
which is itself built on the Rust crate [`ast-grep`](https://ast-grep.github.io/).## Installation
``` r
install.packages('flir', repos = c('https://etiennebacher.r-universe.dev', 'https://cloud.r-project.org'))
```**Note:** using `remotes::install_github()`, `devtools::install_github()`,
or `pak::pak()` without specifying the R-universe repo will require you to
[setup Rust](https://www.rust-lang.org/tools/install) to build the package.## Usage
Optional setup:
* `setup_flir()`: creates the folder `flir` and populates it with built-in rules
as well as a cache file. You can modify those rules or add new ones if you
want more control.You can use `flir` as-is, without any setup. However, running `setup_flir()`
enables the use of caching, meaning that the subsequent runs will be faster. It
is also gives you a place where you can store custom rules for your
project/package.The everyday usage consists of two functions:
* `lint()` looks for lints in R files;
* `fix()` looks for lints in R files and automatically applies their replacement
(if any).One can also experiment with `flir::lint_text()` and `flir::fix_text()`:
```{r}
flir::lint_text(
"
any(is.na(x))
any(duplicated(y))
"
)
flir::fix_text(
"
any(is.na(x))
any(duplicated(y))
"
)
```## Real-life examples
I tested `flir` on several packages while developing it. I proposed some pull
requests for those packages. Here are a few:* `ggplot2`: [#6050](https://github.com/tidyverse/ggplot2/pull/6050/files) and [#6051](https://github.com/tidyverse/ggplot2/pull/6051/files)
* `marginaleffects`: [#1171](https://github.com/vincentarelbundock/marginaleffects/pull/1171/files) and [#1177](https://github.com/vincentarelbundock/marginaleffects/pull/1177/files)
* `targets`: [#1325](https://github.com/ropensci/targets/pull/1325/files)
* `tinytable`: [#325](https://github.com/vincentarelbundock/tinytable/pull/325/files)
* `usethis`: [#2048](https://github.com/r-lib/usethis/pull/2048/files)Except for some manual tweaks when the replacement was wrong (I was testing
`flir` after all), all changes were generated by `flir::fix_package()` or
`flir::fix_dir()`.## Comparison with existing tools
The most used tool for lints detection in R is `lintr`. However, `lintr`'s
performance is not optimal when it is applied on medium to large packages. Also,
`lintr` cannot perform automatic replacement of lints.`styler` is a package to clean code by fixing indentation and other things, but
doesn't perform code replacement based on lints.`flir` is quite performant. This is a small benchmark on 3.5k lines of code with
a few linters:```{r}
file <- system.file("bench/test.R", package = "flir")bench::mark(
lintr = lintr::lint(
file,
linters = list(
lintr::any_duplicated_linter(),
lintr::any_is_na_linter(),
lintr::matrix_apply_linter(),
lintr::function_return_linter(),
lintr::lengths_linter(),
lintr::T_and_F_symbol_linter(),
lintr::undesirable_function_linter(),
lintr::expect_length_linter()
)
),
flir = flir::lint(
file,
linters = list(
flir::any_duplicated_linter(),
flir::any_is_na_linter(),
flir::matrix_apply_linter(),
flir::function_return_linter(),
flir::lengths_linter(),
flir::T_and_F_symbol_linter(),
flir::undesirable_function_linter(),
flir::expect_length_linter()
),
verbose = FALSE,
open = FALSE
),
check = FALSE
)
```## Why the name "flir"?
`flir` was originally named `flint` but I had to rename it to avoid conflicts with
a package named `flint` on CRAN.`flir` stands for "**F**ix **L**ints **I**n **R**".
## Contributing
Did you find some bugs or some errors in the documentation? Do you want
`flir` to support more rules?Take a look at the [contributing
guide](https://flir.etiennebacher.com/CONTRIBUTING.html) for
instructions on bug report and pull requests.## Acknowledgements
The website theme was heavily inspired by Matthew Kay’s `ggblend`
package: .