Skip to content

Commit

Permalink
Progress on create_from_github() (#216)
Browse files Browse the repository at this point in the history
* Progress on create_from_github()

Fixes #114. For now.

* open_project() already has this logic

* Disambiguate `repo` and repo's name; user -> owner
  • Loading branch information
jennybc committed Jan 17, 2018
1 parent 8eea8d7 commit da1a8c2
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 20 deletions.
73 changes: 61 additions & 12 deletions R/create.R
Expand Up @@ -77,43 +77,92 @@ create_project <- function(path,
invisible(TRUE)
}

#' Create a project from a github repository
#' Create a repo and project from GitHub
#'
#' Creates a new local Git repository from a repository on GitHub. If you have
#' pre-configured a GitHub personal access token (PAT) as described in
#' [gh::gh_whoami()], you will get more sensible default behavior for the `fork`
#' argument. You cannot create a fork without a PAT. Currently only works for
#' public repositories. A future version of this function will likely have an
#' interface closer to [use_github()], i.e. more ability to accept credentials
#' and more control over the Git configuration of the affected remote or local
#' repositories.
#'
#' @seealso [use_course()] for one-time download of all files in a Git repo,
#' without any local or remote Git operations.
#'
#' @inheritParams create_package
#' @param repo Full name of repository: `owner/repo`
#' @param fork Create a fork before cloning? Defaults to `TRUE` if you can't
#' push to `repo`, `FALSE` if you can.
#' @param repo GitHub repo specification in this form: `owner/reponame`. The
#' second part will be the name of the new local repo.
#' @inheritParams use_course
#' @param fork Create and clone a fork? Or clone `repo` itself? Defaults to
#' `TRUE` if you can't push to `repo`, `FALSE` if you can.
#' @param rstudio Initiate an [RStudio
#' Project](https://support.rstudio.com/hc/en-us/articles/200526207-Using-Projects)?
#' Defaults to `TRUE` if in an RStudio session and project has no
#' pre-existing `.Rproj` file. Defaults to `FALSE` otherwise.
#' @export
create_from_github <- function(repo, path, fork = NA, open = TRUE) {
#' @examples
#' \dontrun{
#' create_from_github("r-lib/usethis")
#' }
create_from_github <- function(repo,
destdir = NULL,
fork = NA,
rstudio = NULL,
open = interactive()) {
destdir <- destdir %||% conspicuous_place()
check_is_dir(destdir)

repo <- strsplit(repo, "/")[[1]]
if (length(repo) != 2) {
stop("`repo` must be of form user/reponame", call. = FALSE)
stop(
code("repo"), " must be of form ",
value("owner/reponame"), call. = FALSE
)
}
owner <- repo[[1]]
repo <- repo[[2]]
repo_info <- gh::gh("GET /repos/:owner/:repo", owner = owner, repo = repo)

check_not_nested(dirname(path), repo)
check_not_nested(destdir, repo)

# By default, fork only if you can't push to the repo
if (is.na(fork)) {
fork <- !repo_info$permissions$push
perms <- repo_info$permissions
if (is.null(perms)) {
# if permissions are absent, there's no PAT and we can't fork
fork <- FALSE
} else {
# fork only if can't push to the repo
fork <- !isTRUE(perms$push)
}
}
## TODO(jennybc): should we also be checking if fork = TRUE but user owns the
## repo?

if (fork) {
done("Forking repo")
fork_info <- gh::gh("POST /repos/:owner/:repo/forks", owner = owner, repo = repo)
fork_info <- gh::gh(
"POST /repos/:owner/:repo/forks",
owner = owner, repo = repo
)
owner <- fork_info$owner$login
git_url <- fork_info$git_url
} else {
git_url <- repo_info$git_url
}

done("Cloning repo")
repo_path <- create_directory(path, repo)
repo_path <- create_directory(destdir, repo)
done("Cloning repo from ", value(git_url), " into ", value(repo_path))
git2r::clone(git_url, normalizePath(repo_path), progress = FALSE)
proj_set(repo_path)

rstudio <- rstudio %||% rstudioapi::isAvailable()
rstudio <- rstudio && !is_rstudio_project(repo_path)
if (rstudio) {
use_rstudio()
}

if (open) {
open_project(repo_path, repo)
}
Expand Down
1 change: 1 addition & 0 deletions R/proj.R
Expand Up @@ -4,6 +4,7 @@ proj_crit <- function() {
rprojroot::has_file(".here") |
rprojroot::is_rstudio_project |
rprojroot::is_r_package |
rprojroot::is_git_root |
rprojroot::is_remake_project |
rprojroot::is_projectile_project
}
Expand Down
37 changes: 29 additions & 8 deletions man/create_from_github.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit da1a8c2

Please sign in to comment.