From cd81ec57b570390d5e24c0ee1692e6fc8688b77c Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Wed, 24 Jun 2020 15:04:44 -0400 Subject: [PATCH 1/7] add router modifier tag support --- R/plumb-block.R | 29 +++++++++++++++++++------- R/plumber.R | 2 +- tests/testthat/files/router-modifier.R | 4 ++++ tests/testthat/test-router-modifier.R | 7 +++++++ 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 tests/testthat/files/router-modifier.R create mode 100644 tests/testthat/test-router-modifier.R diff --git a/R/plumb-block.R b/R/plumb-block.R index 0d4397e09..220757fc9 100644 --- a/R/plumb-block.R +++ b/R/plumb-block.R @@ -24,6 +24,7 @@ plumbBlock <- function(lineNum, file){ comments <- "" responses <- NULL tags <- NULL + routerModifier <- NULL while (lineNum > 0 && (stri_detect_regex(file[lineNum], pattern="^#['\\*]") || stri_trim_both(file[lineNum]) == "")){ line <- file[lineNum] @@ -207,6 +208,11 @@ plumbBlock <- function(lineNum, file){ comments <- paste(comments, commentMat[1,2]) } + routerModifierMat <- stri_match(line, regex="^#['\\*]\\s*@plumber(.*)$") + if (!is.na(routerModifierMat[1,2])) { + routerModifier <- TRUE + } + lineNum <- lineNum - 1 } @@ -221,20 +227,21 @@ plumbBlock <- function(lineNum, file){ params = rev(params), comments = comments, responses = responses, - tags = tags + tags = tags, + routerModifier = routerModifier ) } #' Evaluate and activate a "block" of code found in a plumber API file. #' @include images.R #' @noRd -evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, mount) { +evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, pr) { lineNum <- srcref[1] - 1 block <- plumbBlock(lineNum, file) - if (sum(!is.null(block$filter), !is.null(block$paths), !is.null(block$assets)) > 1){ - stopOnLine(lineNum, file[lineNum], "A single function can only be a filter, an API endpoint, or an asset (@filter AND @get, @post, @assets, etc.)") + if (sum(!is.null(block$filter), !is.null(block$paths), !is.null(block$assets), !is.null(block$routerModifier)) > 1){ + stopOnLine(lineNum, file[lineNum], "A single function can only be a filter, an API endpoint, an asset or a router modifier (@filter AND @get, @post, @assets, @plumber, etc.)") } # ALL if statements possibilities must eventually call eval(expr, envir) @@ -279,10 +286,18 @@ evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, mou } stat <- PlumberStatic$new(block$assets$dir, expr) - mount(path, stat) - + pr$mount(path, stat) + + } else if (!is.null(block$routerModifier)) { + if (is.expression(expr)){ + func <- eval(expr, envir) + if (is.function(func)) { + func(pr) + return() + } + } + message("Invalid expression for @plumber tag. Use form function(pr) {...}.") } else { - eval(expr, envir) } } diff --git a/R/plumber.R b/R/plumber.R index a5a1e8ddb..3365995d6 100644 --- a/R/plumber.R +++ b/R/plumber.R @@ -240,7 +240,7 @@ plumber <- R6Class( srcref <- attr(e, "srcref")[[1]][c(1,3)] evaluateBlock(srcref, private$lines, e, private$envir, private$addEndpointInternal, - private$addFilterInternal, self$mount) + private$addFilterInternal, self) } private$globalSettings <- plumbGlobals(private$lines) diff --git a/tests/testthat/files/router-modifier.R b/tests/testthat/files/router-modifier.R new file mode 100644 index 000000000..638a52b1f --- /dev/null +++ b/tests/testthat/files/router-modifier.R @@ -0,0 +1,4 @@ +#* @plumber +function(pr){ + pr$handle("GET", "/avatartare", function(raw) {raw}, serializer = serializer_json) +} diff --git a/tests/testthat/test-router-modifier.R b/tests/testthat/test-router-modifier.R new file mode 100644 index 000000000..109bedcf8 --- /dev/null +++ b/tests/testthat/test-router-modifier.R @@ -0,0 +1,7 @@ +context("Router modifier (@plumber tag)") + +test_that("router modifier tag works correctly", { + pr <- plumber$new(test_path("files/router-modifier.R")) + expect_equal(class(pr$routes[[1]])[1], "PlumberEndpoint") + expect_equal(names(pr$routes), "avatartare") +}) From 25435a3e7ff5d3dd95e45dffcc5e8393d6767290 Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Wed, 24 Jun 2020 15:14:46 -0400 Subject: [PATCH 2/7] news --- NEWS.md | 1 + R/plumb-block.R | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 0552f533c..c46d438d0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ plumber (version) ### New features +* Add support for @plumber tag that modify plumber router programmatically using expression of the form function(pr) {pr$...}. * CSV (UTF-8) serialization (@pachamaltese, #520) * SVG (UTF-8) serialization (@pachamaltese, #398) diff --git a/R/plumb-block.R b/R/plumb-block.R index 220757fc9..dcd5a3da5 100644 --- a/R/plumb-block.R +++ b/R/plumb-block.R @@ -296,7 +296,7 @@ evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, pr) return() } } - message("Invalid expression for @plumber tag. Use form function(pr) {...}.") + message("Invalid expression for @plumber tag. Use form function(pr) {pr$...}.") } else { eval(expr, envir) } From 649eb24beff668faa4d3f1dec0a6418e4c9a92fd Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Thu, 25 Jun 2020 10:54:19 -0400 Subject: [PATCH 3/7] Update NEWS.md Co-authored-by: Barret Schloerke --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index c46d438d0..1b80fb2c8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ plumber (version) ### New features -* Add support for @plumber tag that modify plumber router programmatically using expression of the form function(pr) {pr$...}. +* Add support for `#' @plumber` tag that modify plumber router programmatically using expression of the form `function(pr) {....}`. (@meztez and @blairj09, #568) * CSV (UTF-8) serialization (@pachamaltese, #520) * SVG (UTF-8) serialization (@pachamaltese, #398) From 463f59eb5b6e2331bcc99cc887441c348eab228f Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Thu, 25 Jun 2020 10:54:48 -0400 Subject: [PATCH 4/7] Update R/plumb-block.R Co-authored-by: Barret Schloerke --- R/plumb-block.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/plumb-block.R b/R/plumb-block.R index dcd5a3da5..041704254 100644 --- a/R/plumb-block.R +++ b/R/plumb-block.R @@ -208,8 +208,8 @@ plumbBlock <- function(lineNum, file){ comments <- paste(comments, commentMat[1,2]) } - routerModifierMat <- stri_match(line, regex="^#['\\*]\\s*@plumber(.*)$") - if (!is.na(routerModifierMat[1,2])) { + routerModifierMat <- stri_match(line, regex="^#['\\*]\\s*@plumber") + if (!is.na(routerModifierMat[1,1])) { routerModifier <- TRUE } From e6e39fbaff4f492c7276635660449f9464212718 Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Thu, 25 Jun 2020 10:55:11 -0400 Subject: [PATCH 5/7] Update R/plumb-block.R Co-authored-by: Barret Schloerke --- R/plumb-block.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plumb-block.R b/R/plumb-block.R index 041704254..db924c57c 100644 --- a/R/plumb-block.R +++ b/R/plumb-block.R @@ -296,7 +296,7 @@ evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, pr) return() } } - message("Invalid expression for @plumber tag. Use form function(pr) {pr$...}.") + message("Invalid expression for @plumber tag. Use form `function(pr) { }`.") } else { eval(expr, envir) } From cf1466ab082b2854c49ed675b0e8a99604028a07 Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Thu, 25 Jun 2020 15:59:14 -0400 Subject: [PATCH 6/7] Update NEWS.md Co-authored-by: Carson Sievert --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 8ed50c0e6..820f118de 100644 --- a/NEWS.md +++ b/NEWS.md @@ -36,7 +36,7 @@ plumber 1.0.0 * Added support for promises in endpoints, filters, and hooks. (#248) -* Add support for `#' @plumber` tag that modify plumber router programmatically using expression of the form `function(pr) {....}`. (@meztez and @blairj09, #568) +* Add support for `#' @plumber` tag to gain programmatic access to the `plumber` router via `function(pr) {....}`. (@meztez and @blairj09, #568) * Added Swagger support for array parameters using syntax `name:[type]` and new type `list` (synonym df, data.frame). (@meztez, #532) From 9633a9cdac5c9ccc99f4c7c499f0497ccc9e4d3e Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Thu, 25 Jun 2020 16:09:23 -0400 Subject: [PATCH 7/7] Update R/plumb-block.R Co-authored-by: Carson Sievert --- R/plumb-block.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plumb-block.R b/R/plumb-block.R index db924c57c..1f5102d18 100644 --- a/R/plumb-block.R +++ b/R/plumb-block.R @@ -296,7 +296,7 @@ evaluateBlock <- function(srcref, file, expr, envir, addEndpoint, addFilter, pr) return() } } - message("Invalid expression for @plumber tag. Use form `function(pr) { }`.") + stopOnLine(lineNum, file[lineNum], "Invalid expression for @plumber tag, please use the form `function(pr) { }`.") } else { eval(expr, envir) }