shiny-vscode icon indicating copy to clipboard operation
shiny-vscode copied to clipboard

Root directory and relative path issue at runtime

Open pieterjanvc opened this issue 10 months ago • 3 comments

Hello,

I have been using the Shiny extension in Positron (and VS code) and ran into an issue regarding the root directory at runtime. As outlined in the Shiny documentation, once the app is run, the root should be the directory where the app file is located. Let's now consider the following setup where a Shiny app is part of a larger repo and in a subfolder.

repoRoot/ -- .git/ -- analysis.R (not used in shiny app) -- file2.txt (not used in shiny app) -- ShinyApp/ ---- dashboard.R ---- data.csv

The dashboard.R file contains Shiny code that will read in the data.csv file at runtime. In the code this looks like this

library(shiny)

myData <- read.csv("data.csv")

ui <- fluidPage(
 tableOutput("tbl")
)

server <- function(input, output){
 output$tbl <- renderTable({
  myData
 })
}

When I run this code in RStudio, it correctly sets the root of the app to the ShinyApp folder and thus read.csv("data.csv") has a correct relative path and the app will run without errors.

However, if I run the same app in Positron / VS code with the extension, the following error occurs

Error:
! 'myData.csv' does not exist in current working directory ('pathToRepo/repoRoot')

It seems that the extension fails to change the root during execution.

Thanks for looking into this! PJ

pieterjanvc avatar Jan 24 '25 17:01 pieterjanvc

Hello,

It seems the reason this was not working is because the dashboard.R file is not recognised by the extension because it needs to be named app.R or dashboard_app.R. This a rather annoying limitation which is not present in RStudio, but I guess there is a reason for that :)

pieterjanvc avatar Jan 24 '25 17:01 pieterjanvc

In RStudio, dashboard.R works, but only if you have shinyApp() as the last function call in the file, which is relatively common. (The heuristics are here in C++.)

Both RStudio and the VS Code extension work by looking at the file name and the contents in the file and guessing whether or not it's a Shiny app file.

One option would be to re-use RStudio's "last function call is shinyApp()" heuristic, but it's complicated and likely wouldn't be as performant in JavaScript.

Instead, I'd be open to calling any R file that has the exact string shinyApp anywhere in the source a Shiny app. That'd be very fast to check and the false-positives are likely to be quite low (and the impact of missing a true negative is quite low).

gadenbuie avatar Jan 28 '25 14:01 gadenbuie

Hello,

Thanks for the reply. You are correct that I should have added the shinyApp(ui, server) to the end of the file (I forgot to add this in the reprex but I always have it in my regular apps). It would be great if you could indeed set this as a check for the VS/Positron extension as well in which case it might be possible to get rid of the app.R or <name>_app.R requirement.

Keep me posted! Thanks PJ

pieterjanvc avatar Jan 30 '25 12:01 pieterjanvc

After thinking about this a bit more, I think it's likely that assuming any file that contains shinyApp will lead to problems. In particular, shinyApp is very likely to appear inside R package code if the package includes functions that create Shiny apps, and we certainly wouldn't want to run those files as Shiny apps.

I've personally both found the file name expectations limiting but easy enough to work around that I don't think we should change our heuristics at this time.

gadenbuie avatar Aug 06 '25 13:08 gadenbuie