Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 31 additions & 33 deletions R/utils-github.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ resolve_package <- function(org, repo, ref = NULL, date = NULL) {
)
}

#' Execute a gh api call and return stdout/stderr lines
#' @keywords internal
Comment thread
zdz2101 marked this conversation as resolved.
#' @noRd
gh_api <- function(args) {
system2("gh", args, stdout = TRUE, stderr = TRUE)
}


#' Resolve a ref by date — find the latest release/tag on or before the given date
#'
Expand All @@ -67,31 +74,27 @@ resolve_ref_by_date <- function(org, repo, date = NULL) {

if (is.null(date)) {
# Get latest release tag
result <- system2(
"gh", c("api", paste0("repos/", full_repo, "/releases/latest"), "--jq", ".tag_name"),
stdout = TRUE, stderr = TRUE
result <- gh_api(
c("api", paste0("repos/", full_repo, "/releases/latest"), "--jq", ".tag_name")
)
if (length(result) > 0 && !grepl("Not Found", result[1])) {
return(trimws(result[1]))
}
# No releases — fall back to default branch
result <- system2(
"gh", c("api", paste0("repos/", full_repo), "--jq", ".default_branch"),
stdout = TRUE, stderr = TRUE
result <- gh_api(
c("api", paste0("repos/", full_repo), "--jq", ".default_branch")
)
return(trimws(result[1]))
}

# Get all release tag names and dates separately
tags <- system2(
"gh", c("api", paste0("repos/", full_repo, "/releases"), "--paginate",
"--jq", ".[].tag_name"),
stdout = TRUE, stderr = TRUE
tags <- gh_api(
c("api", paste0("repos/", full_repo, "/releases"), "--paginate",
"--jq", ".[].tag_name")
)
dates <- system2(
"gh", c("api", paste0("repos/", full_repo, "/releases"), "--paginate",
"--jq", ".[].published_at"),
stdout = TRUE, stderr = TRUE
dates <- gh_api(
c("api", paste0("repos/", full_repo, "/releases"), "--paginate",
"--jq", ".[].published_at")
)

if (length(tags) == 0 || all(grepl("Not Found", tags))) {
Expand Down Expand Up @@ -127,10 +130,9 @@ resolve_tag_by_date <- function(org, repo, date) {
full_repo <- paste0(org, "/", repo)

# Get tags with their commit dates
result <- system2(
"gh", c("api", paste0("repos/", full_repo, "/tags"), "--paginate",
"--jq", ".[].name"),
stdout = TRUE, stderr = TRUE
result <- gh_api(
c("api", paste0("repos/", full_repo, "/tags"), "--paginate",
"--jq", ".[].name")
)

if (length(result) == 0) {
Expand All @@ -139,16 +141,14 @@ resolve_tag_by_date <- function(org, repo, date) {

# For each tag, get the commit date
tag_dates <- lapply(result, function(tag) {
commit_info <- system2(
"gh", c("api", paste0("repos/", full_repo, "/git/ref/tags/", tag),
"--jq", ".object.sha"),
stdout = TRUE, stderr = TRUE
commit_info <- gh_api(
c("api", paste0("repos/", full_repo, "/git/ref/tags/", tag),
"--jq", ".object.sha")
)
sha <- trimws(commit_info[1])
commit_date_str <- system2(
"gh", c("api", paste0("repos/", full_repo, "/commits/", sha),
"--jq", ".commit.committer.date"),
stdout = TRUE, stderr = TRUE
commit_date_str <- gh_api(
c("api", paste0("repos/", full_repo, "/commits/", sha),
"--jq", ".commit.committer.date")
)
list(tag = tag, date = as.Date(substr(trimws(commit_date_str[1]), 1, 10)))
})
Expand All @@ -172,9 +172,8 @@ resolve_tag_by_date <- function(org, repo, date) {
#' @return Character. The full commit SHA.
gh_get_sha <- function(org, repo, ref) {
full_repo <- paste0(org, "/", repo)
result <- system2(
"gh", c("api", paste0("repos/", full_repo, "/commits/", ref), "--jq", ".sha"),
stdout = TRUE, stderr = TRUE
result <- gh_api(
c("api", paste0("repos/", full_repo, "/commits/", ref), "--jq", ".sha")
)
if (length(result) == 0 || grepl("Not Found", result[1])) {
stop("Could not resolve ref '", ref, "' for ", full_repo)
Expand All @@ -190,10 +189,9 @@ gh_get_sha <- function(org, repo, ref) {
#' @return Character. The package version string.
gh_get_version <- function(org, repo, sha) {
full_repo <- paste0(org, "/", repo)
result <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/DESCRIPTION?ref=", sha),
"--jq", ".content"),
stdout = TRUE, stderr = TRUE
result <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/DESCRIPTION?ref=", sha),
"--jq", ".content")
)

if (length(result) == 0 || grepl("Not Found", result[1])) {
Expand Down
41 changes: 15 additions & 26 deletions R/utils-workflows.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,26 @@ pull_workflows <- function(resolved, path) {
#' List contents of a GitHub directory, returning name/type/path for each entry
#' @keywords internal
gh_list_contents <- function(full_repo, dir_path, sha) {
json_str <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha)),
stdout = TRUE, stderr = TRUE
json_str <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha))
)

if (length(json_str) == 0 || any(grepl("Not Found", json_str))) {
return(NULL)
}

# Minimal JSON parsing — extract name, type, path from each object
json_text <- paste0(json_str, collapse = "\n")

# Use R's built-in JSON-ish parsing via the gh CLI --jq, but since that's

# problematic with escaping, parse the raw JSON with a simple approach
# We'll re-call gh with separate jq queries for each field
names <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].name"),
stdout = TRUE, stderr = TRUE
# Re-call gh with separate jq queries for each field.
names <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].name")
)
types <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].type"),
stdout = TRUE, stderr = TRUE
types <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].type")
)
paths <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].path"),
stdout = TRUE, stderr = TRUE
paths <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/", dir_path, "?ref=", sha),
"--jq", ".[].path")
)

if (length(names) == 0) return(NULL)
Expand Down Expand Up @@ -93,10 +83,9 @@ pull_workflow_dir <- function(full_repo, sha, api_path, local_dir) {
#' Pull a single workflow file from GitHub
#' @keywords internal
pull_workflow_file <- function(full_repo, sha, api_path, local_path) {
file_content <- system2(
"gh", c("api", paste0("repos/", full_repo, "/contents/", api_path, "?ref=", sha),
"--jq", ".content"),
stdout = TRUE, stderr = TRUE
file_content <- gh_api(
c("api", paste0("repos/", full_repo, "/contents/", api_path, "?ref=", sha),
"--jq", ".content")
)

if (length(file_content) > 0 && !any(grepl("Not Found", file_content))) {
Expand Down
Loading
Loading