From 995305c66caa00ad8c6b557d30810f6f77d29603 Mon Sep 17 00:00:00 2001 From: Matt Dray <18232097+matt-dray@users.noreply.github.com> Date: Wed, 21 Jun 2023 18:39:40 +0100 Subject: [PATCH 1/2] Add cli, check action, generic branch name removal, close #14 --- .Rbuildignore | 3 +- .github/.gitignore | 1 + .github/workflows/R-CMD-check.yaml | 49 +++++++++++++++++ DESCRIPTION | 5 +- NEWS.md | 12 ++++- R/01-repo-names.R | 17 +++--- R/02-download-repos.R | 56 +++++++++++++------- R/03-clone-repos.R | 18 +++++-- R/04-copy-repos.R | 84 ++++++++++++++++++++++-------- README.md | 9 ++-- man/ghd_copy.Rd | 3 +- man/ghd_extract_names.Rd | 3 +- man/ghd_get_repos.Rd | 5 +- man/ghdump-package.Rd | 4 +- 14 files changed, 199 insertions(+), 70 deletions(-) create mode 100644 .github/.gitignore create mode 100644 .github/workflows/R-CMD-check.yaml diff --git a/.Rbuildignore b/.Rbuildignore index b571007..92309ab 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,4 +1,5 @@ -^allghrepos\.Rproj$ +^ghdump\.Rproj$ ^\.Rproj\.user$ ^LICENSE\.md$ ^CODE_OF_CONDUCT\.md$ +^\.github$ diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..a3ac618 --- /dev/null +++ b/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,49 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: R-CMD-check + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macos-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + with: + upload-snapshots: true diff --git a/DESCRIPTION b/DESCRIPTION index 5815193..6e0dfca 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: ghdump Title: Clone Or Download All Repos For A GitHub User -Version: 0.0.0.9006 +Version: 0.1.0 Authors@R: person(given = "Matt", family = "Dray", @@ -15,7 +15,8 @@ License: MIT + file LICENSE Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.1.0 +RoxygenNote: 7.2.3 Imports: + cli, gh (>= 1.1.0), purrr (>= 0.3.4) diff --git a/NEWS.md b/NEWS.md index 43362bb..5c6f27a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# ghdump 0.1.0 + +* Added {cli} for a prettier user interface and added new messages. +* Fixed bug where providing a protocol borked downloads (#14). +* Attempted to remove branch name from unzipped file folders by simple regex (`-.*$`) rather than to remove the hard-coded '-master'. +* Added R-CMD check GitHub Action. +* Bump v0.1.0. + # ghdump 0.0.0.9006 * Added protocol argument for user to choose HTTPS or SSH (#10) @@ -12,9 +20,9 @@ * Introduced cloning functionality for (at least) Mac (#6) * Updated readme given new functionality * Separated scripts in `r/` into different files -* Minor improvements to code comments and user prompt text +* Made minor improvements to code comments and user prompt text * Preferred ?readlines() example for 'y'/'n' user input -* Add license +* Added license # ghdump 0.0.0.9003 diff --git a/R/01-repo-names.R b/R/01-repo-names.R index 8b3e1de..e27ffb5 100644 --- a/R/01-repo-names.R +++ b/R/01-repo-names.R @@ -5,18 +5,16 @@ #' Uses \code{\link[gh]{gh}} to access the GitHub API and get the details for #' all of a named user's repos. To use this function you need to have created a #' GitHub account and to have put a GitHub Personal Access Token (PAT) in your -#' .Renviron. See \href{https://happygitwithr.com/github-pat.html}{Happy Git and GitHub for the UseR} +#' .Renviron. See +#' \href{https://happygitwithr.com/github-pat.html}{Happy Git and GitHub for the UseR} #' for more information. #' #' @param gh_user Character string. A GitHub username. #' -#' @return A gh_response object. +#' @return A gh_response (list) object. ghd_get_repos <- function(gh_user) { - cat( - "Fetching GitHub repos for user ", gh_user, "... ", - sep = "" - ) + cli::cli_alert_info("Fetching GitHub repos for user '{gh_user}'. ") # Get repos for username user_repos <- @@ -26,6 +24,8 @@ ghd_get_repos <- function(gh_user) { .limit = Inf # get all repos ) + cli::cli_alert_success("Found {length(user_repos)} repos.") + return(user_repos) } @@ -35,7 +35,8 @@ ghd_get_repos <- function(gh_user) { #' Extract all the 'name' elements from a gh_response object. These are the #' names of all the GitHub repos. #' -#' @param repo_object A gh_response object, as returned by \code{\link{ghd_get_repos}}. +#' @param repo_object A gh_response object, as returned by +#' \code{\link{ghd_get_repos}}. #' #' @return A character vector of GitHub repo names. ghd_extract_names <- function(repo_object) { @@ -48,8 +49,6 @@ ghd_extract_names <- function(repo_object) { repo_names_vec <- unlist(repo_names) - cat(length(repo_names), "repos found\n") - return(repo_names_vec) } diff --git a/R/02-download-repos.R b/R/02-download-repos.R index 070cc6d..62998d4 100644 --- a/R/02-download-repos.R +++ b/R/02-download-repos.R @@ -40,20 +40,27 @@ ghd_download_zips <- function(repo_urls, dest_dir) { # Ask if all the repos should be downloaded q_download_all <- readline( prompt = paste0( - "Definitely download all ", nrow(repo_urls), " repos? y/n: ") + "Definitely download all ", nrow(repo_urls), " repos? y/n: " + ) ) - if (substr(tolower(q_download_all), 1, 1) == "y") { + is_yes <- substr(tolower(q_download_all), 1, 1) == "y" + is_no <- substr(tolower(q_download_all), 1, 1) == "n" + + if (is_yes) { + + cli::cli_alert_info("Downloading zipped repositories to {dest_dir}") + cli::cli_alert_info("Hit ESC at any time to abort.") - cat("Downloading zipped repositories to", dest_dir, "\n") + } else if (is_no) { - } else if (substr(tolower(q_download_all), 1, 1) == "n") { + cli::cli_abort("Aborted by user choice.") stop("Aborted by user choice.\n") } else { - stop("Aborted. Input not understood.\n") + cli::cli_abort("Aborted. Input not understand.") } @@ -99,7 +106,7 @@ ghd_unzip <- function(dir) { ) # Unzip the files - cat("Unzipping repositories\n") + cli::cli_alert_info("Unzipping repositories.") purrr::walk( .x = zip_files, .f = ~ utils::unzip(zipfile = .x, exdir = dir) @@ -110,34 +117,44 @@ ghd_unzip <- function(dir) { prompt = paste0("Retain the zip files? y/n: ") ) + is_yes <- substr(tolower(q_keep_zip), 1, 1) == "y" + is_no <- substr(tolower(q_keep_zip), 1, 1) == "n" + # React to user input - if (substr(tolower(q_keep_zip), 1, 1) == "y") { + if (is_yes) { - cat("Keeping zipped folders.") + cli::cli_alert_info("Keeping zipped folders.") - } else if (substr(tolower(q_keep_zip), 1, 1) == "n") { + } else if (is_no) { - cat("Removing zipped folders\n") + cli::cli_alert_info("Removing zipped folders.") purrr::walk( .x = zip_files, .f = file.remove ) + cli::cli_alert_success("Removed zipped folders.") + } else { - cat("Input not understood. Keeping zipped folders.\n") + + cli::cli_alert_warning("Input not understood. Keeping zipped folders.") + } # Ask if "-master" suffix of unzipped files should be replaced q_remove_suffix <- readline( prompt = paste0( - "Remove '-master' suffix from unzipped directory names? y/n: " + "Remove branch suffix (e.g. '-main') from unzipped directory names? y/n: " ) ) + is_yes <- substr(tolower(q_remove_suffix), 1, 1) == "y" + is_no <- substr(tolower(q_remove_suffix), 1, 1) == "n" + # React to user input - if (substr(tolower(q_remove_suffix), 1, 1) == "y") { + if (is_yes) { # Get paths of each unzipped file unzipped_dirs <- @@ -151,25 +168,28 @@ ghd_unzip <- function(dir) { rename_df <- data.frame( from = unzipped_dirs, - to = gsub(pattern = "-master", replacement = "", x = unzipped_dirs), + to = gsub(pattern = "-.*$", replacement = "", x = unzipped_dirs), stringsAsFactors = FALSE ) # Rename each file to remove "-master" - cat("Renaming files to remove '-master' suffix\n") + cli::cli_alert_info("Renaming files to remove branch suffix.") purrr::walk2( .x = rename_df$from, .y = rename_df$to, .f = file.rename ) + cli::cli_alert_success("Renamed folders.") - } else if (substr(tolower(q_remove_suffix), 1, 1) == "n") { + } else if (is_no) { - cat("Unzipped repository names unchanged.\n") + cli::cli_alert_info("Unzipped repository names unchanged.") } else { - cat("Input not understood. Leaving unzipped repository names unchanged.\n") + cli::cli_alert_warning( + "Input not understood. Leaving unzipped repository names unchanged." + ) } diff --git a/R/03-clone-repos.R b/R/03-clone-repos.R index 6a8562d..ab192d2 100644 --- a/R/03-clone-repos.R +++ b/R/03-clone-repos.R @@ -20,7 +20,10 @@ ghd_clone_one <- function(gh_user, repo, protocol, dest_dir) { if (!protocol %in% c("https", "ssh")) { - stop("You must provide either 'https' or 'ssh' to the protocol argument.") + + cli::cli_abort( + "You must provide either 'https' or 'ssh' to the protocol argument." + ) } # Pass a system call to clone the repo to the destination @@ -70,10 +73,13 @@ ghd_clone_multi <- function(gh_user, names_vec, protocol, dest_dir) { prompt = paste0("Definitely clone all ", length(names_vec), " repos? y/n: ") ) + is_yes <- substr(tolower(q_clone_all), 1, 1) == "y" + is_no <- substr(tolower(q_clone_all), 1, 1) == "n" + # React to user input - if (substr(tolower(q_clone_all), 1, 1) == "y") { + if (is_yes) { - cat("Cloning repositories to", dest_dir, "\n") + cli::cli_alert_info("Cloning repositories to {dest_dir}.") # Prepare safe file clone (passes over failures) clone_safely <- @@ -92,13 +98,15 @@ ghd_clone_multi <- function(gh_user, names_vec, protocol, dest_dir) { .f = clone_safely ) - } else if (substr(tolower(q_clone_all), 1, 1) == "n") { + } else if (is_no) { + + cli::cli_abort("Aborted by user choice.") stop("Aborted by user choice.\n") } else { - stop("Aborted. Input not understood.\n") + cli::cli_abort("Aborted. Input not understand.") } diff --git a/R/04-copy-repos.R b/R/04-copy-repos.R index 7fe4f29..c208345 100644 --- a/R/04-copy-repos.R +++ b/R/04-copy-repos.R @@ -14,7 +14,8 @@ #' @details Make sure you've got a GitHub account and have #' \href{https://happygitwithr.com/github-pat.html}{generated a GitHub PAT} #' and stored it your .Renviron. If you're using \code{protocol = "ssh"}, -#' you need to make sure you have \href{https://happygitwithr.com/ssh-keys.html}{set up your SSH keys}. +#' you need to make sure you have +#' \href{https://happygitwithr.com/ssh-keys.html}{set up your SSH keys}. #' #' @return GitHub repositories either (a) cloned or (b) downloaded in the #' specified local directory. @@ -38,28 +39,59 @@ #' } ghd_copy <- function(gh_user, dest_dir, copy_type, protocol = NULL) { - if (is.character(gh_user) == FALSE) { - stop("Argument gh_user must be a character string that's a GitHub user.\n") + if (!is.character(gh_user)) { + cli::cli_abort( + c( + "Argument 'gh_user' must be a character string that's a GitHub user's profile name.", + "i" = "You provided an object of class {class(gh_user)}." + ) + ) } - if (is.character(dest_dir) == FALSE) { - stop("Argument dest_dir must be a character string that represents a file path.\n") + if (!is.character(dest_dir)) { + cli::cli_abort( + c( + "Argument 'dest_dir' must be a character string that represents a file path.", + "i" = "You provided an object of class {class(dest_dir)}." + ) + ) } if (!copy_type %in% c("download", "clone")) { - stop("Argument copy_type must be 'clone' or 'download'.\n") + cli::cli_abort( + c( + "Argument 'copy_type' must be 'clone' or 'download'.", + "i" = "You provided '{copy_type}'." + ) + ) } if (copy_type == "clone" & is.null(protocol)) { - stop("You must provide either 'https' or 'ssh' to the protocol argument.") + cli::cli_abort( + c( + "Argument 'protocol' must be 'https' or 'ssh'.", + "i" = "You provided '{protocol}'." + ) + ) } - if (copy_type == "clone" & !protocol %in% c("https", "ssh")) { - stop("You must provide either 'https' or 'ssh' to the protocol argument.") + if (copy_type == "clone" && !protocol %in% c("https", "ssh")) { + cli::cli_abort( + c( + "Argument 'protocol' must be 'https' or 'ssh'.", + "i" = "You provided '{protocol}'." + ) + ) } if (copy_type == "download" & !is.null(protocol)) { - warning("You don't need the protocol argument for downloads. Did you mean to clone instead?") + cli::cli_alert_warning( + paste( + "You don't need the 'protocol' argument for downloads.", + "Did you mean to clone instead?" + ) + ) + } # Get repo info for the user @@ -76,19 +108,22 @@ ghd_copy <- function(gh_user, dest_dir, copy_type, protocol = NULL) { prompt = paste0("Create new directory at path ", dest_dir, "? y/n: ") ) + is_yes <- substr(tolower(q_create_dir), 1, 1) == "y" + is_no <- substr(tolower(q_create_dir), 1, 1) == "n" + # Create the directory if 'yes' - if (substr(tolower(q_create_dir), 1, 1) == "y") { + if (is_yes) { # Create the directory dir.create(path = dest_dir) - } else if (substr(tolower(q_create_dir), 1, 1) == "n") { + } else if (is_no) { - stop("Aborted by user choice. Retry with another repo.\n") + cli::cli_abort("Aborted by user choice. Retry with another repo.") } else { - stop("Aborted. Input not understood.\n") + cli::cli_abort("Aborted. Input not understood.") } @@ -100,7 +135,7 @@ ghd_copy <- function(gh_user, dest_dir, copy_type, protocol = NULL) { ghd_clone_multi(gh_user, names_vec, protocol, dest_dir) - cat("Finished cloning\n") + cli::cli_alert_success("Finished cloning.") } else if (copy_type == "download") { # if downloading @@ -112,26 +147,31 @@ ghd_copy <- function(gh_user, dest_dir, copy_type, protocol = NULL) { # Ask if all should be unzipped q_unzip <- readline("Unzip all folders? y/n: ") + is_yes <- substr(tolower(q_unzip), 1, 1) == "y" + is_no <- substr(tolower(q_unzip), 1, 1) == "n" - if (substr(tolower(q_unzip), 1, 1) == "y") { + if (is_yes) { # Unzip the files ghd_unzip(dest_dir) - } else if (substr(tolower(q_unzip), 1, 1) == "n") { + } else if (is_no) { - cat("The downloaded directories will not be unzipped.\n") + cli::cli_alert_info("The downloaded directories will not be unzipped.") } else { - cat( - "Input not understood. The downloaded directories will not be unzipped.\n", - "See ?ghdump:::ghd_unzip() to unzip the directories yourself.\n" + cli::cli_alert_warning( + "Input not understood. The downloaded directories will not be unzipped." + ) + + cli::cli_alert_info( + "See ?ghdump:::ghd_unzip() to unzip the directories yourself." ) } - cat("Finished downloading\n") + cli::cli_alert_success("Finished downloading.") } diff --git a/README.md b/README.md index dc801c3..3df2648 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,11 @@ # ghdump -[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) +[![Project Status: Inactive – The project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows.](https://www.repostatus.org/badges/latest/inactive.svg)](https://www.repostatus.org/#inactive) +[![R-CMD-check](https://github.com/matt-dray/ghdump/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/matt-dray/ghdump/actions/workflows/R-CMD-check.yaml) [![rostrum.blog post](https://img.shields.io/badge/rostrum.blog-post-008900?style=flat&labelColor=black&logo=data:image/gif;base64,R0lGODlhEAAQAPEAAAAAABWCBAAAAAAAACH5BAlkAAIAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAAC55QkISIiEoQQQgghRBBCiCAIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAAh+QQJZAACACwAAAAAEAAQAAAC55QkIiESIoQQQgghhAhCBCEIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAA7)](https://www.rostrum.blog/2020/06/14/ghdump/) + ## Purpose @@ -60,8 +62,7 @@ To download: ghdump::ghd_copy( gh_user = "matt-dray", dest_dir = "~/Documents/repos", - copy_type = "download", - protocol = "https" + copy_type = "download" ) ``` @@ -76,7 +77,7 @@ The function is designed to be used interactively and infrequently. To this end, ## Credits -The function interacts with the GitHub API thanks to [the {gh} package](https://github.com/r-lib/gh) by Gábor Csárdi, Jenny Bryan and Hadley Wickham. Iteration is thanks to [the {purrr} package](https://purrr.tidyverse.org/) by Lionel Henry and Hadley Wickham. +The function interacts with the GitHub API thanks to [the {gh} package](https://github.com/r-lib/gh) by Gábor Csárdi, Jenny Bryan and Hadley Wickham. Iteration is thanks to [the {purrr} package](https://purrr.tidyverse.org/) by Lionel Henry and Hadley Wickham. [The {cli} package](https://cli.r-lib.org/) allowed for a prettier user interface. The {ghdump} package sticker was made thanks to Dmytro Perepolkin's [{bunny}](https://github.com/dmi3kno/bunny) package and the [{magick} package](https://cran.r-project.org/web/packages/magick/vignettes/intro.html) from Jeroen Ooms. diff --git a/man/ghd_copy.Rd b/man/ghd_copy.Rd index f5225e0..5e295e5 100644 --- a/man/ghd_copy.Rd +++ b/man/ghd_copy.Rd @@ -30,7 +30,8 @@ all as zip files and then optionally unzip them. Make sure you've got a GitHub account and have \href{https://happygitwithr.com/github-pat.html}{generated a GitHub PAT} and stored it your .Renviron. If you're using \code{protocol = "ssh"}, -you need to make sure you have \href{https://happygitwithr.com/ssh-keys.html}{set up your SSH keys}. +you need to make sure you have +\href{https://happygitwithr.com/ssh-keys.html}{set up your SSH keys}. } \examples{ \dontrun{ diff --git a/man/ghd_extract_names.Rd b/man/ghd_extract_names.Rd index 9f756b5..8a5ef3c 100644 --- a/man/ghd_extract_names.Rd +++ b/man/ghd_extract_names.Rd @@ -7,7 +7,8 @@ ghd_extract_names(repo_object) } \arguments{ -\item{repo_object}{A gh_response object, as returned by \code{\link{ghd_get_repos}}.} +\item{repo_object}{A gh_response object, as returned by +\code{\link{ghd_get_repos}}.} } \value{ A character vector of GitHub repo names. diff --git a/man/ghd_get_repos.Rd b/man/ghd_get_repos.Rd index 1808ef6..1912086 100644 --- a/man/ghd_get_repos.Rd +++ b/man/ghd_get_repos.Rd @@ -10,12 +10,13 @@ ghd_get_repos(gh_user) \item{gh_user}{Character string. A GitHub username.} } \value{ -A gh_response object. +A gh_response (list) object. } \description{ Uses \code{\link[gh]{gh}} to access the GitHub API and get the details for all of a named user's repos. To use this function you need to have created a GitHub account and to have put a GitHub Personal Access Token (PAT) in your -.Renviron. See \href{https://happygitwithr.com/github-pat.html}{Happy Git and GitHub for the UseR} +.Renviron. See +\href{https://happygitwithr.com/github-pat.html}{Happy Git and GitHub for the UseR} for more information. } diff --git a/man/ghdump-package.Rd b/man/ghdump-package.Rd index 37d0eff..297a5b8 100644 --- a/man/ghdump-package.Rd +++ b/man/ghdump-package.Rd @@ -6,9 +6,7 @@ \alias{ghdump-package} \title{ghdump: Clone Or Download All Repos For A GitHub User} \description{ -Clone all of a GitHub user's repositories, or download them as zip - files to a specified location and optionally unzip them. Intended for - archiving or setting up a new computer. +Clone all of a GitHub user's repositories, or download them as zip files to a specified location and optionally unzip them. Intended for archiving or setting up a new computer. } \seealso{ Useful links: From 88fa1aa013744da0a4674c09d4c5b2425d68ae4c Mon Sep 17 00:00:00 2001 From: Matt Dray <18232097+matt-dray@users.noreply.github.com> Date: Wed, 21 Jun 2023 19:11:37 +0100 Subject: [PATCH 2/2] Update README, close #12 --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3df2648..d915798 100644 --- a/README.md +++ b/README.md @@ -12,25 +12,26 @@ post](https://img.shields.io/badge/rostrum.blog-post-008900?style=flat&labelColo ## Purpose -Clone all of a GitHub user's repositories, or download them as zip files to a specified location and unzip them. Intended for archiving purposes or setting up on a new computer. +Clone all of a GitHub user's repositories, or download them as zip files (and optionally unzip them). Intended for archiving purposes or setting up on a new computer. ## Using {ghdump} Learn more about this package from [an associated blog post](https://www.rostrum.blog/2020/06/14/ghdump/). -Note that the package is under development, may not work in all environments and is not fully tested. Use at own risk. +Note that the package does what I need it to do, but is not fully tested for all systems and set-ups. Please [file an issue](https://github.com/matt-dray/ghdump/issues) or raise a pull request if you have a problem or contribution. ### Install -You can install the developer version of {ghdump} from GitHub with: +You can install {ghdump} from GitHub with: ``` r +install.packages("remotes") # if not yet installed remotes::install_github("matt-dray/ghdump") ``` ### GitHub PAT -You'll need a GitHub Personal Access Token to use {ghdump}. +You'll need a GitHub Personal Access Token (PAT) to use {ghdump}. Assuming you have a GitHub account, generate a token for accessing the GitHub API and store this in your .Renviron file. The {usethis} package helps make this a breeze. Read more in the [Happy Git and GitHub for the useR](https://happygitwithr.com/github-pat.html) book by Jenny Bryan, the STAT 545 TAs and Jim Hester. @@ -43,7 +44,7 @@ Make sure to restart R after these steps. ### Use `ghd_copy()` -{ghdump} has one exported function: `ghd_copy()`. Pass to the function a GitHub user name, a local directory to download into and whether you want to download or clone the repos. If you want to clone, you must [specify the protocol](https://docs.github.com/en/github/using-git/which-remote-url-should-i-use) (make sure [your keys are set up](https://happygitwithr.com/ssh-keys.html) if specifying SSH). +{ghdump} has one exported function: `ghd_copy()`. Pass to the function a GitHub user name, a local directory to download into, and whether you want to download or clone the repos. If you want to clone, you must [specify the protocol](https://docs.github.com/en/github/using-git/which-remote-url-should-i-use) (make sure [your keys are set up](https://happygitwithr.com/ssh-keys.html) if specifying SSH). To clone: @@ -73,11 +74,11 @@ The function is designed to be used interactively and infrequently. To this end, * commit to downloading all zip files (if `copy_type = "download"`) and then whether to: * unzip all the files * retain the zip files - * rename the unzipped directories to remove the default '-master' suffix + * rename the unzipped directories to remove the default branch suffix (e.g. '-master') ## Credits -The function interacts with the GitHub API thanks to [the {gh} package](https://github.com/r-lib/gh) by Gábor Csárdi, Jenny Bryan and Hadley Wickham. Iteration is thanks to [the {purrr} package](https://purrr.tidyverse.org/) by Lionel Henry and Hadley Wickham. [The {cli} package](https://cli.r-lib.org/) allowed for a prettier user interface. +The function interacts with the GitHub API thanks to [the {gh} package](https://github.com/r-lib/gh) by Gábor Csárdi, Jenny Bryan and Hadley Wickham. Iteration is thanks to [the {purrr} package](https://purrr.tidyverse.org/) by Lionel Henry and Hadley Wickham. [The {cli} package](https://cli.r-lib.org/) by Gábor Csárdi allowed for a prettier user interface. The {ghdump} package sticker was made thanks to Dmytro Perepolkin's [{bunny}](https://github.com/dmi3kno/bunny) package and the [{magick} package](https://cran.r-project.org/web/packages/magick/vignettes/intro.html) from Jeroen Ooms.