R/deploy_project.R

# deploy_project ---------------------------------------------------------------
#
#' @title Create a Skeleton for a New Data Science Project
#'
#' @description
#' This function will create all of the scaffolding for a new data science
#' Project. It will set up all of the relevant files and directories including
#' their initial contents.
#'
#' @param name (`character`) The project name.
#' @param path (`character`) An absolute path. The project will be created under
#'   \code{path/name}.
#'
#' @examples
#' \donttest{deploy_project(name = "project-template", path = dirname(getwd()))}
#'
#' @export
#'
deploy_project <- function(name, path){
    ###########################
    ## Defensive Programming ##
    ###########################
    .assert_is_absolute_path(path)
    .assert_is_a_non_missing_nor_empty_string(name)

    ###########
    ## Setup ##
    ###########
    ## Preprocess input arguments
    name <- tidylab.utils::standardise_strings(name, "lowercase", "hyphens")
    ## Create project folder
    target <- file.path(path, name)
    dir.create(target, showWarnings = FALSE, recursive = TRUE)


    #########################################
    ## Save and Load Project Configutation ##
    #########################################
    ## Create project's config.yml
    target <- file.path(path, name, "config.yml")
    .create_config_file(name = basename(target), path = dirname(target))
    ## Create project's config.yml "options" field
    target <- file.path(path, name)
    set_project_env(path = target)


    #########################################
    ## Create the Project Folder Structure ##
    #########################################
    ## Define folders
    project_paths <- ls(envir = .project)[grep("^path_", ls(envir = .project))]
    ## Create folders
    for(project_path in project_paths){
        folder_path <- get(project_path, envir = .project)
        file_path <- file.path(folder_path, ".md")
        dir.create(folder_path, showWarnings = FALSE, recursive = TRUE)
        file.create(file_path, showWarnings = FALSE)
    }


    ##################################
    ## Generate Project DESCRIPTION ##
    ##################################
    ## Create a new DESCRIPTION file
    target <- file.path(.project$path_project, "DESCRIPTION")
    .create_description_file(name = basename(target), path = dirname(target))
    ## Load the DESCRIPTION file
    description_obj <- desc::description$new(target)
    ## Set project name
    description_obj$set(Package = gsub("-", ".", name))
    ## Set project version
    year <- format(as.Date(Sys.Date(), format="%d/%m/%Y"), "%y")
    week <- format(as.Date(Sys.Date(), format="%d/%m/%Y"), "%V")
    version_major <- unlist(description_obj$get_version())[1]
    version_minor <- formatC(year, width = 2, format = "d", flag = "0")
    version_patch <- formatC(week, width = 2, format = "d", flag = "0")
    description_obj$set_version(paste(version_major, version_minor, version_patch, sep = "."))
    ## Set project R version
    R_version <- substr(strsplit(version[['version.string']], ' ')[[1]][3], 1, 3)
    description_obj$set_dep("R", "Depends", version = paste(">=", R_version))
    ## Set project packages
    requirements <- list()
    requirements$type    <- c("Imports", "Imports", "Imports", "Imports", "Suggests", "Suggests")
    requirements$package <- c("magrittr", "remotes", "tidyverse", "tidylab" ,"testthat", "covr")
    requirements$version <- c(">= 1.5", ">= 2.0.2", ">= 1.2.1", "*", "*", "*")
    requirements <- as.data.frame(requirements, stringsAsFactors = FALSE)
    description_obj$set_deps(requirements)
    ## Set project remotes
    description_obj$set_remotes("tidylab/tidylab")
    ## Save changes
    description_obj$write(target)


    ######################
    ## Generate LICENSE ##
    ######################
    target <- file.path(.project$path_project, "LICENSE")
    .create_license_file(name = basename(target), path = dirname(target))


    ########################
    ## Generate GitIgnore ##
    ########################
    target <- file.path(.project$path_project, ".gitignore")
    .create_gitignore_file(name = basename(target), path = dirname(target))


    #######################
    ## Generate Rprofile ##
    #######################
    target <- file.path(.project$path_project, ".Rprofile")
    .create_profile_file(name = basename(target), path = dirname(target))


    ####################
    ## Generate Rproj ##
    ####################
    target <- file.path(.project$path_project, paste0(name, ".Rproj"))
    .create_project_file(name = basename(target), path = dirname(target))


    ############
    ## Return ##
    ############
    return(invisible())
}

# create_license_file ----------------------------------------------------------

.create_license_file <- function(name = "LICENSE", path = getwd()){
    content <- c(
        paste0("YEAR: ", format(as.Date(Sys.Date(), format="%d/%m/%Y"), "%Y")),
        paste0("COPYRIGHT HOLDER: ", "Bilbo Baggins")
    )
    writeLines(content, con = file.path(path, name))
}

# create_description_file ------------------------------------------------------

.create_description_file <- function(name = "DESCRIPTION", path = getwd()){
    writeLines(
'Package: {{ Package }}
Title: {{ Title }}
URL: {{ URL }}
BugReports: {{ BugReports }}
Version: 0.0.0
Authors@R: c(
            person("Bilbo", "Baggins", email = "bilbo@the-shire.co.nz", role = c("aut", "cre")),
            person("Peregrin", "Took", email = "peregrin@the-shire.co.nz", role = "ctb")
            )
Maintainer: Bilbo Baggins <bilbo@the-shire.co.nz>
Description: {{ Description }}
License: MIT + file LICENSE
Encoding: UTF-8',
        con = file.path(path, name))
}

# create_gitignore_file --------------------------------------------------------

.create_gitignore_file <- function(name = ".gitignore", path = getwd()){
    writeLines(
'#####################
# Ignore everything #
#####################
/*
/*/


#########################
# Un-ignore directories #
#########################
!/code/
!/data/
!/docs/
!/models/


##################
## Ignore Files ##
##################
# History files
.Rhistory
.Rapp.history

# Session Data files
.RData

# RStudio files
.Rproj.user/
.Ruserdata

# Produced docs
docs/*.html
docs/*.pdf

# Temporary files created by R markdown
*.utf8.md
*.knit.md

# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth

# knitr and R markdown default cache directories
/*_cache/
/cache/

# Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html
rsconnect/
*.html
*.RData
*.rdb
*.rdx
*.png

# Automated script
code/scripts/ctrl+shift+w.R

# Data folders
data/cache/
data/submissions/

# Package manager folder
.checkpoint/

###################
# Un-ignore Files #
###################
!.gitignore
!.Rprofile
!*.Rproj
!config.yml
!DESCRIPTION',
        con = file.path(path, name))
}

# create_profile_file ----------------------------------------------------------

.create_profile_file <- function(name = ".Rprofile", path = getwd()){
    # see https://www.statmethods.net/interface/customizing.html
    writeLines(
        'tidylab.deployment::setup(path = getwd())',
        con = file.path(path, name))
}

# create_project_file ----------------------------------------------------------

.create_project_file <- function(name = ".Rproj", path = getwd()){
    writeLines(
'Version: 1.0

RestoreWorkspace: No
SaveWorkspace: No
AlwaysSaveHistory: Yes

EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 4
Encoding: UTF-8

RnwWeave: Sweave
LaTeX: pdfLaTeX

BuildType: Package
PackageUseDevtools: Yes
PackageInstallArgs: --no-multiarch --with-keep.source --no-build-vignettes
PackageBuildArgs: --no-build-vignettes --no-manual
PackageBuildBinaryArgs: --no-build-vignettes --no-manual
PackageCheckArgs: --no-build-vignettes --no-manual
PackageRoxygenize: rd,collate,namespace',
        con = file.path(path, name))
}

# create_config_file -----------------------------------------------------------

.create_config_file <- function(name = "config.yml", path = getwd()){
    tags <- list()
    #############################
    ## Define Global Variables ##
    #############################
    tags$options <- list()
    ## Root
    tags$options$path_project <- 'getwd()'
    ## Code
    tags$options$path_code <- 'file.path(.project$path_project, "code")'
    tags$options$path_functions <- 'file.path(.project$path_code, "R")'
    tags$options$path_tests <- 'file.path(.project$path_code, "tests")'
    ## Data
    tags$options$path_data <- 'file.path(.project$path_project, "data")'
    ## Docs
    tags$options$path_docs <- 'file.path(.project$path_project, "docs")'
    ## Models
    tags$options$path_models <- 'file.path(.project$path_project, "models")'


    ######################
    ## Save config.yaml ##
    ######################
    yaml::write_yaml(x = tags, file = file.path(path, name))


    ############
    ## Return ##
    ############
    return(invisible())
}
tidylab/tidylab.deployment documentation built on June 9, 2019, 11:41 a.m.