knitr::opts_chunk$set(
  results = "asis",
  echo = FALSE,
  comment = FALSE,
  warning = FALSE,
  message = FALSE,
  fig.align = "center"
)
library(nomnoml)

Introduction

Supplementary utils for CRAN maintainers and R package developers in the pacs package. The wide range of tools to achieve healthy R environment and make the R developer life easier. Each of the function was inspired be everyday challenges which have to be faced by the experienced R developer in the production quality agile project. These tools should be universal in different work environments.

Objectives

  1. Control Complexity of developed packages.
  2. Support the process of adding/updating packages.
  3. Validate the library.

Reproducible R Environment

Tinyverse

The R community tinyverse movement is a tryout to create a new package development standards. The clue is the TINY part here. The last years of R package development were full of high number of dependencies temptations. tinyverse means as least dependencies as possible as R package dependencies matter. Every dependency you add to your project is an invitation to break your project.

More information is available in the tinyverse vignette.

Think Tiny as a Developer

Minimize dependencies and avoid installing "nice to have" packages. The objective should be to have zero dependencies in an R package. That is why tinytest was created or renv has zero dependencies.

Check a package dependencies exposed to the end users with pacs::pac_deps_user, these are packages installed with the install.packages. When adding a package to Depends, Imports or LinkingTo, then we impact end users when they invoke install.packages. On the other hand if a package is added to Suggests, this impacts mainly developers e.g. R CMD CHECK, check all developer exposed packages with pacs::pac_deps_dev.

The main strategy should be to prefer usage of pacs::pacs_base() packages (already installed in R) and packages with only a few dependencies (the best zero like jsonlite).

One method of reducing number of dependencies (exposed to end users) is to transfer the package from Imports to Suggests and load it in the delayed manner, or not include it at all. Check the tinyverse vignette for more details.

func <- function() {
  if (requireNamespace("PACKAGE", quietly = TRUE)) {
    # regular code 
  } else {
    stop("Please install the PACKAGE to use the func function")
  }
}

Add/Update a package {.mybreak}

Important topics to consider to have a secure, light and healthy library. We should be careful when adding/updating packages. The updating part could be surprising nevertheless e.g. in bigger projects we want to have a stable library for each product release.
Tools: pacs, remotes, CRAN packages websites, cranlogs, and repository website like github.
Example: We think of adding/updating the parsnip package.

```{nomnoml, fig.width=16, fig.height=9, svg=FALSE}

stroke: black

padding: 0

spacing: 0

fontSize: 12

.box:

[Add a Package| [YAGNI]-[Add a Package] [LIFE DURATION] - [Add a Package] [CRAN CHECK PAGE] - [Add a Package] [VERSION]-[Add a Package] [Add a Package]-[NEW DEPENDENCIES] [Add a Package]-[REPO ACTIVITY] [Add a Package]-[COVR] [Add a Package]-[DOWNLOADS] ]

```{nomnoml, fig.width=16, fig.height=8, svg=FALSE}
#stroke: black
#padding: 0
#spacing: 0
#fontSize: 12
#.box: 
[<frame>Update a Package|
[YAGNI]-[Update a Package]
[LIFE DURATION]-[Update a Package]
[CRAN CHECK PAGE]-[Update a Package]
[Update a Package]-[NEW DEPENDENCIES]
[Update a Package]-[NEWS]
[Update a Package]-[SCOPE]
]

Validate {.mybreak}

We could validate numerous things like: R library, R package or renv lock file. Even if we will not find any obvious problems we will need a proof that the environment is validated which is often the authorities' requirement. R library could be easily broken with functions like remotes::install_version or remotes::install_github(..., dependencies = FALSE). On the other hand the renv lock file could be built manually or by an external automation pipeline. We could control many risks with pacs::lib_validate, pacs::pac_validate and pacs::lock_validate functions.

```{nomnoml, fig.width=16, fig.height=6, svg=FALSE}

stroke: black

padding: 0

spacing: 0

fontSize: 12

.box:

[Validate| [VERSIONS]-[Validate] [CRAN CHECK PAGES]-[Validate] [Validate]-[Built] [Validate]-[LIFE DURATIONS] [Validate]-[NEWEST] ]

- **LIFE DURATIONS**, life duration of the version where we should expected at least 14 days.
- **VERSIONS**, do we have the same versions as required by DESCRIPTION files.
- **NEWEST**, is the newest version.
- **BUILT**, packages installed with a previous version of R could not work correctly with the new version of R. Mostly for local usage (without `renv`) and a minor (last number) R version update.
- **CRAN CHECK PAGE**, CRAN checks on variety of servers. We could extract checks for all CRAN packages with `pacs::checked_packages()`.
- **OTHER**

```r
# assesing life durations could be time consuming for a bigger library.
pacs::lib_validate(
  checkred = list(
    scope = c("ERROR", "FAIL"),
    flavors = pacs::cran_flavors()$Flavor
  ),
  lifeduration = FALSE
)

Conclusion

Think tiny and be minimalist for better UX and easier development work.

Contact

Maciej Nasinski

References



Polkas/pacs documentation built on Oct. 2, 2024, 8:04 p.m.