Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable package installation from GitHub, Bioconductor and local directory. #509

Merged
merged 6 commits into from
Nov 13, 2023
Merged
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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: rhino
Title: A Framework for Enterprise Shiny Applications
Version: 1.5.0.9000
Version: 1.5.0.9001
Authors@R:
c(
person("Kamil", "Żyła", role = c("aut", "cre"), email = "[email protected]"),
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# rhino (development)

1. Cypress updated to version 13.
2. `pkg_install` supports installation from local sources, GitHub, and Bioconductor.

# [rhino 1.5.0](https://github.com/Appsilon/rhino/releases/tag/v1.5.0)

Expand Down
37 changes: 35 additions & 2 deletions R/dependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ write_dependencies <- function(deps) {
writeLines(deps, "dependencies.R")
}

extract_package_name <- function(package) {
if (grepl("@", package)) package <- strsplit(package, "@")[[1]][1]

if (grepl("bioc::", package)) return(strsplit(package, "::")[[1]][2])

if (grepl("/", package)) {
package_splited <- strsplit(package, "/")[[1]]
return(package_splited[length(package_splited)])
}

package
}

extract_packages_names <- function(packages) {
purrr::map_chr(packages, extract_package_name)
}

# nolint start: line_length_linter
#' Manage dependencies
#'
Expand All @@ -47,6 +64,18 @@ write_dependencies <- function(deps) {
#' # Update shiny to the latest version
#' rhino::pkg_install("shiny")
#'
#' # Install a specific version of shiny
#' rhino::pkg_install("[email protected]")
#'
#' # Install shiny.i18n package from GitHub
#' rhino::pkg_install("Appsilon/shiny.i18n")
#'
#' # Install Biobase package from Bioconductor
#' rhino::pkg_install("bioc::Biobase")
#'
#' # Install shiny from local source
#' rhino::pkg_install("~/path/to/shiny")
#'
#' # Remove dplyr
#' rhino::pkg_remove("dplyr")
#' }
Expand All @@ -57,8 +86,10 @@ NULL
#' @export
pkg_install <- function(packages) {
stopifnot(is.character(packages))
packages_names <- extract_packages_names(packages)
cli::cli_alert_info("Installing packages: {packages_names}.")
renv::install(packages)
write_dependencies(c(packages, read_dependencies()))
write_dependencies(c(packages_names, read_dependencies()))
renv::snapshot()
invisible()
}
Expand All @@ -67,8 +98,10 @@ pkg_install <- function(packages) {
#' @export
pkg_remove <- function(packages) {
stopifnot(is.character(packages))
packages_names <- extract_packages_names(packages)
cli::cli_alert_info("Removing packages: {packages_names}.")
renv::remove(packages)
write_dependencies(setdiff(read_dependencies(), packages))
write_dependencies(setdiff(read_dependencies(), packages_names))
renv::snapshot()
invisible()
}
12 changes: 12 additions & 0 deletions man/dependencies.Rd

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

57 changes: 57 additions & 0 deletions tests/e2e/test-dependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,60 @@ rhino::pkg_remove("dplyr")
testthat::expect_false(is_installed("dplyr"))
testthat::expect_identical(readLines("dependencies.R"), initial_dependencies)
testthat::expect_identical(readLines("renv.lock"), initial_lockfile)

# install package from GitHub

initial_dependencies <- readLines("dependencies.R")
initial_lockfile <- readLines("renv.lock")

# Check initial state.
testthat::expect_false(is_installed("shiny.i18n"))
testthat::expect_false(any(initial_dependencies == "library(shiny.i18n)"))
testthat::expect_false(any(initial_lockfile == ' "shiny.i18n": {'))

# Install package and check if it was done correctly.
rhino::pkg_install("Appsilon/shiny.i18n")
testthat::expect_true(is_installed("shiny.i18n"))
testthat::expect_setequal(
readLines("dependencies.R"),
c(initial_dependencies, "library(shiny.i18n)")
)
testthat::expect_contains(
readLines("renv.lock"),
' "shiny.i18n": {'
)

# Remove package and check if we're back to initial state.
rhino::pkg_remove("shiny.i18n")
testthat::expect_false(is_installed("shiny.i18n"))
testthat::expect_identical(readLines("dependencies.R"), initial_dependencies)
testthat::expect_identical(readLines("renv.lock"), initial_lockfile)


# install package from Bioconductor

initial_dependencies <- readLines("dependencies.R")
initial_lockfile <- readLines("renv.lock")

# Check initial state.
testthat::expect_false(is_installed("Biobase"))
testthat::expect_false(any(initial_dependencies == "library(Biobase)"))
testthat::expect_false(any(initial_lockfile == ' "Biobase": {'))

# Install package and check if it was done correctly.
rhino::pkg_install("bioc::Biobase")
testthat::expect_true(is_installed("Biobase"))
testthat::expect_setequal(
readLines("dependencies.R"),
c(initial_dependencies, "library(Biobase)")
)
testthat::expect_contains(
readLines("renv.lock"),
' "Biobase": {'
)

# Remove package and check if we're back to initial state.
rhino::pkg_remove("Biobase")
testthat::expect_false(is_installed("Biobase"))
testthat::expect_identical(readLines("dependencies.R"), initial_dependencies)
testthat::expect_identical(readLines("renv.lock"), initial_lockfile)
40 changes: 40 additions & 0 deletions tests/testthat/test-dependencies.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
describe("extract_package_name", {
it("returns the package name intact when using only the package name", {
expect_equal(extract_package_name("shiny"), "shiny")
})

it("returns the package name intact when using the package name and version", {
expect_equal(extract_package_name("[email protected]"), "shiny")
})

it("returns the package name when installing a package from GitHub", {
expect_equal(extract_package_name("r-lib/httr"), "httr")
expect_equal(extract_package_name("r-lib/testthat@c67018fa4970"), "testthat")
})

it("returns the package name when installing a package from a local path", {
expect_equal(extract_package_name("~/path/to/package"), "package")
})

it("returns the package name when installing a package from Bioconductor", {
expect_equal(extract_package_name("bioc::Biobase"), "Biobase")
})
})

describe("extract_packages_names", {
it("returns a vector of package names when installing multiple packages", {
expect_equal(extract_packages_names(c("shiny", "dplyr")), c("shiny", "dplyr"))
})
})

describe("pkg_install", {
it("throws an error when the argument is not a character vector", {
expect_error(pkg_install(1))
})
})

describe("pkg_remove", {
it("throws an error when the argument is not a character vector", {
expect_error(pkg_remove(1))
})
})
Loading