sbom_shiny() describes a Shiny app folder: the app is the root
component, an application, the R packages it needs come from the strongest
source in the folder, and the JavaScript and CSS libraries the app ships
are recorded under it. It runs no code from the app unless you ask for
evaluate_ui = TRUE, and it makes no network requests, except that, with
Nix installed, a default.nix is read by running nix-instantiate (see
sbom_nix()), which may download nixpkgs, and that snapshot and
advisories = TRUE, passed through ..., look up a CRAN snapshot and
download OSV's advisory data.
Arguments
- path
A Shiny app folder.
- evaluate_ui
Whether to run the app's code to find the html dependencies (JavaScript and CSS) its UI holds.
FALSEby default.evaluate_ui = TRUEruns the app's code in a separate R process, which is stopped after 60 seconds. It works forapp.Randui.Rapps. For anapp.Rapp the whole ofapp.Rruns, not only its UI code; for aui.Rapp,ui.Rruns.global.Rand the app'sR/folder are not sourced, so an app that relies on them fails, with the issue below. The process starts R with--vanillaand inherits this session's environment variables, except thatR_LIBSis set to the library given bylib, or else.libPaths(); R also adds the user and site libraries after it. It needs the htmltools package in those libraries. What it finds are observed components, nested under the R package that ships each one. A dependency whose name, version or package sbom does not accept is left out, and one issue counts them. If the UI cannot be evaluated, an issue says so and the SBOM keeps the static result.It finds only the dependencies the UI holds when it is built, and misses any that
renderUI()or other server code inserts later.- ...
The named arguments of
sbom().
Value
An <sbom> object. See sbom_components() to read it.
Details
The layouts it recognizes, checked in this order:
rhino: the folder hasrhino.yml. Its static files are inapp/static.golem: aDESCRIPTIONwith aPackagefield, and eitherinst/golem-config.ymlor bothR/app_ui.RandR/app_server.R. The root is the app, named and versioned by itsDESCRIPTION, which also gives its license and maintainer whatever source the packages come from. Its static files are ininst/app/www.app.R: the folder has anapp.R. Its static files are inwww.ui-server: the folder has bothui.Randserver.R. Its static files are inwww.
The R packages come from the strongest source, as for sbom(): renv.lock,
then a Posit Connect manifest.json, then default.nix, then a package
DESCRIPTION (a golem app's declared Imports are stronger than a code
scan), then a scan of the code. Every other source present cross-checks
it. When the folder holds a Posit Connect manifest, a note says the app
was deployed there.
The libraries in the static folder are found by the header comments of
their files, as for the JavaScript in a package, with the same bounds: six
levels, no symlinked folders, a fixed number of files. They are inferred
components under the root. A rhino app's npm dependencies are not read,
and an issue says so when the app has a package.json or
package-lock.json.
Examples
app <- file.path(tempdir(), "app")
dir.create(app)
writeLines("shiny::shinyApp(shiny::fluidPage(), function(input, output) {})",
file.path(app, "app.R"))
sbom_shiny(app, system = FALSE, lib = character())
#> <sbom> app
#> Components: 3
#> Relationships: 1
#> Issues: 3 (see sbom_issues())
#> Advisories: not requested.