Package dev with {fusen} & {attachment}: load all functions of a flat, manage qmd and auto-fill Remotes field

Author : Sébastien Rochette
Categories : development, fusen, package, Rmarkdown, thinkrverse, tips
Tags : attachment, fusen, package, thinkr-package
Date :

One aim of our open-source packages at ThinkR is to make our development workflows easier. {attachment} and {fusen} are developed maintained to help packages development and maintenance. Inception… If they help us every day, they can probably help you as well! In this blog post, I present the lastest changes of these two packages.

If you want to know how they work for your every day life, you may want to have a look at the Readmes:

hex log of fusen package

Install from r-universe

Both these packages are available on CRAN.
However, if you want to get the latest version, without being constrained by GitHub (token needed, some organisations IT blocking GitHub, …), you may want to install them using as source repository.

# Enable repository from thinkr-open
options(repos = c(
  thinkropen = '',
  CRAN = ''))
# Download and install attachment & fusen in R

R-runiverse is a wonderful platform started and developed by Jeroen Ooms for ROpenSci.
The R-universe platform allows to search and install R packages directly coming from the developers, without the risk of them being removed without the consent of these same developers.
You directly have access to the documentation, as well as indicators of maintenance of the packages.

:name status badge
:total status badge

Quick NEWS in {fusen} v0.4.1

New features

See below for a longer description

  • Load all function chunks of the flat file currently opened with load_flat_functions() (Like a load_all() for a flat file)
  • Allow to inflate() a Quarto “.qmd” flat file (#160)


  • Fix HTML5 doc

Quick NEWS in {attachment} v0.3.0

New features

See below for a longer description

  • find_remotes() and set_remotes_to_desc() now detects github, gitlab, git, bitbucket, local installations to add to the “Remotes:” part of the DESCRIPTION file (@MurielleDelmotte)
  • Quarto documents can be parsed with att_from_qmds() as an alias of att_from_rmds().

Minor changes

  • Documentation for bookdown and quarto dependencies extraction updated

Bug fixes

  • Allow to use dependencies after att_amend_desc() #52


hex log of fusen package

{fusen} – Can I load all functions of the current flat file during development without having to inflate()?

Yes. You can run and load function chunks only in the currently opened flat file with load_flat_functions().
With long flat file currently in development, and before inflate(), it is sometimes difficult to run all chunks needed after multiple modifications. This can also be useful when you start again your development the day after.

load_flat_functions() is like a load_all() for a flat file, although it does not account for dependencies.

In the console, run:


You can also run function chunks of a specific flat file with:

fusen::load_flat_functions(flat_file = "dev/flat_full.Rmd")

{fusen} – Can I inflate a Quarto qmd file?

Yes you can. As long as what you include in your qmd flat file is good for a R package vignette, you can use the qmd format.
This will not really change the output of anything as the flat file is not meant to be rendered.
The vignette created from this flat file will still be a Rmd file.
But why not!?

Hence, you can add a flat file and change its extension to “.qmd” if you like.


{attachment} – Propose content for the “Remotes” field of your DESCRIPTION

set_remotes_to_desc() adds packages that were installed from other source than CRAN to Remotes: field in DESCRIPTION.

For instance:

  • For GitHub : Remotes: thinkr-open/attachment
  • For GitLab : Remotes: gitlab::jimhester/covr
  • For Git : Remotes: git::https://theurl/package_git.git
  • For local package: Remotes: local::c:\mylocalpackage or Remotes: local::subdir/mylocalpackage
  • For Bioconductor : Remotes: bioc::3.3/package_bioc

You may want to run it after att_amend_desc().

att_amend_desc() %>%

If you only want to find if packages were installed from other source than CRAN, without amending DESCRIPTION, you can use find_remotes().

You can use it on a vector of packages names

find_remotes(pkg = c("attachment", "desc", "glue"))

You may also want to combine it to att_from_description()

att_from_description() %>%

{attachment} – Use {attachment} with {bookdown} / {pagedown} / {quarto} and dependencies of the code included

Dependencies of your Bookdown can be automatically discovered and installed if you use a “DESCRIPTION” file in combination with {attachment}.
Indeed, you can use this procedure to create the DESCRIPTION file for local installation or for Continuous Integration with GitLab Pages or GitHub Actions.
See for instance, the GitLab CI workflows in {gitlabr}:

  1. Create a “DESCRIPTION” file
  1. Fill the “DESCRIPTION” file using attachment::att_to_desc_from_is().
    Note that to include it directly in CI (as proposed in {gitlabr} templates), you may need to set att_to_desc_from_is(must.exist = FALSE).
    Note that att_from_rmds() also works for “.qmd” documents. You can use att_from_qmds() if you want, although for now there is no difference and it will also parse “.Rmd” documents.
# bookdown Imports are in Rmds
imports <- c("bookdown", attachment::att_from_rmds("."))
  path.d = "DESCRIPTION",
  imports = imports, suggests = NULL, 
  must.exist = FALSE
  1. Install dependencies from the DESCRIPTION file
# install.packages("remotes")
  1. Build your {bookdown} / {pagedown} / {quarto}


hex log of fusen package

{attachment} and {fusen} together in your workflows

A quick note to remind you that {fusen} uses {attachment} behind the scene.

If you inflate() your flat file, then attachment::att_amend_desc() will be run too.
As it is run without option, you can prevent {attachment} to be run with:

fusen::inflate(document = FALSE)
# I would add this line after, to jump to your own version of attachment::att_amend_desc()
rstudioapi::navigateToFile("dev/0-dev_history.Rmd", line = 92)

Then, in your “dev/0-dev_history.Rmd”, you can add your own specific code.
For instance, in {attachment} itself, in “dev/dev_history.R”, you can find this:

  pkg_ignore = c("remotes", "i", "usethis", "rstudioapi", "renv",
                 "gitlab", "git", "local", "find.rscript", "bioc"), #i
  extra.suggests = c("testthat", "rstudioapi", "renv", "lifecycle"), #"pkgdown", "covr",
  dir.t = "",
  normalize = FALSE)

Enjoy this two packages individually or their combination!


Also read