https://github.com/DanChaltiel/autoimport
A toolbox to automatically generate @importFrom roxygen tags from R files.
https://github.com/DanChaltiel/autoimport
Last synced: 5 months ago
JSON representation
A toolbox to automatically generate @importFrom roxygen tags from R files.
- Host: GitHub
- URL: https://github.com/DanChaltiel/autoimport
- Owner: DanChaltiel
- Created: 2023-03-21T17:30:46.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-14T08:20:35.000Z (5 months ago)
- Last Synced: 2024-11-14T08:30:49.573Z (5 months ago)
- Language: R
- Homepage: https://danchaltiel.github.io/autoimport/
- Size: 1.19 MB
- Stars: 10
- Watchers: 2
- Forks: 1
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: NEWS.md
Awesome Lists containing this project
- jimsghstars - DanChaltiel/autoimport - A toolbox to automatically generate @importFrom roxygen tags from R files. (R)
README
# autoimport
[](http://www.gnu.org/licenses/gpl-3.0.html)
[](https://lifecycle.r-lib.org/articles/stages.html#stable)
[](https://CRAN.R-project.org/package=autoimport)
[](https://github.com/DanChaltiel/autoimport)
[](https://github.com/DanChaltiel/autoimport/actions/workflows/R-CMD-check.yaml)`autoimport` is a package designed to easily add `@importFrom` roxygen tags to all your functions.
## Concept
When importing functions to use them in a package, you have the choice between `@import pkg` to import a whole package and `@importFrom pkg fun1 fun2` to import only a few functions.
The `@importFrom` syntax is preferable, as it has been stressed out that importing whole packages "makes your code harder to read (you can't tell where a function is coming from), and if you `@import` many packages, it increases the chances of function name conflicts."
The [R Packages (2e)](https://r-pkgs.org/dependencies-in-practice.html#in-code-below-r) guidelines say that here are two reasonable locations for @importFrom :
> - As close as possible to the usage of the external function. With this mindset, you would place @importFrom in the roxygen comment above the function in your package where you use the external function.
>
> - In a central location. This approach keeps all @importFrom tags together, in a dedicated section of the package-level documentation file (which can be created with `usethis::use_package_doc()`).I find the first option much clearer, but, as they warn, it tends to get very tedious to keep track of all the function calls.
Therefore, `autoimport` will parse your code, detect all the functions you import, and then add the right @importFrom tags in the right place. Just like that!
## Installation
For now, only the development version is available:
``` r
# Install development version on Github
pak::pak("DanChaltiel/autoimport")
```## Getting started
Simply load the package and run the function!
``` r
devtools::load_all(".")
autoimport::autoimport()
```The first run will take some time, but a cache system is implemented so that next runs are faster.
Then, you can see the diff and accept the changes using the shiny widget:
``` r
autoimport::import_review()
```## Important notes
- `autoimport` will guess the potential source of your functions based on (1) the packages currently loaded in your environment (e.g. via `library()`), and (2) the packages listed as dependencies in DESCRIPTION.
- `load_all(".")` is required for autoimport to have access to the package's private functions, for example so that `dplyr::filter()` cannot mask `yourpackage:::filter()`.
- Some package guesses are bound to be wrong, in which case you should use `usethis::use_import_from()`. See "Limitations" below for more details.
## Limitations
Autoimport is based on `utils::getSrcref()` and share the same limits. Therefore, some function syntaxes are not recognized and `autoimport` will try to remove their `@importFrom` from individual functions:
- Operators (`@importFrom dplyr %>%`, `@importFrom rlang :=`, ...)
- Functions called by name (e.g. `sapply(x, my_fun))`
- Functions used inside strings (e.g. `glue("my_fun={my_fun(x)}")`)To keep them imported, you should either use a prefix (`pkg::my_fun`) or import them in your package-level documentation, as this file is ignored by default (due to `ignore_package=TRUE`).
For that, `usethis::use_import_from()` and `usethis::use_pipe()` are your friends!
Also, note that R6 methods calls trigger a "not found" warning (WIP, see #21).
## Cache system
As running `autoimport()` on a large package can take some time, a cache system is implemented, by default in file `inst/autoimport_cache.rds`.
Any function not modified since last run should be taken from the cache, resulting on a much faster run.
In some seldom cases, this can cause issues with modifications in DESCRIPTION or IMPORTLIST not being taken into account. Run `clean_cache()` to remove this file, or use `use_cache="write"`.
## Algorithm
When trying to figure out which package to import a function from, `autoimport()` follows this algorithm:
- If the function is prefixed with the package, ignore
- Else, if the function is already mentioned in NAMESPACE, use the package
- Else, if the function is exported by only one package, use this package
- Else, ask the user from which package to import the function
- Else, warn that the function was not foundNote that this algorithm is still a bit experimental and that I could only test it on my few own packages. Any feedback is more than welcome!
## Style
As I couldn't find any standardized guideline about the right order of `roxygen2` tags, `autoimport` puts them:
- in place of the first `@importFrom` tag if there is one
- just before the function call otherwise