Skip to content

Commit

Permalink
Merge pull request #221 from b-rodrigues/local_hash
Browse files Browse the repository at this point in the history
- Compute hash of git and CRAN archive packages locally if nix is installed
  • Loading branch information
philipp-baumann authored Jun 30, 2024
2 parents 41ba6c1 + 2ff3bf2 commit 4ffe9f5
Show file tree
Hide file tree
Showing 19 changed files with 716 additions and 286 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
72 changes: 52 additions & 20 deletions R/fetchers.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#' fetchgit Downloads and installs a package hosted of Git
#' @param git_pkg A list of four elements: "package_name", the name of the package, "repo_url", the repository's url, "branch_name", the name of the branch containing the code to download and "commit", the commit hash of interest.
#' @return A character. The Nix definition to download and build the R package from Github.
#' @param git_pkg A list of four elements: "package_name", the name of the
#' package, "repo_url", the repository's url, "branch_name", the name of the
#' branch containing the code to download and "commit", the commit hash of
#' interest.
#' @return A character. The Nix definition to download and build the R package
#' from Github.
#' @noRd
fetchgit <- function(git_pkg) {
package_name <- git_pkg$package_name
Expand Down Expand Up @@ -40,7 +44,7 @@ fetchgit <- function(git_pkg) {


#' fetchzip Downloads and installs an archived CRAN package
#' @param archive_pkg A character of the form "dplyr@0.80"
#' @param archive_pkg A character of the form `"dplyr@0.80"`
#' @return A character. The Nix definition to download and build the R package from CRAN.
#' @noRd
fetchzip <- function(archive_pkg, sri_hash = NULL) {
Expand Down Expand Up @@ -104,17 +108,27 @@ remove_base <- function(list_imports) {
}




#' Finds dependencies of a package from the DESCRIPTION file
#' @param path path to package
#' @importFrom utils untar
#' @return Atomic vector of packages
#' @noRd
get_imports <- function(path) {
tmp_dir <- tempdir()
untar(path, exdir = tmp_dir)

paths <- list.files(tmp_dir, full.names = TRUE, recursive = TRUE)
desc_path <- grep("DESCRIPTION", paths, value = TRUE)
# Is the path pointing to a tar.gz archive
# or directly to a DESCRIPTION file?
if (grepl("\\.tar\\.gz", path)) {
untar(path, exdir = tmp_dir)
paths <- list.files(tmp_dir, full.names = TRUE, recursive = TRUE)
desc_path <- grep("DESCRIPTION", paths, value = TRUE)
} else if (grepl("DESCRIPTION", path)) {
desc_path <- path
} else {
stop("Path is neither a .tar.gz archive, nor pointing to a DESCRIPTION file directly.")
}

columns_of_interest <- c("Depends", "Imports", "LinkingTo")

Expand All @@ -128,10 +142,10 @@ get_imports <- function(path) {

output <- unname(trimws(unlist(strsplit(unlist(imports), split = ","))))

# Remove version of R that may be listed in 'Depends'
# Remove version of R that may be listed in 'Depends'
output <- Filter(function(x) !grepl("R \\(.*\\)", x), output)

# Remove minimum package version for example 'packagename ( > 1.0.0)'
# Remove minimum package version for example 'packagename ( > 1.0.0)'
output <- trimws(gsub("\\(.*?\\)", "", output))

output <- remove_base(unique(output))
Expand All @@ -141,7 +155,9 @@ get_imports <- function(path) {


#' fetchlocal Installs a local R package
#' @param local_pkg A list of local package names ('.tar.gz' archives) to install. These packages need to be in the same folder as the generated `default.nix` file.
#' @param local_pkg A list of local package names ('.tar.gz' archives) to
#' install. These packages need to be in the same folder as the generated
#' `default.nix` file.
#' @importFrom utils tail
#' @return A character. The Nix definition to build the R package from local sources.
#' @noRd
Expand Down Expand Up @@ -173,8 +189,10 @@ fetchlocal <- function(local_pkg) {
}

#' fetchlocals Installs a local R package
#' @param local_pkgs Either a list of paths to local packages, or a path to a single package
#' @return A character. The Nix definition to build the local R packages from local sources.
#' @param local_pkgs Either a list of paths to local packages, or a path to a
#' single package
#' @return A character. The Nix definition to build the local R packages from
#' local sources.
#' @noRd
fetchlocals <- function(local_pkgs) {
paths_exist <- file.exists(local_pkgs)
Expand All @@ -195,9 +213,14 @@ fetchlocals <- function(local_pkgs) {



#' fetchgits Downloads and installs packages hosted on Git. Wraps `fetchgit()` to handle multiple packages
#' @param git_pkgs A list of four elements: "package_name", the name of the package, "repo_url", the repository's url, "branch_name", the name of the branch containing the code to download and "commit", the commit hash of interest. This argument can also be a list of lists of these four elements.
#' @return A character. The Nix definition to download and build the R package from Github.
#' fetchgits Downloads and installs packages hosted on Git. Wraps `fetchgit()`
#' to handle multiple packages
#' @param git_pkgs A list of four elements: "package_name", the name of the
#' package, "repo_url", the repository's url, "branch_name", the name of the
#' branch containing the code to download and "commit", the commit hash of
#' interest. This argument can also be a list of lists of these four elements.
#' @return A character. The Nix definition to download and build the R package
#' from Github.
#' @noRd
fetchgits <- function(git_pkgs) {
if (!all(vapply(git_pkgs, is.list, logical(1)))) {
Expand All @@ -209,9 +232,11 @@ fetchgits <- function(git_pkgs) {
}
}

#' fetchzips Downloads and installs packages hosted in the CRAN archives. Wraps `fetchzip()` to handle multiple packages.
#' fetchzips Downloads and installs packages hosted in the CRAN archives. Wraps
#' `fetchzip()` to handle multiple packages.
#' @param archive_pkgs A character, or an atomic vector of characters.
#' @return A character. The Nix definition to download and build the R package from the CRAN archives.
#' @return A character. The Nix definition to download and build the R package
#' from the CRAN archives.
#' @noRd
fetchzips <- function(archive_pkgs) {
if (is.null(archive_pkgs)) {
Expand All @@ -221,14 +246,21 @@ fetchzips <- function(archive_pkgs) {
} else if (length(archive_pkgs) > 1) {
paste(lapply(archive_pkgs, fetchzip), collapse = "\n")
} else {
stop("There is something wrong with the input. Make sure it is either a single package name, or an atomic vector of package names, for example c('dplyr@0.8.0', 'tidyr@1.0.0').")
stop("There is something wrong with the input. Make sure it is either",
"a single package name, or an atomic vector of package names, for",
"example, `c('dplyr@0.8.0', 'tidyr@1.0.0')`.")
}
}

#' fetchpkgs Downloads and installs packages hosted in the CRAN archives or Github.
#' @param git_pkgs A list of four elements: "package_name", the name of the package, "repo_url", the repository's url, "branch_name", the name of the branch containing the code to download and "commit", the commit hash of interest. This argument can also be a list of lists of these four elements.
#' fetchpkgs Downloads and installs packages hosted in the CRAN archives or
#' Github.
#' @param git_pkgs A list of four elements: "package_name", the name of the
#' package, "repo_url", the repository's url, "branch_name", the name of the
#' branch containing the code to download and "commit", the commit hash of
#' interest. This argument can also be a list of lists of these four elements.
#' @param archive_pkgs A character, or an atomic vector of characters.
#' @return A character. The Nix definition to download and build the R package from the CRAN archives.
#' @return A character. The Nix definition to download and build the R package
#' from the CRAN archives.
#' @noRd
fetchpkgs <- function(git_pkgs, archive_pkgs) {
paste(fetchgits(git_pkgs),
Expand Down
15 changes: 10 additions & 5 deletions R/ga_cachix.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ ga_cachix <- function(cache_name, path_default) {

path <- ".github/workflows"

dir.create(path, recursive = TRUE)
if (!dir.exists(path)) {
dir.create(path, recursive = TRUE)
}
} else {
path <- tempdir()
}

source <- system.file(
file.path("extdata", "cachix-dev-env.yaml"),
file.path("extdata", "cachix_dev_env.yaml"),
package = "rix",
mustWork = TRUE
)
Expand All @@ -54,13 +56,16 @@ ga_cachix <- function(cache_name, path_default) {
system(
paste0(
"sed -i ", darwin_specific_quotes, "'s/CACHE_NAME/", cache_name, "/g' ",
paste0(path, "/cachix-dev-env.yaml")
paste0(path, "/cachix_dev_env.yaml")
)
)

system(
paste0("sed -i ", darwin_specific_quotes, "'s/PATH_TO_DEFAULT_NIX/", path_default, "/g' ", paste0(path, "/cachix-dev-env.yaml"))
paste0("sed -i ", darwin_specific_quotes, "'s/PATH_TO_DEFAULT_NIX/",
path_default, "/g' ", file.path(path, "cachix_dev_env.yaml"))
)

if (identical(Sys.getenv("TESTTHAT"), "true")) paste0(path, "/cachix-dev-env.yaml")
if (identical(Sys.getenv("TESTTHAT"), "true")) {
file.path(path, "cachix_dev_env.yaml")
}
}
6 changes: 4 additions & 2 deletions R/get_latest.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ get_right_commit <- function(r_version) {
}


#' Try fetch contents of an URL with handle and stop with propagating the curl
#' error and also show URL for context
#' Fetch contents from an URL into memory
#'
#' Fetch if available and stop with propagating the curl error. Also show URL
#' for context
#' @noRd
try_get_request <- function(url,
handle,
Expand Down
37 changes: 0 additions & 37 deletions R/get_sri_hash_deps.R
Original file line number Diff line number Diff line change
@@ -1,37 +0,0 @@
#' get_sri_hash_deps Get the SRI hash of the NAR serialization of a Github repo
#' @param repo_url A character. The URL to the package's Github repository or to the `.tar.gz` package hosted on CRAN.
#' @param branch_name A character. The branch of interest, NULL for archived CRAN packages.
#' @param commit A character. The commit hash of interest, for reproducibility's sake, NULL for archived CRAN packages.
#' @return list with following elements:
#' - `sri_hash`: string with SRI hash of the NAR serialization of a Github repo
#' - `deps`: string with R package dependencies separarated by space.
#' @noRd
get_sri_hash_deps <- function(repo_url, branch_name, commit) {
# handle to get error for status code 404
h <- curl::new_handle(failonerror = TRUE)

url <- paste0(
"http://git2nixsha.dev:1506/hash?repo_url=",
repo_url, "&branchName=", branch_name, "&commit=", commit
)

# extra diagnostics
extra_diagnostics <-
c(
"\nIf it's a Github repo, check the url, branch name and commit.\n",
"Are these correct? If it's an archived CRAN package, check the name\n",
"of the package and the version number."
)

req <- try_get_request(
url = url, handle = h,
extra_diagnostics = extra_diagnostics
)

# plumber endpoint delivers list with
# - `sri_hash`: string with SRI hash of the NAR serialization of a Github repo
# - `deps`: string with R package dependencies separated by `" "`
sri_hash_deps_list <- jsonlite::fromJSON(rawToChar(req$content))

return(sri_hash_deps_list)
}
8 changes: 4 additions & 4 deletions R/nix_build_helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ fix_ld_library_path <- function() {
#'
#' @noRd
poll_sys_proc_blocking <- function(cmd, proc,
what = c("nix-build", "expr"),
what = c("nix-build", "expr", "nix-hash"),
message_type =
c("simple", "quiet", "verbose")
) {
what <- match.arg(what, choices = c("nix-build", "expr"))
what <- match.arg(what, choices = c("nix-build", "expr", "nix-hash"))
message_type <- match.arg(message_type,
choices = c("simple", "quiet", "verbose"))
is_quiet <- message_type == "quiet"
Expand Down Expand Up @@ -99,10 +99,10 @@ poll_sys_proc_blocking <- function(cmd, proc,
#' @noRd
poll_sys_proc_nonblocking <- function(cmd,
proc,
what = c("nix-build", "expr"),
what = c("nix-build", "expr", "nix-hash"),
message_type =
c("simple", "quiet", "verbose")) {
what <- match.arg(what, choices = c("nix-build", "expr"))
what <- match.arg(what, choices = c("nix-build", "expr", "nix-hash"))
message_type <- match.arg(message_type,
choices = c("simple", "quiet", "verbose"))
is_quiet <- message_type == "quiet"
Expand Down
Loading

0 comments on commit 4ffe9f5

Please sign in to comment.