Package Creation:
Git & Github
usethis
and other packages## Install packages ---- f_install_packs <- function(packs){ # `%notin%` <- base::Negate("%in%") # installed_packs <- sort( names( installed.packages()[,1] ) ) # for(pack in packs){ pack_name <- substring(pack, regexpr("/", pack) + 1, nchar(pack)) if (pack_name %notin% installed_packs) { print(paste("installing package", pack)) # if (grepl("/", pack, fixed=TRUE)){ message("Github packages need to be installed in a separate R Session if we are using a Github token environment variable 'GITHUB_PAT' in this sessio") devtools::install_github(pack) # } else { install.packages(pack_name) } } else { print(paste("package", pack_name, "already installed")) } } } packs <- c('available', 'usethis', 'sinew', 'pkgdown', 'goodpractice', 'testthat', 'librarian', 'tidyverse', 'here', 'devtools', "DataStrategist/amitFuncs") # NOTE: Github packages need to be installed in a separate R Session if we are # using a Github token environment variable "GITHUB_PAT" in this session f_install_packs(packs) ## Load Packages ---- # Load magrittr to use %>% library("magrittr") # Load usethis package # NOTE: This active file must be in the project root folder before loading usethis librarian::shelf(usethis) ## Open Package Directory ---- fs::file_show(here::here()) ## List Steps for R package construction ---- amitFuncs::packageMakerList() ## Check if the package name is available at CRAN ---- available::available("Futilities2") # Yes ## Install Github Desktop (optional) ---- # https://desktop.github.com/ ## Install Git from https://gitforwindows.org/ ---- # - Note that RStudio for Windows prefers for Git to be installed below # C:/Program Files and this appears to be the default. This implies, for # example, that the Git executable on my Windows system is found at C:/Program # Files/Git/bin/git.exe. Unless you have specific reasons to otherwise, follow # this convention. # - NOTE: When asked about “Adjusting your PATH environment”, make sure to # select “Git from the command line and also from 3rd-party software”. # Otherwise, we believe it is good to accept the defaults. ## Check if Git is installed and follow the instructions ---- shell("which git") Sys.which("git") %>% fs::path_real() ## Set your Git user name and email ---- # - You can do it via Git command line (Git Base) # git config --global user.name 'Jane Doe' # git config --global user.email 'jane@example.com' # - Or via usethis package # NOTE: recommended to use the same user name as Github's usethis::use_git_config(user.name = "GitHunter0", user.email = "flavioadsm@gmail.com") ## Display your Git user name and email ---- # Type in Git Bash: # git config --global --list ## Display the current git repo root dir ---- shell("git rev-parse --show-toplevel") ## Git installation directory: "C:/Program Files/Git" ---- # Display files inside that folder fs::dir_ls("C:/Program Files/Git") %>% fs::path_file() ## Local where Git stores the commit message ---- if (FALSE) "C:/Users/flavio/AppData/Local/Temp" %>% fs::file_show() ## Create a New Package ---- # NOTE: + The package directory cannot contain spaces or special characters package_dir <- here::here() # # Open Package directory if (FALSE) fs::file_show(package_dir) # # Delete files inside the package destination folder, except this file fs::dir_ls(package_dir, all=TRUE) %>% stringr::str_subset( stringr::coll(fs::path(package_dir,"package_creation_guide")), negate=TRUE ) %>% fs::file_delete() # # Fields Content fields_list <- list( Package = "Futilities2", Title = "Various Helper Functions", Version = "0.0.1", `Authors@R` = 'c(person(given = "Git", family = "Hunter0", email = "flavio@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")), person(given = "Author", family = "Second", role = "aut", comment = c(ORCID = "0000-0002-2444-4226")))', Maintainer = "GitHunter0 <flavioadsm@gmail.com>", Description ="Various Helper Functions Functions regarding dataframes, Python/reticulate, data retrieval, ...", Encoding = "UTF-8", LazyData = "true", License = "MIT + file LICENSE", Language = "en" ) # Create a Package if (FALSE) { usethis::create_package(path = package_dir, fields = fields_list) } ## Create a Package with as many tidyverse conventions as possible ---- # creates a new package, immediately applies as many of the tidyverse # conventions as possible, issues a few reminders, and activates the new package usethis::create_tidy_package(path = package_dir) # Add fields content usethis::use_description(fields = fields_list) ## Activates a project in usethis, R session, and RStudio senses ---- # If you are in RStudio, this will open a new RStudio session. If not, it will # change the working directory and active project. # NOTE: only needed if the session is not interactive if (FALSE) usethis::proj_activate(path = package_dir) ## Initialize a Git repository in the package directory and make the first commit ---- usethis::use_git(message="commit 1") ## Add more Features and Specifications ---- # Most are already presented due to create_tidy_package() # Add nice frontpage to the package if (FALSE) usethis::use_readme_rmd() # BUG: + These two Badges are causing errors when to Knit README.Rmd # badge declares the developmental stage of a package, according to # https://www.tidyverse.org/lifecycle/: if (FALSE) usethis::use_lifecycle_badge(stage = "Experimental") # Signal if it is or not on CRAN. badge indicates what version of your package # is available on CRAN, powered by https://www.r-pkg.org if (FALSE) usethis::use_cran_badge() # Add license to the description file # usethis::use_gpl3_license(name = "GitHunter0 Inc") if (FALSE) usethis::use_mit_license("GitHunter0") # Add Code Coverage Badge # Code coverage is the percentage of code which is covered by automated tests. usethis::use_coverage(type = c("codecov")) # NEWS.md the place to announce big changes usethis::use_news_md() # pkgdown makes it easy to turn your package into a beautiful website usethis::use_pkgdown() # Add R Version Dependency Manually to DESCRIPTION "Depends: R (>= 2.10)" ## Add Internal, External or Raw Data into the package - References ---- # + https://r-pkgs.org/data.html # https://coolbutuseless.github.io/2018/12/10/r-packages-internal-and-external-data/ ## Generate/Retrieve Data and Store in 'data-raw' folder the code files (.R) ## necessary to recreate all internal and external data ---- # # Example for an external data: if (FALSE) library(help = datasets) # check native datasets available # Create the first external data usethis::use_data_raw("external_dataset1") # Populate the .R created with the code to generate the data: "external_dataset1 <- data.table::data.table(mtcars)" # And to it (already done by use_data_raw) the command to make the data # available externally: "usethis::use_data(external_dataset1, internal=FALSE, overwrite = TRUE)" # # NOTE: Do that for every external and internal (internal=TRUE) data # # For simplicity, let's create all the data here: external_dataset1 <- data.table::data.table(mtcars) external_dataset2 <- data.table::data.table(Titanic) internal_dataset1 <- data.table::data.table(mtcars)[1:20,] internal_dataset2 <- data.table::data.table(Titanic)[1:20,] ## Add External Data (stored at data/data_name.RData) ---- # It seems that just putting the data as .RData (.rda) inside "data" folder is enough to make it externally available usethis::use_data(external_dataset1, external_dataset2, internal=FALSE, overwrite=TRUE) # Then it would be available by my_package_name::external_dataset1 # NOTE: external data can also be used internally using the same syntax above # NOTE: After we Clean and Rebuild, this data can be loaded into the global environment like any other R data: data(“external_dataset1”, package = "my_package_name") if (FALSE) data(external_dataset1, package="Futilities2") # NOTE: Document External in R/data.R file following this guideline: https://r-pkgs.org/data.html#documenting-data ## Add Internal Data (not available to the users of the package) ---- # All data will be stored in one single file R/sysdata.rda (.RData) usethis::use_data(internal_dataset1, internal_dataset2, internal=TRUE, overwrite = TRUE) # NOTE:: Internal data can still be accessed externally using the triple colon # (:::) like this mypackage_name:::internal_dataset1 ## Add Raw Data (non-R type of files like .csv) # NOTE: Raw Data are stored in 'inst/extdata', not in 'data-raw' in folder # https://r-pkgs.org/data.html#data-extdata fs::dir_create("inst/extdata") if (FALSE) write.csv(mtcars, "inst/extdata/mtcars.csv") # To access it use system.file(), which will return the path to it # system.file("extdata", "file_name.csv", package="mypackage", mustWork=TRUE) system.file("extdata", "mtcars.csv", package="Futilities2", mustWork=TRUE) # fs::path_package() is probably better than base::system.file(), # see https://cran.r-project.org/web/packages/usethis/usethis.pdf fs::path_package(package="Futilities2", "extdata", "mtcars.csv") ## Delete 'hello' files manually if present ---- ## Obtain Github Token ---- # A personal access token (PAT) is needed for git operations via the GitHub API usethis::browse_github_pat( # "read:packages" authorization is needed to use usethis::create_from_github() scopes = c("repo", "gist", "user:email", "read:packages"), description = "R:GITHUB_PAT", host = "https://github.com" ) ## Store the token in .Renviron file of the user home folder (flavio/Documents) ---- # Open the file to edit # For secutiry reasons, we do not want .Renviron inside the package/project if (FALSE) usethis::edit_r_environ(scope = "project") # Instead we use the local user .Renviron usethis::edit_r_environ(scope = "user") # Insert GITHUB_PAT = the token obtained in the last step # Restart R for changes to take effect # Display the Token Sys.getenv("GITHUB_PAT") # Display using usethis function usethis::github_token() ## Get a situation report on your current git/GitHub status ---- # Useful for diagnosing problems. usethis::git_sitrep() ## Take a local project, creates an associated repo on GitHub, adds it to your local repo as the origin remote, and makes an initial push to synchronize ---- usethis::use_github(protocol ="https", private=FALSE, auth_token = usethis::github_token()) ## Create a project/package from a GitHub repo ---- if (FALSE) { # usethis::create_from_github( repo_spec = "GitHunter0/Futilities", # "D:/Flavio/OneDrive/Software_Codes_Files_(my_own)/R/Packages/Futilities2/Futilities2" destdir = NULL, # save at the desktop fork = FALSE, # NA, TRUE, protocol = "https", auth_token = usethis::github_token()) } ## Commit to Git using the Git tab from Rstudio ---- # The method below using git2r package does not work very well if (FALSE) { git2r::add(repo = here::here(), path = dir(here::here(), recursive=TRUE, all.files=FALSE, full.names = FALSE)) # git2r::commit(repo = here::here(), message = "Commit 3") } ## Push to Github ---- # Use RStudio Git Tab or Github Desktop ## Create symbolic link (symlink) to OneDrive if needed ---- # Open Command Prompt as Administrator at C:\Windows\system32> # REM mklink /J <TargetFolder> <OriginalFolder> # Example: 'mklink /j “D:/Flavio/OneDrive/__symlinks/finapps/R” “D:/working/finapps/R”' ## Use pipe from magrittr package usethis::use_pipe(export=TRUE) ## Add Roxygen comments to functions using sinew package/add-in ---- library("sinew") # Run function, select with cursor the function name, # then "Addins" -> "SINEW" - "CreateOxygen" # or Generate the output with this function and paste it manually if (FALSE) sinew::makeOxygen("name_of_the_function") # # sinew package does not detect %>%, so we need to add manually as below or use # use_pipe(): # @importFrom magrittr %>% # magrittr::`%>%` # https://github.com/yonicd/sinew/issues/56 # # To use data from other packages (in this case 'mtcars' from "datasets"), add # to NAMESPACE file: # importFrom("datasets", "mtcars") # # NOTE: There are other limitations of sines, like with NSE ## Use pipe from magrittr package (better method) ---- usethis::use_pipe(export=TRUE) ## Use data.table if (FALSE) usethis::use_data_table() ## Add packages to Description file "imports" field ---- # Displays which function is coming from which package if (FALSE) sines::makeImport('R',format = 'oxygen') # Copy and past in the DESCRIPTION file # NOTE: add magrittr or dplyr manually since sinew does not detect %>% sinew::makeImport("R", format="description") %>% stringr::str_split(": |,", n=Inf) %>% .[[1]] %>% .[-1] %>% # Automatically insert in the description file purrr::iwalk(., ~{ usethis::use_package(package=.x, type = "Imports") }) # Add magrittr which sinew may not detect usethis::use_package(package="magrittr", type = "Imports") # # NOTE: + If you are acessing external data as internal using mypackage::external_data, sinew will wrongly add it to the 'Imports' field at DESCRIPTION and as Roxygen comment (@Importfrom ...) in .R file, which will cause circular dependency and error. Therefore, manually remove all of that. # ## Add development version of package "amitFuncs" to imports # The file gets like this: # imports: "amitFuncs (>= 0.27)" # remotes: "DataStrategist/amitFuncs if (FALSE) usethis::use_dev_package(package="amitFuncs", type = "Imports") ## Create .R file in R folder ---- usethis::use_r("new-script") ## create a matching test file in test folder ---- usethis::use_test("new-script") ## Create testthat file and incorporate testthat to the package ---- # - Create a tests/testthat directory. # - Adds testthat to the Suggests field in the DESCRIPTION. # - Creates a file tests/testthat.R that runs all your # tests when R CMD check runs. (You’ll learn more about that in automated # checking.) if (FALSE) usethis::use_testthat() # already created ## .Rbuildignore - ignore selected files/folders when building the package ---- # This is just a plain text file that tells R to ignore selected files or # folders when building the package (e.g., if we wanted to include a folder for # our own purposes that is not needed or wanted for building the package) if (FALSE) usethis::use_build_ignore("[.]xlsx$", escape = FALSE) ## .gitignore - specifies files/folders that Git should ignore and not be pushed to GitHub too ---- if (FALSE) usethis::use_git_ignore(c("tests/testthat/secrets.tar")) ## This is the workhorse function that uses roclets, the built-in document transformation functions, to build all documentation for a package. ---- # See the documentation for the individual roclets, roxygen2::rd_roclet(), # roxygen2::namespace_roclet(), and for roxygen2::update_collate(), for more # details. devtools::document() ## Automatize to create/update documentation every time we install and restart the package (because it is common to forget) ---- "Build Tab -> More -> Configure Build Tools -> Configure -> Check box 'Install and Restart'" ## Remember to check Documentation ---- # - Roxygen for each function # - README.Rmd # - DESCRIPTION # - NEWS # NOTE: Knit README.Rmd (to .md), so that it can be used as Github front page). # BUG: Also, some Badges are causing errors to knit, so they must be commented out. ## Build -> More -> Clean and Rebuild / Install and Restart ---- # QUESTIOM: What is the difference between the two? # https://github.com/rstudio/rstudio/issues/4289 # "Clean and Rebuild" removes files created during a previous run; recommended. # That allows to load and use the package locally if (FALSE) library(Futilities2) ; myfun2(1:10) ## Run a Check ---- "Build Tab -> Check" ## Run a Check for good practices ---- goodpractice::gp() ## Build pkgdown website ---- # NOTE: pkgdown website files will be stored at "docs" folder. Later, generate the website in Github by going to "Settings" -> "Github Pages" - "master branch / docs folder". Then, add the website link to the package description in Github front page. First you must remove "docs" from .gitignore # Run once to configure your package to use pkgdown usethis::use_pkgdown() # BUG: This is returning an error: # https://github.com/r-lib/pkgdown/issues/1435 # NOTE: The solution is to make the Rstudio terminal window wide enough, and open a new terminal. pkgdown::build_site() if (FALSE) { pkgdown::build_home() pkgdown::build_reference() pkgdown::build_news() pkgdown::build_site(new_process = FALSE) } ## Commit using Git tab, then Push to Github using button ---- ## Manually Create and Publish R Packages ---- # - https://www.youtube.com/watch?v=XbSwdHBiO4E # - Install Github Desktop and login with your Github account; # - Install Git and set user name and email (the same used in Github) # - type git config --global --list at Terminal to see if the email and user name are correct. # - Global Options -> Git -> Enable -> Select Git Executable Path -> Restart R Create Project -> New Directory -> R Package -> Mark option "create a git repository" (this option will appear only after the previous installations) ; # - Create your .R files and Description file; # - Press -> More -> Clean and Rebuild # - Then go to Github Desktop, select this repository and "Commit to Master" -> Click Publish to Github. # - Done. Now you can install your package via devtools::install_github()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.