Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 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: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# plumber (development version)

* Always mount OpenAPI documentation at `/__docs__/` as the first mount to have preference when using conflicting mount locations (e.g. a static mount at `/`). (#882)


# plumber 1.2.1

Expand Down
16 changes: 14 additions & 2 deletions R/plumber.R
Original file line number Diff line number Diff line change
Expand Up @@ -250,24 +250,34 @@ Plumber <- R6Class(
}

# Set and restore the wd to make it appear that the proc is running local to the file's definition.
old_wd <- NULL
if (!is.null(private$filename)) {
old_wd <- setwd(dirname(private$filename))
on.exit({setwd(old_wd)}, add = TRUE)
Comment thread
schloerke marked this conversation as resolved.
}

# Run user exit hooks given docs and wd are still set
on.exit(private$runHooks("exit"), add = TRUE)

if (isTRUE(docs_info$enabled)) {
mount_docs(
pr = self,
pr_private = private,
host = host,
port = port,
docs_info = docs_info,
callback = swaggerCallback,
quiet = quiet
)
# Unmount the docs before restoring the wd
# Unmount needs to happen after exit hooks
# No guarantee that new exit hooks are not added after running API
on.exit(unmount_docs(self, docs_info), add = TRUE)
}

on.exit(private$runHooks("exit"), add = TRUE)
# Restore the prior working directory after exit hooks have run
if (!is.null(old_wd)) {
on.exit(setwd(old_wd), add = TRUE)
}

httpuv::runServer(host, port, self)
},
Expand Down Expand Up @@ -299,6 +309,8 @@ Plumber <- R6Class(
path <- paste0(path, "/")
}

# Mount order matters
# Append a mounted router
private$mnts[[path]] <- router
},
#' @description Unmount a Plumber router
Expand Down
14 changes: 12 additions & 2 deletions R/ui.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#' @include globals.R
docs_root <- paste0("/__docs__/")

# Mount OpenAPI and Docs
#' @noRd
mount_docs <- function(pr, host, port, docs_info, callback, quiet = FALSE) {
mount_docs <- function(pr, pr_private, host, port, docs_info, callback, quiet = FALSE) {

# return early if not enabled
if (!isTRUE(docs_info$enabled)) {
Expand Down Expand Up @@ -34,7 +35,17 @@ mount_docs <- function(pr, host, port, docs_info, callback, quiet = FALSE) {

if (is_docs_available(docs_info$docs)) {
docs_mount <- .globals$docs[[docs_info$docs]]$mount
current_mnt_names <- names(pr_private$mnts)
docs_url <- do.call(docs_mount, c(list(pr, api_url), docs_info$args))
# Mount order matters
# Move new & ordered docs mounts to the front to be processed first
post_mnt_names <- names(pr_private$mnts)
doc_paths <- setdiff(post_mnt_names, current_mnt_names)
pr_private$mnts <- c(
pr_private$mnts[doc_paths],
pr_private$mnts[setdiff(post_mnt_names, doc_paths)]
)

if (!isTRUE(quiet)) {
message("Running ", docs_info$docs, " Docs at ", docs_url, sep = "")
}
Expand Down Expand Up @@ -184,7 +195,6 @@ register_docs <- function(name, index, static = NULL) {
stopifnot(is.function(index))
if (!is.null(static)) stopifnot(is.function(static))

docs_root <- paste0("/__docs__/")
docs_paths <- c("/index.html", "/")
mount_docs_func <- function(pr, api_url, ...) {
# Save initial extra argument values
Expand Down
6 changes: 6 additions & 0 deletions tests/testthat/helper-interrupt.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

with_interrupt <- function(expr, delay = 0) {
# Causes pr_run() to immediately exit
later::later(httpuv::interrupt, delay = delay)
force(expr)
}
6 changes: 0 additions & 6 deletions tests/testthat/test-plumber-run.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@

with_interrupt <- function(expr) {
# Causes pr_run() to immediately exit
later::later(httpuv::interrupt)
force(expr)
}

test_that("quiet=TRUE suppresses startup messages", {
with_interrupt({
expect_message(pr() %>% pr_run(quiet = TRUE), NA)
Expand Down
26 changes: 26 additions & 0 deletions tests/testthat/test-ui.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

test_that("doc mounts are prepended", {

assertions <- 0

root <-
test_path("files/static.R") %>%
pr() %>%
pr_set_docs(TRUE) %>%
pr_hook("exit", function(...) {
expect_length(root$mounts, 3)
assertions <<- assertions + 1
expect_equal(names(root$mounts)[1], "/__docs__/")
assertions <<- assertions + 1
})

expect_length(root$mounts, 2)
assertions <- assertions + 1

# no docs. do not find printed message
with_interrupt({
root %>% pr_run()
})

expect_equal(assertions, 3)
})