diff --git a/NEWS.md b/NEWS.md index 48fda94a..c832e132 100644 --- a/NEWS.md +++ b/NEWS.md @@ -20,6 +20,8 @@ * The `renv.lock` is ignored when the `RSCONNECT_PACKRAT` environment variable or the `rsconnect.packrat` option is set. (#936) +* The content type is inferred by analyzing the set of top-level files. (#942) + # rsconnect 1.0.1 * `deployDoc()` includes `.Rprofile`, `requirements.txt` and `renv.lock` when diff --git a/R/appMetadata.R b/R/appMetadata.R index 0a1b8234..b8cbecb5 100644 --- a/R/appMetadata.R +++ b/R/appMetadata.R @@ -36,7 +36,7 @@ appMetadata <- function(appDir, # Inference only uses top-level files rootFiles <- appFiles[dirname(appFiles) == "."] appMode <- inferAppMode( - file.path(appDir, appFiles), + file.path(appDir, rootFiles), usesQuarto = quarto, isShinyappsServer = isShinyappsServer ) @@ -117,7 +117,7 @@ checkAppLayout <- function(appDir, appPrimaryDoc = NULL) { } # infer the mode of the application from files in the root dir -inferAppMode <- function(absoluteAppFiles, +inferAppMode <- function(absoluteRootFiles, usesQuarto = NA, isShinyappsServer = FALSE) { @@ -127,24 +127,24 @@ inferAppMode <- function(absoluteAppFiles, } # plumber API - plumberFiles <- matchingNames(absoluteAppFiles, "^(plumber|entrypoint).r$") + plumberFiles <- matchingNames(absoluteRootFiles, "^(plumber|entrypoint).r$") if (length(plumberFiles) > 0) { return("api") } # Shiny application using single-file app.R style. - appR <- matchingNames(absoluteAppFiles, "^app.r$") + appR <- matchingNames(absoluteRootFiles, "^app.r$") if (length(appR) > 0) { return("shiny") } - rmdFiles <- matchingNames(absoluteAppFiles, "\\.rmd$") - qmdFiles <- matchingNames(absoluteAppFiles, "\\.qmd$") + rmdFiles <- matchingNames(absoluteRootFiles, "\\.rmd$") + qmdFiles <- matchingNames(absoluteRootFiles, "\\.qmd$") if (is.na(usesQuarto)) { # Can't use _quarto.yml alone because it causes deployment failures for # static content: https://github.com/rstudio/rstudio/issues/11444 - quartoYml <- matchingNames(absoluteAppFiles, "^_quarto.y(a)?ml$") + quartoYml <- matchingNames(absoluteRootFiles, "^_quarto.y(a)?ml$") usesQuarto <- length(qmdFiles) > 0 || (length(quartoYml) > 0 && length(rmdFiles > 0)) @@ -167,7 +167,7 @@ inferAppMode <- function(absoluteAppFiles, # Shiny application using server.R; checked later than Rmd with shiny runtime # because server.R may contain the server code paired with a ShinyRmd and needs # to be run by rmarkdown::run (rmd-shiny). - serverR <- matchingNames(absoluteAppFiles, "^server.r$") + serverR <- matchingNames(absoluteRootFiles, "^server.r$") if (length(serverR) > 0) { return("shiny") } diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index e8d4a92a..579386bd 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -51,6 +51,10 @@ local_temp_app <- function(files = list(), env = caller_env()) { for (name in names(files)) { content <- files[[name]] + hier <- dirname(name) + if (!hier == ".") { + dir.create(file.path(dir, hier), recursive = TRUE) + } writeLines(content, file.path(dir, name)) } diff --git a/tests/testthat/test-appMetadata.R b/tests/testthat/test-appMetadata.R index c5e44337..dbb04a1e 100644 --- a/tests/testthat/test-appMetadata.R +++ b/tests/testthat/test-appMetadata.R @@ -33,6 +33,13 @@ test_that("handles special case of appPrimaryDoc as R file", { expect_equal(metadata$appMode, "shiny") }) +# https://github.com/rstudio/rsconnect/issues/942 +test_that("files beneath the root are not ignored when determining app-mode", { + dir <- local_temp_app(list("app.R" = "", "plumber/api/plumber.R" = "")) + metadata <- appMetadata(dir) + expect_equal(metadata$appMode, "shiny") +}) + # checkLayout ------------------------------------------------------------- test_that("checkLayout() errors if primary doc & app.R", {