Author: Sébastien Rochette
Date: 2023-06-19

# Deal with check outputs

#### Sébastien Rochette

#### 2023-06-19

    library(checkhelper)

## Create a fake package for examples

- The function has no visible global variables and missing documented functions
- The function has `@export` tag but not `@return` tag

    # Create fake package ----
    pkg_path <- tempfile(pattern = "pkg.")
    dir.create(pkg_path)

    # Create fake package
    usethis::create_package(pkg_path, open = FALSE)

    #> ✔ Setting active project to '/tmp/RtmpOmxnjd/pkg.e0fa160b8054'
    #> ✔ Creating 'R/'
    #> ✔ Writing 'DESCRIPTION'
    #> ✔ Writing 'NAMESPACE'
    #> ✔ Writing 'pkg.e0fa160b8054.Rproj'
    #> ✔ Adding '^pkg\\.e0fa160b8054\\.Rproj$' to '.Rbuildignore'
    #> ✔ Adding '.Rproj.user' to '.gitignore'
    #> ✔ Adding '^\\.Rproj\\.user$' to '.Rbuildignore'
    #> ✔ Setting active project to '/mnt/Data/github/ThinkR-open/checkhelper'

    # Create function no visible global variables and missing documented functions
    cat("
    #' Function
    #' @importFrom dplyr filter
    #' @export
    my_fun <- function() {
    data %>%
    filter(col == 3) %>%
    mutate(new_col = 1) %>%
    ggplot() +
      aes(x, y, colour = new_col) +
      geom_point()
    }
    ", file = file.path(pkg_path, "R", "function.R"))

    attachment::att_amend_desc(path = pkg_path)

    #> Saving attachment parameters to yaml config file
    #> Updating pkg.e0fa160b8054 documentation
    #> ℹ Loading pkg.e0fa160b8054Writing ']8;;file:///tmp/RtmpOmxnjd/pkg.e0fa160b8054/NAMESPACENAMESPACE]8;;'Writing ']8;;file:///tmp/RtmpOmxnjd/pkg.e0fa160b8054/NAMESPACENAMESPACE]8;;'Writing ']8;;ide:run:pkgload::dev_help('my_fun')my_fun.Rd]8;;'ℹ Loading pkg.e0fa160b8054[+] 1 package(s) added: dplyr.

    # Files of the package
    fs::dir_tree(pkg_path, recurse = TRUE)

## Avoid missing return value for exported functions

CRAN does not like when exported functions do not have returned value. Using `find_missing_tags()`, you can detect exported functions with missing or empty `@return` tag

    find_missing_tags(pkg_path)

    #> ℹ Loading pkg.e0fa160b8054
    #> Missing or empty return value for exported functions: my_fun
    #>
    #>
    #>
    #> ℹ Loading pkg.e0fa160b8054

    #> $package_doc
    #> # A tibble: 0 × 0
    #>
    #> $data
    #> # A tibble: 0 × 0
    #>
    #> $functions
    #> # A tibble: 1 × 11
    #>      id filename   topic  has_e…¹ has_r…² retur…³ has_n…⁴ rdnam…⁵
    #>   <int> <chr>      <chr>  <lgl>   <lgl>   <chr>   <lgl>   <chr>
    #> 1     1 function.R my_fun TRUE    FALSE   ""      FALSE   my_fun
    #> # … with 3 more variables: not_empty_return_value <lgl>,
    #> #   test_has_export_and_return <chr>,
    #> #   test_has_export_or_has_nord <chr>, and abbreviated variable
    #> #   names ¹​has_export, ²​has_return, ³​return_value, ⁴​has_nord,
    #> #   ⁵​rdname_value

## Deal with check outputs

- `get_no_visible()` runs the checks and extract no visible global variables and missing documented functions
- `print_globals()` proposes a template to add missing global variables in a `globals.R` file. Note that you can also transform all these variables with `.data[[variable]]`

    # Get globals
    globals <- get_no_visible(pkg_path, quiet = TRUE)
    globals

    #> $globalVariables
    #> # A tibble: 4 × 7
    #>   notes             filep…¹ fun   is_fu…² is_gl…³ varia…⁴ propo…⁵
    #>   <chr>             <chr>   <chr> <lgl>   <lgl>   <chr>   <chr>
    #> 1 my_fun: no visib… -       my_f… FALSE   TRUE    data    " impo…
    #> 2 my_fun: no visib… -       my_f… FALSE   TRUE    x        <NA>
    #> 3 my_fun: no visib… -       my_f… FALSE   TRUE    y        <NA>
    #> 4 my_fun: no visib… -       my_f… FALSE   TRUE    new_col  <NA>
    #> # … with abbreviated variable names ¹​filepath, ²​is_function,
    #> #   ³​is_global_variable, ⁴​variable, ⁵​proposed
    #>
    #> $functions
    #> # A tibble: 5 × 7
    #>   notes             filep…¹ fun   is_fu…² is_gl…³ varia…⁴ propo…⁵
    #>   <chr>             <chr>   <chr> <lgl>   <lgl>   <chr>   <chr>
    #> 1 my_fun: no visib… -       my_f… TRUE    FALSE   %>%     <NA>
    #> 2 my_fun: no visib… -       my_f… TRUE    FALSE   mutate  <NA>
    #> 3 my_fun: no visib… -       my_f… TRUE    FALSE   ggplot  <NA>
    #> 4 my_fun: no visib… -       my_f… TRUE    FALSE   aes     <NA>
    #> 5 my_fun: no visib… -       my_f… TRUE    FALSE   geom_p… <NA>
    #> # … with abbreviated variable names ¹​filepath, ²​is_function,
    #> #   ³​is_global_variable, ⁴​variable, ⁵​proposed

    # Print globals to copy-paste
    print_globals(globals)

    #> --- Functions to add in NAMESPACE (with @importFrom ?) ---
    #>
    #> my_fun: %>%, aes, geom_point, ggplot, mutate
    #>
    #> --- Potential GlobalVariables ---
    #> -- code to copy to your R/globals.R file --
    #>
    #> globalVariables(unique(c(
    #> # my_fun:
    #> "data", "new_col", "x", "y"
    #> )))

    # Store in package using usethis::use_r("globals")