Skip to content

Commit

Permalink
Merge pull request #1 from vimc/vimc-7256
Browse files Browse the repository at this point in the history
Add shared drive remote
  • Loading branch information
r-ash authored Dec 4, 2023
2 parents c379e4f + 2dbeaf3 commit 17f23f8
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 342 deletions.
7 changes: 3 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ Encoding: UTF-8
LazyData: true
Language: en-GB
Imports:
cli,
orderly1 (>= 1.7.0),
spud (>= 0.1.5),
zip
Suggests:
mockery,
openssl,
testthat
Remotes:
reside-ic/spud,
orderly1=vimc/orderly@vimc-7135
RoxygenNote: 7.0.2
RoxygenNote: 7.2.3
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Generated by roxygen2: do not edit by hand

export(orderly_remote_sharepoint)
export(orderly_remote_sharedrive)
118 changes: 31 additions & 87 deletions R/orderly.R
Original file line number Diff line number Diff line change
@@ -1,133 +1,77 @@
##' Implements an orderly "remote" using Sharepoint as a backend. Use
##' Implements an orderly "remote" using a shared drive as a backend. Use
##' this within an \code{orderly_config.yml} configuration.
##'
##' A configuration might look like:
##'
##' \preformatted{
##' remote:
##' real:
##' driver: orderly.sharepoint::orderly_remote_sharepoint
##' driver: orderly.sharedrive::orderly_remote_sharedrive
##' args:
##' url: https://example.sharepoint.com
##' site: mysite
##' path: Shared Documents/orderly/real
##' path: ~/path/to/network/drive
##' }
##'
##' which would create a remote called \code{real}, using your group's
##' Sharepoint hosted at \code{https://example.sharepoint.com}, on
##' site \code{mysite} and within that site using path \code{Shared
##' Documents/orderly/real}.
##'
##' Currently authentication is interactive, or uses the values of
##' environment variables \code{SHAREPOINT_USERNAME} and
##' \code{SHAREPOINT_PASS}. Once we expose richer authentication
##' approaches in spud that will be exposed here (RESIDE-162).
##' which would create a remote called \code{real}, at the file path
##' specified. This can be a network drive or a one drive synced drive.
##'
##' This function is not intended to be used interactively
##'
##' @title Create an orderly remote based on Sharepoint
##'
##' @param url Sharepoint URL
##'
##' @param site Sharepoint "site"
##' @title Create an orderly remote based at a path
##'
##' @param path Path within the Sharepoint site. In our experience
##' these often start with \code{Shared Documents} but your setup
##' may vary.
##' @param path Path to use as a remote
##'
##' @param name Friendly name for the remote
##'
##' @return An \code{orderly_remote_sharepoint} object
##' @return An \code{orderly_remote_sharepoint} object, designed to be
##' @return An \code{orderly_remote_sharedrive} object
##' @return An \code{orderly_remote_sharedrive} object, designed to be
##' used by orderly. This function should however not generally be
##' called by users directly, as it should be used within
##' \code{orderly_config.yml}
##' @export
orderly_remote_sharepoint <- function(url, site, path, name = NULL) {
client <- orderly_sharepoint_client(url)
folder <- orderly_sharepoint_folder(client, site, path)
orderly_remote_sharepoint_$new(folder, name)
}


## Seems hard to mock the whole class out, which I think validates my
## general approach of exposing free constructor!
## https://github.com/r-lib/mockery/issues/21
orderly_sharepoint_client <- function(url) {
spud::sharepoint$new(url) # nocov
orderly_remote_sharedrive <- function(path, name = NULL) {
orderly_remote_sharedrive_$new(path, name)
}


orderly_sharepoint_folder <- function(client, site, path) {
folder <- tryCatch(
client$folder(site, path, verify = TRUE),
error = function(e)
stop(sprintf("Error reading from %s:%s - %s",
site, path, e$message), call. = FALSE))
path <- "orderly.sharepoint"
exists <- tryCatch({
folder$download(path)
TRUE
}, error = function(e) FALSE)
if (exists) {
return(folder)
}
if (nrow(folder$list()) > 0L) {
stop(sprintf(
"Directory %s:%s cannot be used for orderly; contains other files",
site, path))
}
tmp <- tempfile()
on.exit(unlink(tmp))
writeLines("orderly.sharepoint", tmp)
folder$upload(tmp, path)
folder$create("archive")
folder
}


orderly_remote_sharepoint_ <- R6::R6Class(
"orderly_remote_sharepoint",
orderly_remote_sharedrive_ <- R6::R6Class(
"orderly_remote_sharedrive",
cloneable = FALSE,

public = list(
folder = NULL,
path = NULL,
archive_root = NULL,
name = NULL,

initialize = function(folder, name = NULL) {
self$folder <- folder
initialize = function(path, name = NULL) {
self$path <- path
self$archive_root <- file.path(path, "archive")
self$name <- name
},

list_reports = function() {
sort(self$folder$folders("archive")$name)
basename(list.dirs(self$archive_root, recursive = FALSE))
},

list_versions = function(name) {
sort(self$folder$files(file.path("archive", name))$name)
sort(list.files(file.path(self$archive_root, name)))
},

push = function(path) {
path_meta <- file.path(path, "orderly_run.rds")
stopifnot(file.exists(path_meta))

zip <- tempfile(fileext = ".zip")
zip_dir(path, zip)
on.exit(unlink(zip))
if (!file.exists(path_meta)) {
cli::cli_abort("Can't push report at path '{path_meta}', report doesn't exist.")
}

dat <- readRDS(path_meta)
name <- dat$meta$name
id <- dat$meta$id

self$folder$create(file.path("archive", name))
self$folder$upload(zip, file.path("archive", name, id))
dir.create(file.path(self$archive_root, name), FALSE, TRUE)
zip_dir(path, file.path(self$archive_root, name, id))
},

pull = function(name, id) {
zip <- tempfile(fileext = ".zip")
on.exit(unlink(zip))
zip <- self$folder$download(file.path("archive", name, id), zip)
unzip_archive(zip, name, id)
unzip_archive(file.path(self$archive_root, name, id), name, id)
},

metadata = function(name, id) {
Expand All @@ -136,22 +80,22 @@ orderly_remote_sharepoint_ <- R6::R6Class(
},

run = function(...) {
stop("'orderly_remote_sharepoint' remotes do not run")
stop("'orderly_remote_sharedrive' remotes do not run")
},

kill = function(...) {
stop("'orderly_remote_sharepoint' remotes do not support kill")
stop("'orderly_remote_sharedrive' remotes do not support kill")
},

url_report = function(name, id) {
stop("'orderly_remote_sharepoint' remotes do not support urls")
stop("'orderly_remote_sharedrive' remotes do not support urls")
},

bundle_pack = function(...) {
stop("'orderly_remote_sharepoint' remotes do not support bundles")
stop("'orderly_remote_sharedrive' remotes do not support bundles")
},

bundle_import = function(...) {
stop("'orderly_remote_sharepoint' remotes do not support bundles")
stop("'orderly_remote_sharedrive' remotes do not support bundles")
}
))
3 changes: 3 additions & 0 deletions R/tools.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## NOTE: duplicated out of orderlyweb for now - it's not clear where
## this really belongs. See VIMC-3771
unzip_archive <- function(zip, name, id) {
if (!file.exists(zip)) {
cli::cli_abort("Can't pull archive from '{zip}', file doesn't exist.")
}
dest <- tempfile()
res <- utils::unzip(zip, exdir = dest)

Expand Down
7 changes: 4 additions & 3 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Sharepoint
Sharepoint's
Sharedrive
codecov
io
sharepoint
sharedrive
vimc
onedrive
41 changes: 41 additions & 0 deletions man/orderly_remote_sharedrive.Rd

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

56 changes: 0 additions & 56 deletions man/orderly_remote_sharepoint.Rd

This file was deleted.

39 changes: 39 additions & 0 deletions tests/testthat/helper-orderly.sharedrive.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#' Set up orderly for tests
#'
#' This will create an orderly instance with 2 run reports
#' * example which has been run twice
#' * example2 which has also been run twice
#'
#' @param add_remote If true then will setup a sharedrive remote and push
#' all reports to it.
#'
#' @return The path to the orderly instance
setup_orderly <- function(add_remote = TRUE) {
path <- orderly1::orderly_example("minimal")
example1_1 <- orderly1::orderly_run("example", root = path, echo = FALSE)
p1 <- orderly1::orderly_commit(example1_1, root = path)
example1_2 <- orderly1::orderly_run("example", root = path, echo = FALSE)
p2 <- orderly1::orderly_commit(example1_2, root = path)
example2_1 <- orderly1::orderly_run("example2", root = path, echo = FALSE)
p3 <- orderly1::orderly_commit(example2_1, root = path)
example2_2 <- orderly1::orderly_run("example2", root = path, echo = FALSE)
p4 <- orderly1::orderly_commit(example2_2, root = path)

remote_path <- NULL
if (add_remote) {
remote_path <- tempfile()

cl <- orderly_remote_sharedrive(remote_path)
res1 <- cl$push(p1)
res2 <- cl$push(p2)
res3 <- cl$push(p3)
res4 <- cl$push(p4)
}

list(
root = path,
remote = remote_path,
report_paths = list(example = c(p1, p2),
example2 = c(p3, p4))
)
}
Loading

0 comments on commit 17f23f8

Please sign in to comment.