À l’issue de ce tutoriel, nous aurons créé un package, qui inclue potentiellement du code C++ (via Rcpp et RcppArmadillo), documenté avec roxygen2, avec des tests unitaires via testthat, partagé sur GitHub, maintenu à l’aide de Travis-CI, avec un site Internet avec pkgdown.

TOO LONG, DIDN’T READ

library(devtools)
library(usethis)
library(testthat)
library(pkgdown)
remotes::install_github("ropenscilabs/travis")
remotes::install_github("ropenscilabs/tic")

### CREATE PACKAGE
create_package("name")
use_package_doc()
use_roxygen_md()

### ADD DESCRIPTION FILES
edit_file("DESCRIPTION")
use_mit_license("Firstname Lastname")

### ADD DEPENDENCIES (IF APPLICABLE)
use_package("name_of_package")

### ADD R FUNCTIONS AND THEIR DOCUMENTATION
use_r("name_of_r_file")
# Code > Insert Roxygen Skeleton (Ctrl+Alt+Shift+R)

### ADD VIGNETTE-LIKE RMD TO YOUR PACKAGE
use_readme_rmd()

### ADD UNITARY TESTS
use_testthat()
use_test("name_of_test_file")
test()

### ADD RCPP SUPPORT
use_rcpp()
use_rcpp_armadillo()
# File > New File > C++ File
    #include <Rcpp.h>  >>>  #include <RcppArmadillo.h>
    // [[Rcpp::depends(RcppArmadillo)]]
# BUILD NOW AT LEAST ONCE, ELSE DEVTOOLS::DOCUMENT() WILL FAIL

### SHARE TO GITHUB
use_git()
# Push to new repo: https://gist.github.com/mindplace/b4b094157d7a3be6afd2c96370d39fad

### LINK TO TRAVIS-CI
use_travis()
# Go to travis-ci.org and link your repo

### ADD PAT TO R
# Create PAT: https://github.com/settings/tokens with "public_repo" scope.
# Add the PAT to .Renviron
edit_r_environ()
# GITHUB_PAT=<GENERATED PAT>
git_vaccinate()

[travis::travis_set_pat() | BUT NEEDS MORE PERMISSIONS]

### SETTING A WEBPAGE FOR YOUR PACKAGE
use_pkgdown()
use_pkgdown_travis()

### CREATE SSH KEYPAIR FOR TRAVIS DEPLOY
# Run use_travis_deploy_manual.R

#----- 'use_travis_deploy', but manual

# Generate SSH keypair
key <- openssl::rsa_keygen()
pub_key <- tic:::get_public_key(key)
private_key <- tic:::encode_private_key(key)

# Go to the GitHub repository page - then Settings > Deploy keys,
# add the public key there (check the box for write-access).
title <- "travis+tic"
public_key <- travis:::create_key_data(pub_key, title)

# Go to the Travis repository page - then More Options > Settings.
# Add an environment-variable named id_rsa. Paste your clipboard-contents into its value.
# Make sure you are not displaying the value in the log. Save.
name <- "id_rsa"
private_key

#----- End of 'use_travis_deploy', but manual

# Go to the GitHub repository page - then Settings > Deploy keys, add the public key there (check the box for write-access).
# Go to the Travis repository page - then More Options > Settings. Add an environment-variable named id_rsa. Paste your clipboard-contents into its value. Make sure you are not displaying the value in the log. Save.

[OR travis::use_travis_deploy() | TOO MANY PERMISSIONS]

### ADD TEST COVERAGE REPORTS
use_coverage(type="codecov")
# Go to the codecov repository page - then Add a repository > 'repo_name' > Copy Token. Then go to the Travis repository page - then More Options > Settings. Add an environment-variable named CODECOV_TOKEN. Paste your clipboard-contents into its value. 

Prérequis

Un package minimal

Une première fonction R

Ajoutons notre première fonction R pour exemple.

La documentation Roxygen (repérée par les #' et les balises commençant par @) est essentielle, non seulement pour rendre votre package compréhensible, mais surtout parce que roxygen2 va gérer le NAMESPACE automatiquement. En particulier, la balise @export spécifie que la fonction matrix_mult sera exportée, donc visible et utilisable pour l’utilisateur du package. Le squelette Roxygen se trouve dans Code > Insert Roxygen Skeleton (ou Ctrl+Alt+Shift+R).

pkgdown

On peut créer une page de documentation (type vignette) pour le package. En particulier, ce sera la page d’accueil du site web associé à votre package.

Cette page est générée principalement par le fichier ‘README.Rmd’ (à modifier à la main) et les documentations ‘.Rd’ du dossier ‘/man’ générées par Roxygen.

Tests unitaires

On ajoute des tests unitaires simples à notre package.

On peut vérifier que nos tests fonctionnent avec

Ajout de Rcpp et RcppArmadillo

On ajoute le support Rcpp et RcppArmadillo.

Ne lancez pas devtools::document() malgré l’ordre de usethis ! L’instruction échoue sans fichier source et sans build. Commençons donc par ajouter un fichier source.

Encore une fois, le squelette Roxygen est important pour documenter la fonction, mais aussi pour préciser qu’il faut exporter la fonction dans le NAMESPACE.

Pour éviter des problèmes mémoires et autres amuseries quand on détache le package, on ajoute une fonction .onUnload qui retire le DLL :

A ce niveau, il est nécessaire de construire une première fois le package (Ctrl+Shift+B), puis de lancer devtools::document() (Ctrl+Shift+D) pour mettre à jour la documentation et le namespace.

Rajoutons aussi un test unitaire pour notre nouvelle fonction .cpp :

Intégration à GitHub

Il est temps d’intégrer votre package à Git.

Créez un nouveau repo sur votre compte GitHub et pushez votre package (voir https://gist.github.com/mindplace/b4b094157d7a3be6afd2c96370d39fad pour la procédure à suivre, retranscris ci-dessous au cas où le lien url venait à être cassé).

Create a remote, empty folder/repository on Github.

  1. Login to your Github account.

  2. At the top right of any Github page, you should see a ‘+’ icon. Click that, then select ‘New Repository’.

  3. Give your repository a name–ideally the same name as your local project. If I’m building a travel application, its folder will be called ‘travel-app’ on my computer, and ‘travel-app’ will be the Github repository name as well.

  4. Click ‘Create Repository’. The next screen you see will be important, so don’t close it.

Connect your local project folder to your empty folder/repository on Github.

The screen you should be seeing now on Github is titled ‘Quick setup — if you’ve done this kind of thing before’.

Copy the link in the input right beneath the title, it should look something like this: https://github.com/mindplace/test-repo.git This is the web address that your local folder will use to push its contents to the remote folder on Github.

  1. Go back to your project in the terminal/command line.

  2. In your terminal/command line, type git remote add origin [copied web address]

Example: git remote add origin https://github.com/mindplace/test-repo.git

  1. Push your branch to Github: git push origin master

  2. Go back to the folder/repository screen on Github that you just left, and refresh it. The title ‘Quick setup — if you’ve done this kind of thing before’ should disappear, and you should see your files there.

Intégration continue avec Travis-CI

Commencez par créer un compte sur https://travis-ci.org/ si ce n’est pas déjà fait (il faudra probablement vous connecter avec votre compte GitHub). L’intégration avec Travis-CI est rapide et sans douleur :

Vos prochains pushes seront désormais testés avec Travis. Effectuez un commit-push maintenant.

Push sans faire appel à Travis

Soyons green ! Il est possible d’effectuer des pushes sans faire appel à Travis. Pour ceci, il faut que les commits contenus dans le push possèdent la chaine de caractère [ci skip] dans leur message de commit. Par exemple

commit -m 'Ceci est un message [ci skip]'

Associer une page web GitHub à votre package

Dans un premier temps, créez votre site.

Pour que Travis compile et associe automatiquement votre site Web, il lui faut deux choses : un Personal Access Token (PAT) (à créer et associer une bonne fois pour toutes) et une clé de déploiement (à créer et associer pour chaque repo de votre compte GitHub).

PAT et use_pkgdown_travis

Pour le PAT, la solution la plus simple (mais la plus permissive pour Travis et donc la moins secure) est la suivante:

Pour donner moins de permission à Travis (https://happygitwithr.com/github-pat.html):

  1. Créer un PAT sans aucun scope sur https://github.com/settings/tokens
  2. Ajouter le PAT à .Renviron

  3. S’assurer que vous ne pusherez jamais votre PAT par mégarde.

Maintenant, vous pouvez associer pkgdown à Travis pour qu’il compile votre site à chaque push.

Je vous encourage également à rajouter la ligne ‘warnings_are_errors: false’ dans ‘.travis.yml’. Cela évite que Travis indique un échec juste parce que vous avez oublié de mettre un exemple dans votre documentation.

Clé de déploiement et use_travis_deploy

Pour la clé de déploiement, le plus simple, mais aussi le plus permissif (et donc le moins secure) est de lancer

Pour réduire les permissions de Travis, suivre ces étapes :

  1. Lancez le programme suivant pour générer une paire de clefs SSH

  2. Sur la page de votre repo GitHub, allez dans Settings > Deploy keys, et ajoutez votre clef publique public_key (cochez la case ‘Allow write access’).

  3. Sur la page de votre repo Travis, allez dans More Options > Settings. Ajoutez une variable d’environnement appelée ‘id_rsa’. Copiez la clef privée private_key dans value et assurez-vous que ‘Display value in build log’ est désactivé.

Désormais, chacun de vos pushes compile votre site à partir du fichier ‘README.Rmd’ et des documentations .Rd. Votre site est accessible sur .github.io/ (par exemple, fcheysson.github.io/mypkg).

Couverture de tests

Pour rajouter le niveau de couverture de vos tests unitaires sur votre page GitHub et le site web du package :

Il faut ensuite lier codecov à votre GitHub. Pour ceci, rendez-vous sur https://codecov.io/, connectez-vous avec votre compte GitHub et associez votre repo en suivant les instructions (dans votre repo Travis, dans More options > Settings, ajoutez une variable d’environnement nommée CODECOV_TOKEN ayant pour valeur celle donnée par codecov.io).