Skip to content

Commit

Permalink
version 0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredlander authored and cran-robot committed Jun 19, 2018
0 parents commit 952f571
Show file tree
Hide file tree
Showing 30 changed files with 916 additions and 0 deletions.
22 changes: 22 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Package: RepoGenerator
Title: Generates a Project and Repo for Easy Initialization of a
Workshop
Version: 0.0.1
Authors@R: person(c("Jared", "P."), "Lander", email = "packages@jaredlander.com", role = c("aut", "cre"))
Description: Generates a project and repo for easy initialization of a GitHub repo for R workshops. The repo includes a README with instructions to ensure that all users have the needed packages, an 'RStudio' project with the right directories and the proper data. The repo can then be used for hosting code taught during the workshop.
Depends: R (>= 3.3.0)
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
Imports: rstudioapi, git2r, rmarkdown, httr
RoxygenNote: 6.0.1
Suggests: testthat, covr
URL: https://github.com/jaredlander/RepoGenerator
BugReports: https://github.com/jaredlander/RepoGenerator/issues
SystemRequirements: GitHub, 'RStudio'
NeedsCompilation: no
Packaged: 2018-06-17 21:16:21 UTC; jared
Author: Jared P. Lander [aut, cre]
Maintainer: Jared P. Lander <packages@jaredlander.com>
Repository: CRAN
Date/Publication: 2018-06-19 08:10:24 UTC
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
YEAR: 2018
COPYRIGHT HOLDER: Lander Analytics
29 changes: 29 additions & 0 deletions MD5
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
6ccd4ae41dc6725d6aca3abd62f9cf24 *DESCRIPTION
2a587cec62cb713e9d0dd0345d0678f5 *LICENSE
e6c69c3e107ecd49d1ae689e4d4f2942 *NAMESPACE
3f2174b840554c5e8509fd1a05a26c0d *NEWS.md
279075e12922d9247eebee0e9e965835 *R/CreateRepo.r
21d66872430153e321624866a432254c *R/data.r
efc659b159ff65aeb8cfe2d7f3db3784 *R/githubAPI.r
ca7c4e7879300f89a8278c8c884e25cb *README.md
50a3b4e950378cf10f901fb559a4d271 *data/datafiles.rda
d70ede3db2d35a96416120845685cdb0 *inst/DownloadData_orig.r
b7b041c1be182e1ff7c74e8a4407af6c *inst/metadata/DataList.csv
dd10db22da9b4ad982a0ba64ef871369 *inst/payload/README.Rmd
017edc42186745b46b12a858a7a43ccf *inst/payload/code/code.md
a7f59227198135bf5868818296299015 *inst/payload/data/data.md
7a343706aa6dff2642bd21916955da6a *inst/payload/markdown/markdown.md
6efb7307752df034f5f7afed4074d25c *inst/payload/prep/DownloadData.r
6dded068ab2a567e4374b5fc8d0e127f *inst/payload/prep/prep.md
439026dcec2313bf28c8507cba83eb1f *man/callGitHubAPI.Rd
f2e8686479331a7fca8ab2f869e91b7c *man/createDownloadText.Rd
a8254b627edadb5c6eb2dbbf68e73b2b *man/createRepo.Rd
cecd0ef0c0fa20904643e0b9065e4bc4 *man/datafiles.Rd
54a04acaea5d3c9afaa4d1ba238d6f6a *tests/testthat.R
c638374b5bb92bcdab049f8b71aa52e6 *tests/testthat/test-Download-code-blocks.R
f80c57b3d62038c76d15010591b4d4ee *tests/testthat/test-GitHub-API.R
0cac6fb647563aa7f06e048c6b8ca0e2 *tests/testthat/test-Master-Build.R
a1fe9fbf72369145b9916ffcab4de4bd *tools/readme/GitHub-Developer-Settings.png
4558ec8b8ec0f598754d16394ac167ae *tools/readme/GitHub-Settings.png
fcef2de0a24708433a32d91108a1ff2a *tools/readme/GitHub-Token-Generation.png
6bce8a88f0bf8ff0df555afa034f71de *tools/readme/PAT-Options.png
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Generated by roxygen2: do not edit by hand

export(createRepo)
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Version 0.0.2
- Tracking the .gitignore file

# Version 0.0.1
- Launch of package
- Designed to automatically generate RStudio projects and GitHub repos like https://github.com/jaredlander/WorkshopExampleRepo
143 changes: 143 additions & 0 deletions R/CreateRepo.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#' @title createRepo
#' @description Creates a new project and pushes it to GitHub
#' @details This is designed to make a bare repo to be used for workshops. It will create a new project with a customized README and customized download file. It then pushes this to GitHub.
#' @export
#' @author Jared P. Lander
#' @md
#' @param name Name to use for project and repo
#' @param path Location for the new project
#' @param data [data.frame] listing data sources. Must have at least the following columns: Local (the name the file should be on disk after downloaded), Remote (the URL of the file), Mode (the way to write to disk, either 'w' or 'wb').
#' @param packages Vector of packages that the user will be instructed to install.
#' @param user GitHub username
#' @param organizer Name of organizer of class. This can be in the form a a Markdown-style link.
#' @param token The name of the environment variable holding the GitHub access token. This can be set with [base::Sys.setenv()].
#' @param readme Path to parameterized rmarkdown document with parameters `className`, `organizer` and `packages`. If missing the default from the package is used.
#' @param ssh If `TRUE`, change the remote to use ssh instead of https
#' @return If all operations are successful, returns `TRUE`
#'
createRepo <- function(name, path,
data,
packages=c('here', 'knitr', 'rmarkdown',
'tidyverse', 'usethis'),
user,
organizer=user,
token='GITHUB_PAT',
readme,
ssh=TRUE)
{
# use defaults for certain arguments
if(missing(user))
{
user <- Sys.info()['user']
}

# they must specify a path
if(missing(path))
{
stop('You must specify a path to for the generated repo.')
}

# they MUST install usethis and rprojroot, so if they are not in the
# packages list they are added
# and a message is generated saying as such
unique(c(packages, 'rprojroot', 'usethis'))

# create new project
rstudioapi::initializeProject(path=path)

# copy code, data, images, prep, etc
# folders <- dir(here::here('payload'), full.names=TRUE)
folders <- dir(system.file('payload', package='RepoGenerator'),
full.names=TRUE,
# include all files to get .gitignore
# this seems a little dangerous to me
# because what other hidden files are coming
all.files=TRUE)
file.copy(folders, file.path(path), recursive=TRUE)

if(missing(readme))
{
readme <- file.path(path, 'README.Rmd')
}

# render the README
rmarkdown::render(readme,
params=list(
className=name,
organizer=organizer,
packages=packages
),
output_format=rmarkdown::github_document())
# remove the HTML version of README which was created for some reason I don't know
unlink(file.path(path, 'README.html'))

## add list of files to the download file
# if the data is missing, take all the data in metadata
if(missing(data))
{
data <- utils::read.csv(system.file('metadata/DataList.csv', package="RepoGenerator"),
stringsAsFactors=FALSE, header=TRUE)
}

dataBlocks <- createDownloadText(data)
write(dataBlocks, file=file.path(path, 'prep', 'DownloadData.r'), append=TRUE)

# create new GitHub repo
# requires that the token be stored in GITHUB_PAT
new_github_repo <- createGitHubRepo(repoName=name,
token=Sys.getenv(token))

# create git repo
repo <- git2r::init(path)

# add and commit files
git2r::add(repo, dir(path, recursive=TRUE))
# also add .gitignore
# not sure if we can just change the above dir to include hidden files
# because that might also include the .git folder
git2r::add(repo, file.path(path, '.gitignore'))
git2r::commit(repo, "Adding all files to Git")

# add the remote
git2r::remote_add(repo, 'origin', sprintf('https://github.com/%s/%s.git',
user, name)
)

# push to git
git2r::push(repo, "origin", "refs/heads/master",
credentials=git2r::cred_token(token))

# switch to SSH afterward
# this will allow us to use the ssh key to push to it instead of https
if(ssh)
{
# first we remove the current https remote
git2r::remote_remove(repo, name='origin')
# then we add the ssh remote
git2r::remote_add(repo, 'origin', sprintf('git@github.com:%s/%s.git',
user, name)
)
}

return(TRUE)
}

#' @title createDownloadText
#' @description Builds text for file that downloads data
#' @details Creates a block of code. The first line is a comment of the file name, then is uses [download.file()] using the remote URL and the local filename.
#' @author Jared P. Lander
#' @md
#' @param info [data.frame] listing data sources. Must have at least the following columns: Local (the name the file should be on disk after downloaded), Remote (the URL of the file), Mode (the way to write to disk, either 'w' or 'wb').
#' @return Returns the block of text
#' @examples
#'
#' dataList <- read.csv(system.file('metadata/DataList.csv', package='RepoGenerator'),
#' stringsAsFactors=FALSE, header=TRUE)
#' cat(RepoGenerator:::createDownloadText(dataList))
#'
createDownloadText <- function(info)
{
downloadBlock <- "# %s\ndownload.file(\n\t'%s',\n\tdestfile=file.path(dataDir, '%s'),\n\tmode='%s')\n"

sprintf(downloadBlock, info$Local, info$Remote, info$Local, info$Mode)
}
15 changes: 15 additions & 0 deletions R/data.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#' List of a few datasets commonly used in our workshops.
#'
#' A dataset containing information about data to download for a workshop.
#'
#' @format A data frame with 53940 rows and 10 variables:
#' \describe{
#' \item{Data}{Colloquial name of data}
#' \item{Remote}{URL of file}
#' \item{Local}{Name to use for file on disc}
#' \item{Type}{Type of file, such as CSV, Excel}
#' \item{Mode}{Way to write file to disc such as 'w' for text files or 'wb' for binary files}
#' \item{Tag}{Tag for the type of data}
#' \item{Purpose}{What the data is used to show}
#' }
"datafiles"
90 changes: 90 additions & 0 deletions R/githubAPI.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#' @title callGitHubAPI
#' @description Function for interacting with the GitHub API
#' @details Builds up and executes a GitHub API request
#' @author Jared P. Lander
#' @param repoName Name of repo to interact with
#' @param token GitHub Personal Access Token: this should be the actual token, not the name of an environment variable
#' @param apiURL The base URL for the GitHub API, this really should not need to be changed
#' @param path The API endpoint
#' @param encoding The type of encoding for the request, either json of form
#' @param method The method to be used, as an R function, such as POST or GET
#' @return An API status
#'
callGitHubAPI <- function(repoName,
token,
apiURL='https://api.github.com',
path='/user/repos', encoding=c('json', 'form'),
method=httr::POST
)
{
encoding <- match.arg(encoding)
# build up full URL so we can call the appropriate API endpoint
apiURL <- httr::modify_url(apiURL, path=path)

# if the token is not supplied, try to get it from the environment variable
if(missing(token))
{
token <- Sys.getenv('GITHUB_PAT')
}

## make the call
# this is a post statement to create the repo
result <- method(
# this is the base URL and the end point
url=apiURL,
# the body only consists of the name of the repo we are creating
body=list(name=repoName),
# use the proper encoding
encode=encoding,
# build headers
httr::add_headers(
# the type of data the API accepts
Accept="application/vnd.github.v3+json",
# Just used the name of this package, not sure it's correct
"User-Agent"="RepoGenerator",
# the API access token, typically stored in GITHUB_PAT
Authorization=sprintf("token %s", token)
)
)

return(result)
}

#' @title createGitHubRepo
#' @describeIn callGitHubAPI Creating a GitHub Repo
createGitHubRepo <- function(repoName,
token)
{
callGitHubAPI(repoName=repoName, token=token,
apiURL='https://api.github.com',
path='/user/repos',
encoding='json',
method=httr::POST)
}

#' @title deleteGitHubRepo
#' @describeIn callGitHubAPI Deleting a GitHub Repo
#' @param owner GitHub username
deleteGitHubRepo <- function(owner,
repoName,
token)
{
callGitHubAPI(repoName=repoName, token=token,
apiURL='https://api.github.com',
path=sprintf('/repos/%s/%s', owner, repoName),
encoding='json',
method=httr::DELETE)
}

#' @title checkGitHubRepoExists
#' @describeIn callGitHubAPI Check that a GitHub Repo exists
checkGitHubRepoExists <- function(owner,
repoName,
token)
{
callGitHubAPI(repoName=repoName, token=token,
apiURL='https://api.github.com',
path=sprintf('/repos/%s/%s', owner, repoName),
encoding='json',
method=httr::GET)
}

0 comments on commit 952f571

Please sign in to comment.