diff --git a/internal/bundles/manifest.go b/internal/bundles/manifest.go index 9b25650c0..8e6cecb35 100644 --- a/internal/bundles/manifest.go +++ b/internal/bundles/manifest.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "sort" + "strings" "github.com/posit-dev/publisher/internal/clients/connect" "github.com/posit-dev/publisher/internal/config" @@ -202,6 +203,14 @@ func (manifest *Manifest) AddFile(path string, fileMD5 []byte) { manifest.Files[path] = ManifestFile{ Checksum: hex.EncodeToString(fileMD5), } + + // Update manifest content category if a file being added is a site configuration + for _, ymlFile := range util.KnownSiteYmlConfigFiles { + if strings.ToLower(path) == ymlFile { + manifest.Metadata.ContentCategory = "site" + break + } + } } func (manifest *Manifest) ToJSON() ([]byte, error) { diff --git a/internal/bundles/manifest_test.go b/internal/bundles/manifest_test.go index 4af1b543d..57a5d66f7 100644 --- a/internal/bundles/manifest_test.go +++ b/internal/bundles/manifest_test.go @@ -54,6 +54,25 @@ func (s *ManifestSuite) TestAddFile() { "subdir/test.Rmd": ManifestFile{Checksum: "030405"}, }) } + +func (s *ManifestSuite) TestAddFile_UpdatesSiteCategory() { + for _, siteConfigYml := range util.KnownSiteYmlConfigFiles { + manifest := NewManifest() + manifest.AddFile("test.Rmd", []byte{0x00, 0x01, 0x02}) + s.Equal(manifest.Files, ManifestFileMap{ + "test.Rmd": ManifestFile{Checksum: "000102"}, + }) + s.Equal(manifest.Metadata.ContentCategory, "") + + manifest.AddFile(siteConfigYml, []byte{0x03, 0x04, 0x05}) + s.Equal(manifest.Files, ManifestFileMap{ + "test.Rmd": ManifestFile{Checksum: "000102"}, + siteConfigYml: ManifestFile{Checksum: "030405"}, + }) + s.Equal(manifest.Metadata.ContentCategory, "site") + } +} + func (s *ManifestSuite) TestReadManifest() { manifestJson := `{"version": 1, "platform": "4.1.0"}` reader := strings.NewReader(manifestJson) diff --git a/internal/bundles/matcher/walker.go b/internal/bundles/matcher/walker.go index bbdb7bbf1..23538f3e1 100644 --- a/internal/bundles/matcher/walker.go +++ b/internal/bundles/matcher/walker.go @@ -26,6 +26,9 @@ var StandardExclusions = []string{ "!.DS_Store", "!.Rhistory", "!.quarto/", + "!packrat/", + "!*.Rproj", + "!.rscignore", // Less precise than rsconnect, which checks for a // matching Rmd filename in the same directory. "!*_cache/", diff --git a/internal/inspect/detectors/rmarkdown.go b/internal/inspect/detectors/rmarkdown.go index 31e754652..3b2578204 100644 --- a/internal/inspect/detectors/rmarkdown.go +++ b/internal/inspect/detectors/rmarkdown.go @@ -3,7 +3,9 @@ package detectors // Copyright (C) 2023 by Posit Software, PBC. import ( + "fmt" "regexp" + "slices" "strings" "github.com/posit-dev/publisher/internal/config" @@ -80,7 +82,123 @@ func isShinyRmd(metadata *RMarkdownMetadata) bool { return false } +func (d *RMarkdownDetector) isSite(base util.AbsolutePath) (bool, string) { + for _, ymlFile := range util.KnownSiteYmlConfigFiles { + exists, err := base.Join(ymlFile).Exists() + if err == nil && exists { + d.log.Debug("Site configuration file is present, project being considered as static site", "file", ymlFile) + return true, ymlFile + } + } + return false, "" +} + +func (d *RMarkdownDetector) lookForSiteMetadata(base util.AbsolutePath) (*RMarkdownMetadata, string) { + // Attempt to get site metadata looking up in common files + possibleIndexFiles := []string{"index.Rmd", "index.rmd", "app.Rmd", "app.rmd"} + for _, file := range possibleIndexFiles { + fileAbsPath := base.Join(file) + exists, err := fileAbsPath.Exists() + if err != nil || !exists { + continue + } + metadata, err := d.getRmdFileMetadata(fileAbsPath) + if err != nil { + continue + } + if metadata != nil { + return metadata, file + } + } + return nil, "" +} + +func (d *RMarkdownDetector) configFromFileInspect(base util.AbsolutePath, entrypointPath util.AbsolutePath) (*config.Config, error) { + relEntrypoint, err := entrypointPath.Rel(base) + if err != nil { + return nil, err + } + + metadata, err := d.getRmdFileMetadata(entrypointPath) + if err != nil { + d.log.Warn("Failed to read RMarkdown metadata", "path", entrypointPath, "error", err) + return nil, err + } + + cfg := config.New() + cfg.Entrypoint = relEntrypoint.String() + + if isShinyRmd(metadata) { + cfg.Type = config.ContentTypeRMarkdownShiny + } else { + cfg.Type = config.ContentTypeRMarkdown + } + + if isSite, siteConfigFile := d.isSite(base); isSite { + var siteMetadata *RMarkdownMetadata + var indexFile string + cfg.Files = []string{fmt.Sprint("/", siteConfigFile)} + + if metadata == nil { + siteMetadata, indexFile = d.lookForSiteMetadata(base) + metadata = siteMetadata + } + + if indexFile != "" { + cfg.Files = append(cfg.Files, fmt.Sprint("/", indexFile)) + } + + entrypointBase := fmt.Sprint("/", entrypointPath.Base()) + if !slices.Contains(cfg.Files, entrypointBase) { + cfg.Files = append(cfg.Files, entrypointBase) + } + } + + if metadata != nil { + title := metadata.Title + if title != "" { + cfg.Title = title + } + + if metadata.Params != nil { + cfg.HasParameters = true + } + } + needsR, needsPython, err := pydeps.DetectMarkdownLanguages(base) + if err != nil { + return nil, err + } + if needsR { + // Indicate that R inspection is needed. + d.log.Info("RMarkdown: detected R code; configuration will include R") + cfg.R = &config.R{} + } + if needsPython { + // Indicate that Python inspection is needed. + d.log.Info("RMarkdown: detected Python code; configuration will include Python") + cfg.Python = &config.Python{} + } + return cfg, nil +} + func (d *RMarkdownDetector) InferType(base util.AbsolutePath, entrypoint util.RelativePath) ([]*config.Config, error) { + entrypointIsSiteConfig := slices.Contains(util.KnownSiteYmlConfigFiles, strings.ToLower(entrypoint.String())) + + // When the choosen entrypoint is a site configuration yml + // generate a single configuration as a site project. + if entrypointIsSiteConfig { + d.log.Debug("A site configuration file was picked as entrypoint", "entrypoint", entrypoint.String()) + + cfg, err := d.configFromFileInspect(base, base.Join(entrypoint.String())) + if err != nil { + return nil, err + } + + if cfg != nil { + return []*config.Config{cfg}, nil + } + } + if entrypoint.String() != "" { // Optimization: skip inspection if there's a specified entrypoint // and it's not one of ours. @@ -88,6 +206,7 @@ func (d *RMarkdownDetector) InferType(base util.AbsolutePath, entrypoint util.Re return nil, nil } } + var configs []*config.Config entrypointPaths, err := base.Glob("*.Rmd") if err != nil { @@ -102,44 +221,10 @@ func (d *RMarkdownDetector) InferType(base util.AbsolutePath, entrypoint util.Re // Only inspect the specified file continue } - metadata, err := d.getRmdFileMetadata(entrypointPath) - if err != nil { - d.log.Warn("Failed to read RMarkdown metadata", "path", entrypointPath, "error", err) - continue - } - cfg := config.New() - cfg.Entrypoint = relEntrypoint.String() - - if isShinyRmd(metadata) { - cfg.Type = config.ContentTypeRMarkdownShiny - } else { - cfg.Type = config.ContentTypeRMarkdown - } - - if metadata != nil { - title := metadata.Title - if title != "" { - cfg.Title = title - } - - if metadata.Params != nil { - cfg.HasParameters = true - } - } - needsR, needsPython, err := pydeps.DetectMarkdownLanguages(base) + cfg, err := d.configFromFileInspect(base, entrypointPath) if err != nil { return nil, err } - if needsR { - // Indicate that R inspection is needed. - d.log.Info("RMarkdown: detected R code; configuration will include R") - cfg.R = &config.R{} - } - if needsPython { - // Indicate that Python inspection is needed. - d.log.Info("RMarkdown: detected Python code; configuration will include Python") - cfg.Python = &config.Python{} - } configs = append(configs, cfg) } return configs, nil diff --git a/internal/inspect/detectors/rmarkdown_test.go b/internal/inspect/detectors/rmarkdown_test.go index 80cac4eb2..fa654ef60 100644 --- a/internal/inspect/detectors/rmarkdown_test.go +++ b/internal/inspect/detectors/rmarkdown_test.go @@ -4,9 +4,11 @@ package detectors import ( "fmt" + "runtime" "testing" "github.com/posit-dev/publisher/internal/config" + "github.com/posit-dev/publisher/internal/executor/executortest" "github.com/posit-dev/publisher/internal/logging" "github.com/posit-dev/publisher/internal/schema" "github.com/posit-dev/publisher/internal/util" @@ -325,3 +327,162 @@ func (s *RMarkdownSuite) TestInferTypeWithEntrypoint() { R: &config.R{}, }, configs[0]) } + +func (s *RMarkdownSuite) TestInferTypeRmdSite() { + if runtime.GOOS == "windows" { + s.T().Skip("This test does not run on Windows") + } + + realCwd, err := util.Getwd(nil) + s.NoError(err) + + base := realCwd.Join("testdata", "rmd-site") + + detector := NewRMarkdownDetector(logging.New()) + executor := executortest.NewMockExecutor() + detector.executor = executor + + configs, err := detector.InferType(base, util.NewRelativePath("index.Rmd", nil)) + s.Nil(err) + + s.Len(configs, 1) + s.Equal(&config.Config{ + Schema: schema.ConfigSchemaURL, + Type: config.ContentTypeRMarkdown, + Entrypoint: "index.Rmd", + Title: "Testing RMD Site", + Validate: true, + Files: []string{ + "/_site.yml", + "/index.Rmd", + }, + R: &config.R{}, + }, configs[0]) +} + +func (s *RMarkdownSuite) TestInferTypeRmdSite_FromSiteYml() { + if runtime.GOOS == "windows" { + s.T().Skip("This test does not run on Windows") + } + + realCwd, err := util.Getwd(nil) + s.NoError(err) + + base := realCwd.Join("testdata", "rmd-site") + + detector := NewRMarkdownDetector(logging.New()) + executor := executortest.NewMockExecutor() + detector.executor = executor + + configs, err := detector.InferType(base, util.NewRelativePath("_site.yml", nil)) + s.Nil(err) + + s.Len(configs, 1) + s.Equal(&config.Config{ + Schema: schema.ConfigSchemaURL, + Type: config.ContentTypeRMarkdown, + Entrypoint: "_site.yml", + Title: "Testing RMD Site", + Validate: true, + Files: []string{ + "/_site.yml", + "/index.Rmd", + }, + R: &config.R{}, + }, configs[0]) +} + +func (s *RMarkdownSuite) TestInferTypeRmdSite_FromSiteYml_NoMeta() { + if runtime.GOOS == "windows" { + s.T().Skip("This test does not run on Windows") + } + + realCwd, err := util.Getwd(nil) + s.NoError(err) + + base := realCwd.Join("testdata", "rmd-site-no-meta") + + detector := NewRMarkdownDetector(logging.New()) + executor := executortest.NewMockExecutor() + detector.executor = executor + + configs, err := detector.InferType(base, util.NewRelativePath("_site.yml", nil)) + s.Nil(err) + + s.Len(configs, 1) + s.Equal(&config.Config{ + Schema: schema.ConfigSchemaURL, + Type: config.ContentTypeRMarkdown, + Entrypoint: "_site.yml", + Title: "", + Validate: true, + Files: []string{ + "/_site.yml", + }, + R: &config.R{}, + }, configs[0]) +} + +func (s *RMarkdownSuite) TestInferTypeRmdSite_Bookdown() { + if runtime.GOOS == "windows" { + s.T().Skip("This test does not run on Windows") + } + + realCwd, err := util.Getwd(nil) + s.NoError(err) + + base := realCwd.Join("testdata", "bookdown-proj") + + detector := NewRMarkdownDetector(logging.New()) + executor := executortest.NewMockExecutor() + detector.executor = executor + + configs, err := detector.InferType(base, util.NewRelativePath("index.Rmd", nil)) + s.Nil(err) + + s.Len(configs, 1) + s.Equal(&config.Config{ + Schema: schema.ConfigSchemaURL, + Type: config.ContentTypeRMarkdown, + Entrypoint: "index.Rmd", + Title: "A Minimal Book Example", + Validate: true, + Files: []string{ + "/_bookdown.yml", + "/index.Rmd", + }, + R: &config.R{}, + }, configs[0]) +} + +func (s *RMarkdownSuite) TestInferTypeRmdSite_FromBookdownYml() { + if runtime.GOOS == "windows" { + s.T().Skip("This test does not run on Windows") + } + + realCwd, err := util.Getwd(nil) + s.NoError(err) + + base := realCwd.Join("testdata", "bookdown-proj") + + detector := NewRMarkdownDetector(logging.New()) + executor := executortest.NewMockExecutor() + detector.executor = executor + + configs, err := detector.InferType(base, util.NewRelativePath("_bookdown.yml", nil)) + s.Nil(err) + + s.Len(configs, 1) + s.Equal(&config.Config{ + Schema: schema.ConfigSchemaURL, + Type: config.ContentTypeRMarkdown, + Entrypoint: "_bookdown.yml", + Title: "A Minimal Book Example", + Validate: true, + Files: []string{ + "/_bookdown.yml", + "/index.Rmd", + }, + R: &config.R{}, + }, configs[0]) +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/01-intro.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/01-intro.Rmd new file mode 100644 index 000000000..6b16e7375 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/01-intro.Rmd @@ -0,0 +1,21 @@ +# Introduction {#intro} + +You can label chapter and section titles using `{#label}` after them, e.g., we can reference Chapter \@ref(intro). If you do not manually label them, there will be automatic labels anyway, e.g., Chapter \@ref(methods). + +Figures and tables with captions will be placed in `figure` and `table` environments, respectively. + +```{r nice-fig, fig.cap='Here is a nice figure!', out.width='80%', fig.asp=.75, fig.align='center'} +par(mar = c(4, 4, .1, .1)) +plot(pressure, type = 'b', pch = 19) +``` + +Reference a figure by its code chunk label with the `fig:` prefix, e.g., see Figure \@ref(fig:nice-fig). Similarly, you can reference tables generated from `knitr::kable()`, e.g., see Table \@ref(tab:nice-tab). + +```{r nice-tab, tidy=FALSE} +knitr::kable( + head(iris, 20), caption = 'Here is a nice table!', + booktabs = TRUE +) +``` + +You can write citations, too. For example, we are using the **bookdown** package [@R-bookdown] in this sample book, which was built on top of R Markdown and **knitr** [@xie2015]. diff --git a/internal/inspect/detectors/testdata/bookdown-proj/02-literature.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/02-literature.Rmd new file mode 100644 index 000000000..00745d079 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/02-literature.Rmd @@ -0,0 +1,3 @@ +# Literature + +Here is a review of existing methods. diff --git a/internal/inspect/detectors/testdata/bookdown-proj/03-method.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/03-method.Rmd new file mode 100644 index 000000000..dcb431cb0 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/03-method.Rmd @@ -0,0 +1,23 @@ +# Methods + +We describe our methods in this chapter. + +Math can be added in body using usual syntax like this + +## math example + +$p$ is unknown but expected to be around 1/3. Standard error will be approximated + +$$ +SE = \sqrt{\frac{p(1-p)}{n}} \approx \sqrt{\frac{1/3 (1 - 1/3)} {300}} = 0.027 +$$ + +You can also use math in footnotes like this^[where we mention $p = \frac{a}{b}$]. + +We will approximate standard error to 0.027[^longnote] + +[^longnote]: $p$ is unknown but expected to be around 1/3. Standard error will be approximated + + $$ + SE = \sqrt{\frac{p(1-p)}{n}} \approx \sqrt{\frac{1/3 (1 - 1/3)} {300}} = 0.027 + $$ diff --git a/internal/inspect/detectors/testdata/bookdown-proj/04-application.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/04-application.Rmd new file mode 100644 index 000000000..d5b076e10 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/04-application.Rmd @@ -0,0 +1,7 @@ +# Applications + +Some _significant_ applications are demonstrated in this chapter. + +## Example one + +## Example two diff --git a/internal/inspect/detectors/testdata/bookdown-proj/05-summary.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/05-summary.Rmd new file mode 100644 index 000000000..c1ac36fbb --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/05-summary.Rmd @@ -0,0 +1,3 @@ +# Final Words + +We have finished a nice book. diff --git a/internal/inspect/detectors/testdata/bookdown-proj/06-references.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/06-references.Rmd new file mode 100644 index 000000000..4e5a594ed --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/06-references.Rmd @@ -0,0 +1,3 @@ +`r if (knitr:::is_html_output()) ' +# References {-} +'` diff --git a/internal/inspect/detectors/testdata/bookdown-proj/DESCRIPTION b/internal/inspect/detectors/testdata/bookdown-proj/DESCRIPTION new file mode 100644 index 000000000..5c3a64d20 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/DESCRIPTION @@ -0,0 +1,6 @@ +Package: placeholder +Type: Book +Title: Does not matter. +Version: 0.0.1 +Imports: bookdown +Remotes: rstudio/bookdown diff --git a/internal/inspect/detectors/testdata/bookdown-proj/LICENSE b/internal/inspect/detectors/testdata/bookdown-proj/LICENSE new file mode 100644 index 000000000..2c4afabdb --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/LICENSE @@ -0,0 +1,117 @@ +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + + diff --git a/internal/inspect/detectors/testdata/bookdown-proj/README.md b/internal/inspect/detectors/testdata/bookdown-proj/README.md new file mode 100644 index 000000000..4408a4a45 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/README.md @@ -0,0 +1,5 @@ +[![Build Status](https://travis-ci.com/rstudio/bookdown-demo.svg?branch=master)](https://travis-ci.com/rstudio/bookdown-demo) + +This is a minimal example of a book based on R Markdown and **bookdown** (https://github.com/rstudio/bookdown). Please see the page "[Get Started](https://bookdown.org/yihui/bookdown/get-started.html)" at https://bookdown.org/yihui/bookdown/ for how to compile this example into HTML. You may generate a copy of the book in `bookdown::pdf_book` format by calling `bookdown::render_book('index.Rmd', 'bookdown::pdf_book')`. More detailed instructions are available here https://bookdown.org/yihui/bookdown/build-the-book.html. + +You can find the preview of this example at https://bookdown.org/yihui/bookdown-demo/. diff --git a/internal/inspect/detectors/testdata/bookdown-proj/_bookdown.yml b/internal/inspect/detectors/testdata/bookdown-proj/_bookdown.yml new file mode 100644 index 000000000..6586f1a2b --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/_bookdown.yml @@ -0,0 +1,5 @@ +book_filename: "bookdown-demo" +language: + ui: + chapter_name: "Chapter " +delete_merged_file: true diff --git a/internal/inspect/detectors/testdata/bookdown-proj/_build.sh b/internal/inspect/detectors/testdata/bookdown-proj/_build.sh new file mode 100644 index 000000000..349b1f904 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/_build.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -ev + +Rscript -e "bookdown::render_book('index.Rmd', 'bookdown::gitbook')" +Rscript -e "bookdown::render_book('index.Rmd', 'bookdown::pdf_book')" +Rscript -e "bookdown::render_book('index.Rmd', 'bookdown::epub_book')" + diff --git a/internal/inspect/detectors/testdata/bookdown-proj/_deploy.sh b/internal/inspect/detectors/testdata/bookdown-proj/_deploy.sh new file mode 100755 index 000000000..ee544e05c --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/_deploy.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +[ -z "${GITHUB_PAT}" ] && exit 0 +[ "${TRAVIS_BRANCH}" != "master" ] && exit 0 + +git config --global user.email "xie@yihui.name" +git config --global user.name "Yihui Xie" + +git clone -b gh-pages https://${GITHUB_PAT}@github.com/${TRAVIS_REPO_SLUG}.git book-output +cd book-output +cp -r ../_book/* ./ +git add --all * +git commit -m"Update the book" || true +git push -q origin gh-pages diff --git a/internal/inspect/detectors/testdata/bookdown-proj/_output.yml b/internal/inspect/detectors/testdata/bookdown-proj/_output.yml new file mode 100644 index 000000000..90f6b2051 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/_output.yml @@ -0,0 +1,18 @@ +bookdown::gitbook: + css: style.css + config: + toc: + before: | +
  • A Minimal Book Example
  • + after: | +
  • Published with bookdown
  • + edit: https://github.com/rstudio/bookdown-demo/edit/master/%s + download: ["pdf", "epub"] +bookdown::pdf_book: + includes: + in_header: preamble.tex + latex_engine: xelatex + citation_package: natbib + keep_tex: yes +bookdown::epub_book: default +bookdown::bs4_book: default diff --git a/internal/inspect/detectors/testdata/bookdown-proj/_publish.R b/internal/inspect/detectors/testdata/bookdown-proj/_publish.R new file mode 100644 index 000000000..0bd933f07 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/_publish.R @@ -0,0 +1,41 @@ +# publish the book with different HTML styles; you should not need this script + +unlink('_book', recursive = TRUE) + +x = readLines('index.Rmd') +i = 1 +s = paste0('title: "A Minimal Book Example (', c('Bootstrap', 'Tufte'), ' Style)"') +for (fmt in c('html_book', 'tufte_html_book')) { + unlink('_book', recursive = TRUE) + file.copy('index.Rmd', '_index.Rmd') + file.copy('_output.yml', '_output.yml2') + writeLines( + gsub('^title: ".*"', s[i], gsub('gitbook', fmt, x)), 'index.Rmd' + ) + cat( + 'bookdown::', fmt, ':\n', ' css: [style.css, toc.css]\n', sep = '', file = '_output.yml', + append = TRUE + ) + cmd = sprintf("bookdown::render_book('index.Rmd', 'bookdown::%s', quiet = TRUE)", fmt) + res = xfun::Rscript(c('-e', shQuote(cmd))) + file.rename('_index.Rmd', 'index.Rmd') + file.rename('_output.yml2', '_output.yml') + if (res != 0) stop('Failed to compile the book to ', fmt) + i = i + 1 + bookdown::publish_book(paste0('bookdown-demo', i)) +} +unlink('_book', recursive = TRUE) + +# default formats +formats = c( + 'bookdown::pdf_book', 'bookdown::epub_book', 'bookdown::gitbook' +) + +# render the book to all formats unless they are specified via command-line args +for (fmt in formats) { + cmd = sprintf("bookdown::render_book('index.Rmd', '%s', quiet = TRUE)", fmt) + res = xfun::Rscript(c('-e', shQuote(cmd))) + if (res != 0) stop('Failed to compile the book to ', fmt) +} + +bookdown::publish_book('bookdown-demo') diff --git a/internal/inspect/detectors/testdata/bookdown-proj/book.bib b/internal/inspect/detectors/testdata/bookdown-proj/book.bib new file mode 100644 index 000000000..f52f3d22a --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/book.bib @@ -0,0 +1,10 @@ +@Book{xie2015, + title = {Dynamic Documents with {R} and knitr}, + author = {Yihui Xie}, + publisher = {Chapman and Hall/CRC}, + address = {Boca Raton, Florida}, + year = {2015}, + edition = {2nd}, + note = {ISBN 978-1498716963}, + url = {http://yihui.name/knitr/}, +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/bookdown-demo.Rproj b/internal/inspect/detectors/testdata/bookdown-proj/bookdown-demo.Rproj new file mode 100644 index 000000000..e4c1c67d2 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/bookdown-demo.Rproj @@ -0,0 +1,18 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: knitr +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes + +BuildType: Website diff --git a/internal/inspect/detectors/testdata/bookdown-proj/index.Rmd b/internal/inspect/detectors/testdata/bookdown-proj/index.Rmd new file mode 100644 index 000000000..596547f25 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/index.Rmd @@ -0,0 +1,36 @@ +--- +title: "A Minimal Book Example" +author: "Yihui Xie" +date: "`r Sys.Date()`" +site: bookdown::bookdown_site +output: bookdown::gitbook +documentclass: book +bibliography: [book.bib, packages.bib] +biblio-style: apalike +link-citations: yes +github-repo: rstudio/bookdown-demo +description: "This is a minimal example of using the bookdown package to write a book. The output format for this example is bookdown::gitbook." +--- + +# Prerequisites + +This is a _sample_ book written in **Markdown**. You can use anything that Pandoc's Markdown supports, e.g., a math equation $a^2 + b^2 = c^2$. + +The **bookdown** package can be installed from CRAN or Github: + +```{r eval=FALSE} +install.packages("bookdown") +# or the development version +# devtools::install_github("rstudio/bookdown") +``` + +Remember each Rmd file contains one and only one chapter, and a chapter is defined by the first-level heading `#`. + +To compile this example to PDF, you need XeLaTeX. You are recommended to install TinyTeX (which includes XeLaTeX): . + +```{r include=FALSE} +# automatically create a bib database for R packages +knitr::write_bib(c( + .packages(), 'bookdown', 'knitr', 'rmarkdown' +), 'packages.bib') +``` diff --git a/internal/inspect/detectors/testdata/bookdown-proj/now.json b/internal/inspect/detectors/testdata/bookdown-proj/now.json new file mode 100644 index 000000000..572b9a8ea --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/now.json @@ -0,0 +1,4 @@ +{ + "type": "static", + "public": true +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/preamble.tex b/internal/inspect/detectors/testdata/bookdown-proj/preamble.tex new file mode 100644 index 000000000..8a88e02a2 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/preamble.tex @@ -0,0 +1,8 @@ +\usepackage{booktabs} +\usepackage{amsthm} +\makeatletter +\def\thm@space@setup{% + \thm@preskip=8pt plus 2pt minus 4pt + \thm@postskip=\thm@preskip +} +\makeatother diff --git a/internal/inspect/detectors/testdata/bookdown-proj/renv.lock b/internal/inspect/detectors/testdata/bookdown-proj/renv.lock new file mode 100644 index 000000000..411e9745b --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/renv.lock @@ -0,0 +1,422 @@ +{ + "R": { + "Version": "4.3.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bookdown": { + "Package": "bookdown", + "Version": "0.41.1", + "Source": "GitHub", + "RemoteType": "github", + "RemoteHost": "api.github.com", + "RemoteUsername": "rstudio", + "RemoteRepo": "bookdown", + "RemoteRef": "main", + "RemoteSha": "bd78cf85f05f1fdadd7818206f0105c0ea792160", + "Requirements": [ + "R", + "htmltools", + "jquerylib", + "knitr", + "rmarkdown", + "tinytex", + "xfun", + "yaml" + ], + "Hash": "f81d4eef60a474c3cdd50ba657b39a82" + }, + "bslib": { + "Package": "bslib", + "Version": "0.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "1b117970533deb6d4e992c1b34e9d905" + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "c35768291560ce302c0a6589f92e837d" + }, + "cli": { + "Package": "cli", + "Version": "3.6.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "89e6d8219950eac806ae0c489052048a" + }, + "digest": { + "Package": "digest", + "Version": "0.6.31", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "8b708f296afd9ae69f450f9640be8990" + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "rlang" + ], + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.21", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "d59f3b464e8da1aef82dc04b588b8dfb" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f7736a18de97dea803bde0a2daaafb27" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "1e22b8cabbad1eae951a75e9f8b52378" + }, + "fs": { + "Package": "fs", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "94af08e0aa9675a16fadbb3aaaa90d2a" + }, + "glue": { + "Package": "glue", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e" + }, + "highr": { + "Package": "highr", + "Version": "0.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "d65ba49117ca223614f71b60d85b8ab7" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "ellipsis", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "2d7b3857980e0e0d0a1fd6f11928ab0f" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "3ee4d9899e4db3e976fc82b98d24a31a" + }, + "knitr": { + "Package": "knitr", + "Version": "1.48", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "acf380f300c721da9fde7df115a5f86f" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "001cecbeac1cff9301bdc3775ee46a86" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "7ce2733a9826b3aeb1775d56fd305472" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "renv": { + "Package": "renv", + "Version": "1.0.7", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "397b7b2a265bc5a7a06852524dabae20" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.22", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "stringr", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "75a01be060d800ceb14e32c666cacac9" + }, + "sass": { + "Package": "sass", + "Version": "0.4.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "cc3ec7dd33982ef56570229b62d6388e" + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stats", + "tools", + "utils" + ], + "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ], + "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.45", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "e4e357f28c2edff493936b6cb30c3d65" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "d0ef2856b83dc33ea6e255caf6229ee2" + }, + "xfun": { + "Package": "xfun", + "Version": "0.49", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "stats", + "tools" + ], + "Hash": "8687398773806cfff9401a2feca96298" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0d0056cc5383fbc240ccd0cb584bf436" + } + } +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/renv/.gitignore b/internal/inspect/detectors/testdata/bookdown-proj/renv/.gitignore new file mode 100644 index 000000000..0ec0cbba2 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ diff --git a/internal/inspect/detectors/testdata/bookdown-proj/renv/activate.R b/internal/inspect/detectors/testdata/bookdown-proj/renv/activate.R new file mode 100644 index 000000000..d13f9932a --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/renv/activate.R @@ -0,0 +1,1220 @@ + +local({ + + # the requested version of renv + version <- "1.0.7" + attr(version, "sha") <- NULL + + # the project directory + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() + + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + + # figure out whether the autoloader is enabled + enabled <- local({ + + # first, check config option + override <- getOption("renv.config.autoloader.enabled") + if (!is.null(override)) + return(override) + + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + + # next, check environment variables + # TODO: prefer using the configuration one in the future + envvars <- c( + "RENV_CONFIG_AUTOLOADER_ENABLED", + "RENV_AUTOLOADER_ENABLED", + "RENV_ACTIVATE_PROJECT" + ) + + for (envvar in envvars) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(tolower(envval) %in% c("true", "t", "1")) + } + + # enable by default + TRUE + + }) + + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + + return(FALSE) + + } + + # avoid recursion + if (identical(getOption("renv.autoloader.running"), TRUE)) { + warning("ignoring recursive attempt to run renv autoloader") + return(invisible(TRUE)) + } + + # signal that we're loading renv during R startup + options(renv.autoloader.running = TRUE) + on.exit(options(renv.autoloader.running = NULL), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # unload renv if it's already been loaded + if ("renv" %in% loadedNamespaces()) + unloadNamespace("renv") + + # load bootstrap tools + `%||%` <- function(x, y) { + if (is.null(x)) y else x + } + + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + paste(substring(lines, common), collapse = "\n") + + } + + startswith <- function(string, prefix) { + substring(string, 1, nchar(prefix)) == prefix + } + + bootstrap <- function(version, library) { + + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + + # attempt to download renv + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) + + # now attempt to install + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + + return(invisible()) + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # get CRAN repository + cran <- getOption("renv.repos.cran", "https://cloud.r-project.org") + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) { + + # check for RSPM; if set, use a fallback repository for renv + rspm <- Sys.getenv("RSPM", unset = NA) + if (identical(rspm, repos)) + repos <- c(RSPM = rspm, CRAN = cran) + + return(repos) + + } + + # check for lockfile repositories + repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) + if (!inherits(repos, "error") && length(repos)) + return(repos) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- cran + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_repos_lockfile <- function() { + + lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") + if (!file.exists(lockpath)) + return(NULL) + + lockfile <- tryCatch(renv_json_read(lockpath), error = identity) + if (inherits(lockfile, "error")) { + warning(lockfile) + return(NULL) + } + + repos <- lockfile$R$Repositories + if (length(repos) == 0) + return(NULL) + + keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) + vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) + names(vals) <- keys + + return(vals) + + } + + renv_bootstrap_download <- function(version) { + + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) + ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } + + for (method in methods) { + path <- tryCatch(method(), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("All download methods failed") + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + args <- list( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos + + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") + + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (inherits(status, "condition")) + return(FALSE) + + # report success and return + destfile + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # retrieve package database + db <- tryCatch( + as.data.frame( + utils::available.packages(type = type, repos = repos), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) + return(destfile) + + } + + return(FALSE) + + } + + renv_bootstrap_download_tarball <- function(version) { + + # if the user has provided the path to a tarball via + # an environment variable, then use it + tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) + if (is.na(tarball)) + return() + + # allow directories + if (dir.exists(tarball)) { + name <- sprintf("renv_%s.tar.gz", version) + tarball <- file.path(tarball, name) + } + + # bail if it doesn't exist + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail + return() + + } + + catf("- Using local tarball '%s'.", tarball) + tarball + + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + pat <- Sys.getenv("GITHUB_PAT") + if (nzchar(Sys.which("curl")) && nzchar(pat)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) + return(FALSE) + + renv_bootstrap_download_augment(destfile) + + return(destfile) + + } + + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + R <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + system2(R, args, stdout = TRUE, stderr = TRUE) + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version, description = NULL) { + + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") + + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) + else + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + else + paste("renv", description[["Version"]], sep = "@") + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = if (dev) description[["RemoteSha"]] + ) + + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) + + FALSE + + } + + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # execute renv load hooks, if any + hooks <- getHook("renv::autoload") + for (hook in hooks) + if (is.function(hook)) + tryCatch(hook(), error = warnify) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + renv_json_read <- function(file = NULL, text = NULL) { + + jlerr <- NULL + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) { + + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + jlerr <- json + + } + + # otherwise, fall back to the default JSON reader + json <- tryCatch(renv_json_read_default(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + # report an error + if (!is.null(jlerr)) + stop(jlerr) + else + stop(json) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # find strings in the JSON + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + + # if any are found, replace them with placeholders + replaced <- text + strings <- character() + replacements <- character() + + if (!identical(c(locs), -1L)) { + + # get the string values + starts <- locs + ends <- locs + attr(locs, "match.length") - 1L + strings <- substring(text, starts, ends) + + # only keep those requiring escaping + strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + + # compute replacements + replacements <- sprintf('"\032%i\032"', seq_along(strings)) + + # replace the strings + mapply(function(string, replacement) { + replaced <<- sub(string, replacement, replaced, fixed = TRUE) + }, strings, replacements) + + } + + # transform the JSON into something the R parser understands + transformed <- replaced + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) + transformed <- gsub(":", "=", transformed, fixed = TRUE) + text <- paste(transformed, collapse = "\n") + + # parse it + json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + + # construct map between source strings, replaced strings + map <- as.character(parse(text = strings)) + names(map) <- as.character(parse(text = replacements)) + + # convert to list + map <- as.list(map) + + # remap strings in object + remapped <- renv_json_read_remap(json, map) + + # evaluate + eval(remapped, envir = baseenv()) + + } + + renv_json_read_remap <- function(json, map) { + + # fix names + if (!is.null(names(json))) { + lhs <- match(names(json), names(map), nomatch = 0L) + rhs <- match(names(map), names(json), nomatch = 0L) + names(json)[rhs] <- map[lhs] + } + + # fix values + if (is.character(json)) + return(map[[json]] %||% json) + + # handle true, false, null + if (is.name(json)) { + text <- as.character(json) + if (text == "true") + return(TRUE) + else if (text == "false") + return(FALSE) + else if (text == "null") + return(NULL) + } + + # recurse + if (is.recursive(json)) { + for (i in seq_along(json)) { + json[i] <- list(renv_json_read_remap(json[[i]], map)) + } + } + + json + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) + + invisible() + +}) diff --git a/internal/inspect/detectors/testdata/bookdown-proj/renv/settings.json b/internal/inspect/detectors/testdata/bookdown-proj/renv/settings.json new file mode 100644 index 000000000..9c39f83f0 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/renv/settings.json @@ -0,0 +1,15 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [], + "package.dependency.fields": ["Imports", "Depends", "LinkingTo"], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "explicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/style.css b/internal/inspect/detectors/testdata/bookdown-proj/style.css new file mode 100644 index 000000000..f317b4384 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/style.css @@ -0,0 +1,14 @@ +p.caption { + color: #777; + margin-top: 10px; +} +p code { + white-space: inherit; +} +pre { + word-break: normal; + word-wrap: normal; +} +pre code { + white-space: inherit; +} diff --git a/internal/inspect/detectors/testdata/bookdown-proj/toc.css b/internal/inspect/detectors/testdata/bookdown-proj/toc.css new file mode 100644 index 000000000..3e7b40012 --- /dev/null +++ b/internal/inspect/detectors/testdata/bookdown-proj/toc.css @@ -0,0 +1,127 @@ +#TOC ul, +#TOC li, +#TOC span, +#TOC a { + margin: 0; + padding: 0; + position: relative; +} +#TOC { + line-height: 1; + border-radius: 5px 5px 0 0; + background: #141414; + background: linear-gradient(to bottom, #333333 0%, #141414 100%); + border-bottom: 2px solid #0fa1e0; + width: auto; +} +#TOC:after, +#TOC ul:after { + content: ""; + display: block; + clear: both; +} +#TOC a { + background: #141414; + background: linear-gradient(to bottom, #333333 0%, #141414 100%); + color: #ffffff; + display: block; + padding: 19px 20px; + text-decoration: none; + text-shadow: none; +} +#TOC ul { + list-style: none; +} +#TOC > ul > li { + display: inline-block; + float: left; + margin: 0; +} +#TOC > ul > li > a { + color: #ffffff; +} +#TOC > ul > li:hover:after { + content: ""; + display: block; + width: 0; + height: 0; + position: absolute; + left: 50%; + bottom: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 10px solid #0fa1e0; + margin-left: -10px; +} +#TOC > ul > li:first-child > a { + border-radius: 5px 0 0 0; +} +#TOC.align-right > ul > li:first-child > a, +#TOC.align-center > ul > li:first-child > a { + border-radius: 0; +} +#TOC.align-right > ul > li:last-child > a { + border-radius: 0 5px 0 0; +} +#TOC > ul > li.active > a, +#TOC > ul > li:hover > a { + color: #ffffff; + box-shadow: inset 0 0 3px #000000; + background: #070707; + background: linear-gradient(to bottom, #262626 0%, #070707 100%); +} +#TOC .has-sub { + z-index: 1; +} +#TOC .has-sub:hover > ul { + display: block; +} +#TOC .has-sub ul { + display: none; + position: absolute; + width: 200px; + top: 100%; + left: 0; +} +#TOC .has-sub ul li a { + background: #0fa1e0; + border-bottom: 1px dotted #31b7f1; + filter: none; + display: block; + line-height: 120%; + padding: 10px; + color: #ffffff; +} +#TOC .has-sub ul li:hover a { + background: #0c7fb0; +} +#TOC ul ul li:hover > a { + color: #ffffff; +} +#TOC .has-sub .has-sub:hover > ul { + display: block; +} +#TOC .has-sub .has-sub ul { + display: none; + position: absolute; + left: 100%; + top: 0; +} +#TOC .has-sub .has-sub ul li a { + background: #0c7fb0; + border-bottom: 1px dotted #31b7f1; +} +#TOC .has-sub .has-sub ul li a:hover { + background: #0a6d98; +} +#TOC ul ul li.last > a, +#TOC ul ul li:last-child > a, +#TOC ul ul ul li.last > a, +#TOC ul ul ul li:last-child > a, +#TOC .has-sub ul li:last-child > a, +#TOC .has-sub ul li.last > a { + border-bottom: 0; +} +#TOC ul { + font-size: 1.2rem; +} diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/_site.yml b/internal/inspect/detectors/testdata/rmd-site-no-meta/_site.yml new file mode 100644 index 000000000..e69de29bb diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/another.Rmd b/internal/inspect/detectors/testdata/rmd-site-no-meta/another.Rmd new file mode 100644 index 000000000..9dd657a91 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/another.Rmd @@ -0,0 +1,3 @@ +# Another + +Here is another page. It links to [index](index.html) and [article](article.html). diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/article.Rmd b/internal/inspect/detectors/testdata/rmd-site-no-meta/article.Rmd new file mode 100644 index 000000000..138030660 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/article.Rmd @@ -0,0 +1,3 @@ +# Article + +This is an article. It has a link to [index](index.html) and [another](another.html). diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/index.Rmd b/internal/inspect/detectors/testdata/rmd-site-no-meta/index.Rmd new file mode 100644 index 000000000..87e0035a0 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/index.Rmd @@ -0,0 +1,27 @@ +# R Markdown site + +This is the index page. It has a link to [article](article.html) and [another](another.html). + +### A huge plot (scatter plot matrix) + +One disadvantage of `recordPlot()` is that it may not be able to record huge plots due to memory limits, e.g. a scatter plot matrix of tens of thousands of points: + +```{r gen-data, cache=TRUE} +# generate some random data +dat = matrix(runif(100000), ncol=5) +dat[, 3] = -.2 * dat[, 1] + .8 * dat[, 2] # to make the plot less boring +pairs(dat) +``` + +But scatter plots with such a large number of points are usually difficult to read (basically you can see nothing), so we'd better use some alternative ways to visualize them. For example, we can use 2D density estimates and draw contour plots, or just plot the LOWESS curve. + +```{r line-contour, cache=TRUE, dependson='gen-data'} +dens2d = function(x, y, ...) { + library(MASS) + res = kde2d(x, y) + with(res, contour(x, y, z, add = TRUE)) +} +pairs(dat, lower.panel = dens2d, upper.panel = function(x, y, ...) { + lines(lowess(y ~ x), col = 'red') +}) +``` diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/manifest.json b/internal/inspect/detectors/testdata/rmd-site-no-meta/manifest.json new file mode 100644 index 000000000..0e2aa6cc8 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/manifest.json @@ -0,0 +1,908 @@ +{ + "version": 1, + "locale": "en_US", + "platform": "4.3.0", + "metadata": { + "appmode": "rmd-static", + "primary_rmd": "index.Rmd", + "primary_html": null, + "content_category": "site", + "has_parameters": false + }, + "packages": { + "R6": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "R6", + "Title": "Encapsulated Classes with Reference Semantics", + "Version": "2.5.1", + "Authors@R": "person(\"Winston\", \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@stdout.org\")", + "Description": "Creates classes with reference semantics, similar to R's built-in\n reference classes. Compared to reference classes, R6 classes are simpler\n and lighter-weight, and they are not built on S4 classes so they do not\n require the methods package. These classes allow public and private\n members, and they support inheritance, even when the classes are defined in\n different packages.", + "Depends": "R (>= 3.0)", + "Suggests": "testthat, pryr", + "License": "MIT + file LICENSE", + "URL": "https://r6.r-lib.org, https://github.com/r-lib/R6/", + "BugReports": "https://github.com/r-lib/R6/issues", + "RoxygenNote": "7.1.1", + "NeedsCompilation": "no", + "Packaged": "2021-08-06 20:18:46 UTC; winston", + "Author": "Winston Chang [aut, cre]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2021-08-19 14:00:05 UTC", + "Built": "R 4.3.0; ; 2023-04-11 20:07:58 UTC; unix" + } + }, + "base64enc": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "base64enc", + "Version": "0.1-3", + "Title": "Tools for base64 encoding", + "Author": "Simon Urbanek ", + "Maintainer": "Simon Urbanek ", + "Depends": "R (>= 2.9.0)", + "Enhances": "png", + "Description": "This package provides tools for handling base64 encoding. It is more flexible than the orphaned base64 package.", + "License": "GPL-2 | GPL-3", + "URL": "http://www.rforge.net/base64enc", + "NeedsCompilation": "yes", + "Packaged": "2015-02-04 20:31:00 UTC; svnuser", + "Repository": "CRAN", + "Date/Publication": "2015-07-28 08:03:37", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:42 UTC; unix", + "Archs": "base64enc.so.dSYM" + } + }, + "bslib": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "bslib", + "Title": "Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'", + "Version": "0.4.2", + "Authors@R": "c(\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\"),\n person(family = \"Bootstrap contributors\", role = \"ctb\",\n comment = \"Bootstrap library\"),\n person(family = \"Twitter, Inc\", role = \"cph\",\n comment = \"Bootstrap library\"),\n person(\"Javi\", \"Aguilar\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootstrap colorpicker library\"),\n person(\"Thomas\", \"Park\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootswatch library\"),\n person(family = \"PayPal\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootstrap accessibility plugin\")\n )", + "Description": "Simplifies custom 'CSS' styling of both 'shiny' and 'rmarkdown' via 'Bootstrap' 'Sass'. Supports 'Bootstrap' 3, 4 and 5 as well as their various 'Bootswatch' themes. An interactive widget is also provided for previewing themes in real time.", + "Depends": "R (>= 2.10)", + "Imports": "grDevices, htmltools (>= 0.5.4), jsonlite, sass (>= 0.4.0),\njquerylib (>= 0.1.3), rlang, cachem, memoise (>= 2.0.1),\nbase64enc, mime", + "Suggests": "shiny (>= 1.6.0), rmarkdown (>= 2.7), thematic, knitr,\ntestthat, withr, rappdirs, curl, magrittr, fontawesome, bsicons", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Collate": "'bootswatch.R' 'bs-current-theme.R' 'bs-dependencies.R'\n'bs-global.R' 'bs-remove.R' 'bs-theme-layers.R' 'utils.R'\n'bs-theme-preview.R' 'bs-theme-update.R' 'bs-theme.R' 'card.R'\n'deprecated.R' 'files.R' 'imports.R' 'layout.R' 'nav-items.R'\n'nav-update.R' 'navs-legacy.R' 'navs.R' 'onLoad.R' 'page.R'\n'precompiled.R' 'print.R' 'shiny-devmode.R' 'staticimports.R'\n'utils-shiny.R' 'utils-tags.R' 'value-box.R'\n'version-default.R' 'versions.R'", + "URL": "https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib", + "BugReports": "https://github.com/rstudio/bslib/issues", + "Config/testthat/edition": "3", + "Config/Needs/routine": "desc, renv", + "Config/Needs/website": "brio, dplyr, glue, purrr, rprojroot, stringr,\ntidyr, DT, leaflet, plotly, htmlwidgets, shiny, ggplot2,\nsvglite", + "Config/Needs/deploy": "BH, DT, ggplot2, hexbin, lattice, lubridate,\ndplyr, modelr, nycflights13, histoslider, reactable, rprojroot,\nrsconnect, plotly, leaflet, gt, shiny, htmlwidgets", + "NeedsCompilation": "no", + "Packaged": "2022-12-15 16:02:29 UTC; cpsievert", + "Author": "Carson Sievert [aut, cre] (),\n Joe Cheng [aut],\n RStudio [cph],\n Bootstrap contributors [ctb] (Bootstrap library),\n Twitter, Inc [cph] (Bootstrap library),\n Javi Aguilar [ctb, cph] (Bootstrap colorpicker library),\n Thomas Park [ctb, cph] (Bootswatch library),\n PayPal [ctb, cph] (Bootstrap accessibility plugin)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2022-12-16 10:30:06 UTC", + "Built": "R 4.3.0; ; 2023-04-17 22:45:58 UTC; unix" + } + }, + "cachem": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "cachem", + "Version": "1.0.8", + "Title": "Cache R Objects with Automatic Pruning", + "Description": "Key-value stores with automatic pruning. Caches can limit\n either their total size or the age of the oldest object (or both),\n automatically pruning objects to maintain the constraints.", + "Authors@R": "c(\n person(\"Winston\", \"Chang\", , \"winston@rstudio.com\", c(\"aut\", \"cre\")),\n person(family = \"RStudio\", role = c(\"cph\", \"fnd\")))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "ByteCompile": "true", + "URL": "https://cachem.r-lib.org/, https://github.com/r-lib/cachem", + "Imports": "rlang, fastmap (>= 1.1.1)", + "Suggests": "testthat", + "RoxygenNote": "7.2.3", + "Config/Needs/routine": "lobstr", + "Config/Needs/website": "pkgdown", + "NeedsCompilation": "yes", + "Packaged": "2023-05-01 15:38:38 UTC; winston", + "Author": "Winston Chang [aut, cre],\n RStudio [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2023-05-01 16:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-05-03 23:25:36 UTC; unix", + "Archs": "cachem.so.dSYM" + } + }, + "cli": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "cli", + "Title": "Helpers for Developing Command Line Interfaces", + "Version": "3.6.1", + "Authors@R": "c(\n person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", role = \"ctb\"),\n person(\"Kirill\", \"Müller\", role = \"ctb\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "A suite of tools to build attractive command line interfaces\n ('CLIs'), from semantic elements: headings, lists, alerts, paragraphs,\n etc. Supports custom themes via a 'CSS'-like language. It also\n contains a number of lower level 'CLI' elements: rules, boxes, trees,\n and 'Unicode' symbols with 'ASCII' alternatives. It support ANSI\n colors and text styles as well.", + "License": "MIT + file LICENSE", + "URL": "https://cli.r-lib.org, https://github.com/r-lib/cli#readme", + "BugReports": "https://github.com/r-lib/cli/issues", + "Depends": "R (>= 3.4)", + "Imports": "utils", + "Suggests": "callr, covr, crayon, digest, glue (>= 1.6.0), grDevices,\nhtmltools, htmlwidgets, knitr, methods, mockery, processx, ps\n(>= 1.3.4.9000), rlang (>= 1.0.2.9003), rmarkdown, rprojroot,\nrstudioapi, testthat, tibble, whoami, withr", + "Config/Needs/website": "r-lib/asciicast, bench, brio, cpp11, decor, desc,\nfansi, prettyunits, sessioninfo, tidyverse/tidytemplate,\nusethis, vctrs", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1.9000", + "NeedsCompilation": "yes", + "Packaged": "2023-03-22 13:59:32 UTC; gaborcsardi", + "Author": "Gábor Csárdi [aut, cre],\n Hadley Wickham [ctb],\n Kirill Müller [ctb],\n RStudio [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN", + "Date/Publication": "2023-03-23 12:52:05 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:08:33 UTC; unix", + "Archs": "cli.so.dSYM" + } + }, + "digest": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "digest", + "Author": "Dirk Eddelbuettel with contributions\n by Antoine Lucas, Jarek Tuszynski, Henrik Bengtsson, Simon Urbanek,\n Mario Frasca, Bryan Lewis, Murray Stokely, Hannes Muehleisen,\n Duncan Murdoch, Jim Hester, Wush Wu, Qiang Kou, Thierry Onkelinx,\n Michel Lang, Viliam Simko, Kurt Hornik, Radford Neal, Kendon Bell,\n Matthew de Queljoe, Ion Suruceanu, Bill Denney, Dirk Schumacher,\n and Winston Chang.", + "Version": "0.6.31", + "Date": "2022-12-10", + "Maintainer": "Dirk Eddelbuettel ", + "Title": "Create Compact Hash Digests of R Objects", + "Description": "Implementation of a function 'digest()' for the creation of hash\n digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32',\n 'xxhash', 'murmurhash', 'spookyhash' and 'blake3' algorithms) permitting easy\n comparison of R language objects, as well as functions such as'hmac()' to\n create hash-based message authentication code. Please note that this package\n is not meant to be deployed for cryptographic purposes for which more\n comprehensive (and widely tested) libraries such as 'OpenSSL' should be\n used.", + "URL": "https://github.com/eddelbuettel/digest,\nhttp://dirk.eddelbuettel.com/code/digest.html", + "BugReports": "https://github.com/eddelbuettel/digest/issues", + "Depends": "R (>= 3.3.0)", + "Imports": "utils", + "License": "GPL (>= 2)", + "Suggests": "tinytest, simplermarkdown", + "VignetteBuilder": "simplermarkdown", + "NeedsCompilation": "yes", + "Packaged": "2022-12-10 18:30:14 UTC; edd", + "Repository": "CRAN", + "Date/Publication": "2022-12-11 07:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:54 UTC; unix", + "Archs": "digest.so.dSYM" + } + }, + "ellipsis": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "ellipsis", + "Version": "0.3.2", + "Title": "Tools for Working with ...", + "Description": "The ellipsis is a powerful tool for extending functions. Unfortunately \n this power comes at a cost: misspelled arguments will be silently ignored. \n The ellipsis package provides a collection of functions to catch problems\n and alert the user.", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(\"RStudio\", role = \"cph\")\n )", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "URL": "https://ellipsis.r-lib.org, https://github.com/r-lib/ellipsis", + "BugReports": "https://github.com/r-lib/ellipsis/issues", + "Depends": "R (>= 3.2)", + "Imports": "rlang (>= 0.3.0)", + "Suggests": "covr, testthat", + "NeedsCompilation": "yes", + "Packaged": "2021-04-29 12:06:44 UTC; lionel", + "Author": "Hadley Wickham [aut, cre],\n RStudio [cph]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2021-04-29 12:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:17:48 UTC; unix", + "Archs": "ellipsis.so.dSYM" + } + }, + "evaluate": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "evaluate", + "Type": "Package", + "Title": "Parsing and Evaluation Tools that Provide More Details than the\nDefault", + "Version": "0.21", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", role = \"aut\"),\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Michael\", \"Lawrence\", role = \"ctb\"),\n person(\"Thomas\", \"Kluyver\", role = \"ctb\"),\n person(\"Jeroen\", \"Ooms\", role = \"ctb\"),\n person(\"Barret\", \"Schloerke\", role = \"ctb\"),\n person(\"Adam\", \"Ryczkowski\", role = \"ctb\"),\n person(\"Hiroaki\", \"Yutani\", role = \"ctb\"),\n person(\"Michel\", \"Lang\", role = \"ctb\"),\n person(\"Karolis\", \"Koncevičius\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Parsing and evaluation tools that make it easy to recreate the\n command line behaviour of R.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/evaluate", + "BugReports": "https://github.com/r-lib/evaluate/issues", + "Depends": "R (>= 3.0.2)", + "Imports": "methods", + "Suggests": "covr, ggplot2, lattice, rlang, testthat (>= 3.0.0), withr", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Packaged": "2023-05-01 21:56:45 UTC; yihui", + "Author": "Hadley Wickham [aut],\n Yihui Xie [aut, cre] (),\n Michael Lawrence [ctb],\n Thomas Kluyver [ctb],\n Jeroen Ooms [ctb],\n Barret Schloerke [ctb],\n Adam Ryczkowski [ctb],\n Hiroaki Yutani [ctb],\n Michel Lang [ctb],\n Karolis Koncevičius [ctb],\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-05-05 23:30:02 UTC", + "Built": "R 4.3.0; ; 2023-05-05 23:40:19 UTC; unix" + } + }, + "fastmap": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "fastmap", + "Title": "Fast Data Structures", + "Version": "1.1.1", + "Authors@R": "c(\n person(\"Winston\", \"Chang\", email = \"winston@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(given = \"RStudio\", role = c(\"cph\", \"fnd\")),\n person(given = \"Tessil\", role = \"cph\", comment = \"hopscotch_map library\")\n )", + "Description": "Fast implementation of data structures, including a key-value\n store, stack, and queue. Environments are commonly used as key-value stores\n in R, but every time a new key is used, it is added to R's global symbol\n table, causing a small amount of memory leakage. This can be problematic in\n cases where many different keys are used. Fastmap avoids this memory leak\n issue by implementing the map using data structures in C++.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Suggests": "testthat (>= 2.1.1)", + "URL": "https://r-lib.github.io/fastmap/, https://github.com/r-lib/fastmap", + "BugReports": "https://github.com/r-lib/fastmap/issues", + "NeedsCompilation": "yes", + "Packaged": "2023-02-24 16:01:27 UTC; winston", + "Author": "Winston Chang [aut, cre],\n RStudio [cph, fnd],\n Tessil [cph] (hopscotch_map library)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2023-02-24 16:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:53 UTC; unix", + "Archs": "fastmap.so.dSYM" + } + }, + "fontawesome": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "fontawesome", + "Version": "0.5.1", + "Title": "Easily Work with 'Font Awesome' Icons", + "Description": "Easily and flexibly insert 'Font Awesome' icons into 'R Markdown'\n documents and 'Shiny' apps. These icons can be inserted into HTML content\n through inline 'SVG' tags or 'i' tags. There is also a utility function for\n exporting 'Font Awesome' icons as 'PNG' images for those situations where\n raster graphics are needed.", + "Authors@R": "c(\n person(\"Richard\", \"Iannone\", , \"rich@posit.co\", c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"ctb\",\n comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"ctb\"),\n person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"),\n comment = \"Font-Awesome font\"),\n person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/fontawesome,\nhttps://rstudio.github.io/fontawesome/", + "BugReports": "https://github.com/rstudio/fontawesome/issues", + "Encoding": "UTF-8", + "ByteCompile": "true", + "RoxygenNote": "7.2.3", + "Depends": "R (>= 3.3.0)", + "Imports": "rlang (>= 1.0.6), htmltools (>= 0.5.1.1)", + "Suggests": "covr, dplyr (>= 1.0.8), knitr (>= 1.31), testthat (>= 3.0.0),\nrsvg", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Packaged": "2023-04-18 17:20:05 UTC; rich", + "Author": "Richard Iannone [aut, cre] (),\n Christophe Dervieux [ctb] (),\n Winston Chang [ctb],\n Dave Gandy [ctb, cph] (Font-Awesome font),\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN", + "Date/Publication": "2023-04-18 20:30:02 UTC", + "Built": "R 4.3.0; ; 2023-04-22 00:45:59 UTC; unix" + } + }, + "fs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "fs", + "Title": "Cross-Platform File System Operations Based on 'libuv'", + "Version": "1.6.2", + "Authors@R": "c(\n person(\"Jim\", \"Hester\", role = \"aut\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"),\n person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")),\n person(\"libuv project contributors\", role = \"cph\",\n comment = \"libuv library\"),\n person(\"Joyent, Inc. and other Node contributors\", role = \"cph\",\n comment = \"libuv library\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "A cross-platform interface to file system operations, built\n on top of the 'libuv' C library.", + "License": "MIT + file LICENSE", + "URL": "https://fs.r-lib.org, https://github.com/r-lib/fs,\nhttps://fs.r-lib.org/", + "BugReports": "https://github.com/r-lib/fs/issues", + "Depends": "R (>= 3.4)", + "Imports": "methods", + "Suggests": "covr, crayon, knitr, pillar (>= 1.0.0), rmarkdown, spelling,\ntestthat (>= 3.0.0), tibble (>= 1.1.0), vctrs (>= 0.3.0), withr", + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.1.2", + "SystemRequirements": "GNU make", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Packaged": "2023-04-24 13:43:26 UTC; gaborcsardi", + "Author": "Jim Hester [aut],\n Hadley Wickham [aut],\n Gábor Csárdi [aut, cre],\n libuv project contributors [cph] (libuv library),\n Joyent, Inc. and other Node contributors [cph] (libuv library),\n RStudio [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN", + "Date/Publication": "2023-04-25 08:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-30 06:45:54 UTC; unix", + "Archs": "fs.so.dSYM" + } + }, + "glue": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "glue", + "Title": "Interpreted String Literals", + "Version": "1.6.2", + "Authors@R": "c(\n person(\"Jim\", \"Hester\", role = \"aut\",\n comment = c(ORCID = \"0000-0002-2739-7082\")),\n person(\"Jennifer\", \"Bryan\", , \"jenny@rstudio.com\", role = c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0002-6983-2759\")),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "An implementation of interpreted string literals, inspired by\n Python's Literal String Interpolation\n and Docstrings\n and Julia's Triple-Quoted\n String Literals\n .", + "License": "MIT + file LICENSE", + "URL": "https://github.com/tidyverse/glue, https://glue.tidyverse.org/", + "BugReports": "https://github.com/tidyverse/glue/issues", + "Depends": "R (>= 3.4)", + "Imports": "methods", + "Suggests": "covr, crayon, DBI, dplyr, forcats, ggplot2, knitr, magrittr,\nmicrobenchmark, R.utils, rmarkdown, rprintf, RSQLite, stringr,\ntestthat (>= 3.0.0), vctrs (>= 0.3.0), waldo (>= 0.3.0), withr", + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "hadley/emo, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Packaged": "2022-02-23 22:50:40 UTC; jenny", + "Author": "Jim Hester [aut] (),\n Jennifer Bryan [aut, cre] (),\n RStudio [cph, fnd]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN", + "Date/Publication": "2022-02-24 07:50:20 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:07:27 UTC; unix", + "Archs": "glue.so.dSYM" + } + }, + "highr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "highr", + "Type": "Package", + "Title": "Syntax Highlighting for R Source Code", + "Version": "0.10", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Yixuan\", \"Qiu\", role = \"aut\"),\n person(\"Christopher\", \"Gandrud\", role = \"ctb\"),\n person(\"Qiang\", \"Li\", role = \"ctb\")\n )", + "Description": "Provides syntax highlighting for R source code. Currently it\n supports LaTeX and HTML output. Source code of other languages is supported\n via Andre Simon's highlight package ().", + "Depends": "R (>= 3.3.0)", + "Imports": "xfun (>= 0.18)", + "Suggests": "knitr, markdown, testit", + "License": "GPL", + "URL": "https://github.com/yihui/highr", + "BugReports": "https://github.com/yihui/highr/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2022-12-22 06:43:07 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Yixuan Qiu [aut],\n Christopher Gandrud [ctb],\n Qiang Li [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2022-12-22 07:00:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 06:44:58 UTC; unix" + } + }, + "htmltools": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "htmltools", + "Type": "Package", + "Title": "Tools for HTML", + "Version": "0.5.5", + "Authors@R": "c(\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Barret\", \"Schloerke\", role = \"aut\", email = \"barret@rstudio.com\", comment = c(ORCID = \"0000-0001-9986-114X\")),\n person(\"Winston\", \"Chang\", role = \"aut\", email = \"winston@rstudio.com\", comment = c(ORCID = \"0000-0002-1576-2126\")),\n person(\"Yihui\", \"Xie\", role = \"aut\", email = \"yihui@rstudio.com\"),\n person(\"Jeff\", \"Allen\", role = \"aut\", email = \"jeff@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\")\n )", + "Description": "Tools for HTML generation and output.", + "Depends": "R (>= 2.14.1)", + "Imports": "utils, digest, grDevices, base64enc, rlang (>= 0.4.10),\nfastmap (>= 1.1.0), ellipsis", + "Suggests": "markdown, testthat, withr, Cairo, ragg, shiny", + "Enhances": "knitr", + "License": "GPL (>= 2)", + "URL": "https://github.com/rstudio/htmltools,\nhttps://rstudio.github.io/htmltools/", + "BugReports": "https://github.com/rstudio/htmltools/issues", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "Collate": "'colors.R' 'fill.R' 'html_dependency.R' 'html_escape.R'\n'html_print.R' 'images.R' 'known_tags.R' 'selector.R'\n'staticimports.R' 'tag_query.R' 'utils.R' 'tags.R' 'template.R'", + "Config/Needs/website": "rstudio/quillt, bench", + "NeedsCompilation": "yes", + "Packaged": "2023-03-22 22:59:42 UTC; cpsievert", + "Author": "Joe Cheng [aut],\n Carson Sievert [aut, cre] (),\n Barret Schloerke [aut] (),\n Winston Chang [aut] (),\n Yihui Xie [aut],\n Jeff Allen [aut],\n RStudio [cph]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2023-03-23 09:50:06 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-12 06:43:49 UTC; unix", + "Archs": "htmltools.so.dSYM" + } + }, + "jquerylib": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "jquerylib", + "Title": "Obtain 'jQuery' as an HTML Dependency Object", + "Version": "0.1.4", + "Authors@R": "c(\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\"),\n person(family = \"jQuery Foundation\", role = \"cph\",\n comment = \"jQuery library and jQuery UI library\"),\n person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"),\n comment = \"jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt\")\n )", + "Description": "Obtain any major version of 'jQuery' () and use it in any webpage generated by 'htmltools' (e.g. 'shiny', 'htmlwidgets', and 'rmarkdown').\n Most R users don't need to use this package directly, but other R packages (e.g. 'shiny', 'rmarkdown', etc.) depend on this package to avoid bundling redundant copies of 'jQuery'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "RoxygenNote": "7.0.2", + "Imports": "htmltools", + "Suggests": "testthat", + "NeedsCompilation": "no", + "Packaged": "2021-04-26 16:40:21 UTC; cpsievert", + "Author": "Carson Sievert [aut, cre] (),\n Joe Cheng [aut],\n RStudio [cph],\n jQuery Foundation [cph] (jQuery library and jQuery UI library),\n jQuery contributors [ctb, cph] (jQuery library; authors listed in\n inst/lib/jquery-AUTHORS.txt)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2021-04-26 17:10:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 11:15:31 UTC; unix" + } + }, + "jsonlite": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "jsonlite", + "Version": "1.8.4", + "Title": "A Simple and Robust JSON Parser and Generator for R", + "License": "MIT + file LICENSE", + "Depends": "methods", + "Authors@R": "c(\n person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroen@berkeley.edu\",\n comment = c(ORCID = \"0000-0002-4035-0289\")),\n person(\"Duncan\", \"Temple Lang\", role = \"ctb\"),\n person(\"Lloyd\", \"Hilaiel\", role = \"cph\", comment=\"author of bundled libyajl\"))", + "URL": "https://arxiv.org/abs/1403.2805 (paper)", + "BugReports": "https://github.com/jeroen/jsonlite/issues", + "Maintainer": "Jeroen Ooms ", + "VignetteBuilder": "knitr, R.rsp", + "Description": "A reasonably fast JSON parser and generator, optimized for statistical \n data and the web. Offers simple, flexible tools for working with JSON in R, and\n is particularly powerful for building pipelines and interacting with a web API. \n The implementation is based on the mapping described in the vignette (Ooms, 2014).\n In addition to converting JSON data from/to R objects, 'jsonlite' contains \n functions to stream, validate, and prettify JSON data. The unit tests included \n with the package verify that all edge cases are encoded and decoded consistently \n for use with dynamic data in systems and applications.", + "Suggests": "httr, vctrs, testthat, knitr, rmarkdown, R.rsp, sf", + "RoxygenNote": "7.2.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2022-12-05 23:21:23 UTC; jeroen", + "Author": "Jeroen Ooms [aut, cre] (),\n Duncan Temple Lang [ctb],\n Lloyd Hilaiel [cph] (author of bundled libyajl)", + "Repository": "CRAN", + "Date/Publication": "2022-12-06 08:10:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:18:22 UTC; unix", + "Archs": "jsonlite.so.dSYM" + } + }, + "knitr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "knitr", + "Type": "Package", + "Title": "A General-Purpose Package for Dynamic Report Generation in R", + "Version": "1.42", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Abhraneel\", \"Sarma\", role = \"ctb\"),\n person(\"Adam\", \"Vogt\", role = \"ctb\"),\n person(\"Alastair\", \"Andrew\", role = \"ctb\"),\n person(\"Alex\", \"Zvoleff\", role = \"ctb\"),\n person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"),\n person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"),\n person(\"Aron\", \"Atkins\", role = \"ctb\"),\n person(\"Aaron\", \"Wolen\", role = \"ctb\"),\n person(\"Ashley\", \"Manton\", role = \"ctb\"),\n person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")),\n person(\"Ben\", \"Baumer\", role = \"ctb\"),\n person(\"Brian\", \"Diggs\", role = \"ctb\"),\n person(\"Brian\", \"Zhang\", role = \"ctb\"),\n person(\"Bulat\", \"Yapparov\", role = \"ctb\"),\n person(\"Cassio\", \"Pereira\", role = \"ctb\"),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\"),\n person(\"David\", \"Hall\", role = \"ctb\"),\n person(\"David\", \"Hugh-Jones\", role = \"ctb\"),\n person(\"David\", \"Robinson\", role = \"ctb\"),\n person(\"Doug\", \"Hemken\", role = \"ctb\"),\n person(\"Duncan\", \"Murdoch\", role = \"ctb\"),\n person(\"Elio\", \"Campitelli\", role = \"ctb\"),\n person(\"Ellis\", \"Hughes\", role = \"ctb\"),\n person(\"Emily\", \"Riederer\", role = \"ctb\"),\n person(\"Fabian\", \"Hirschmann\", role = \"ctb\"),\n person(\"Fitch\", \"Simeon\", role = \"ctb\"),\n person(\"Forest\", \"Fang\", role = \"ctb\"),\n person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"),\n person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"),\n person(\"Gregoire\", \"Detrez\", role = \"ctb\"),\n person(\"Hadley\", \"Wickham\", role = \"ctb\"),\n person(\"Hao\", \"Zhu\", role = \"ctb\"),\n person(\"Heewon\", \"Jeon\", role = \"ctb\"),\n person(\"Henrik\", \"Bengtsson\", role = \"ctb\"),\n person(\"Hiroaki\", \"Yutani\", role = \"ctb\"),\n person(\"Ian\", \"Lyttle\", role = \"ctb\"),\n person(\"Hodges\", \"Daniel\", role = \"ctb\"),\n person(\"Jacob\", \"Bien\", role = \"ctb\"),\n person(\"Jake\", \"Burkhead\", role = \"ctb\"),\n person(\"James\", \"Manton\", role = \"ctb\"),\n person(\"Jared\", \"Lander\", role = \"ctb\"),\n person(\"Jason\", \"Punyon\", role = \"ctb\"),\n person(\"Javier\", \"Luraschi\", role = \"ctb\"),\n person(\"Jeff\", \"Arnold\", role = \"ctb\"),\n person(\"Jenny\", \"Bryan\", role = \"ctb\"),\n person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"),\n person(\"Jeremy\", \"Stephens\", role = \"ctb\"),\n person(\"Jim\", \"Hester\", role = \"ctb\"),\n person(\"Joe\", \"Cheng\", role = \"ctb\"),\n person(\"Johannes\", \"Ranke\", role = \"ctb\"),\n person(\"John\", \"Honaker\", role = \"ctb\"),\n person(\"John\", \"Muschelli\", role = \"ctb\"),\n person(\"Jonathan\", \"Keane\", role = \"ctb\"),\n person(\"JJ\", \"Allaire\", role = \"ctb\"),\n person(\"Johan\", \"Toloe\", role = \"ctb\"),\n person(\"Jonathan\", \"Sidi\", role = \"ctb\"),\n person(\"Joseph\", \"Larmarange\", role = \"ctb\"),\n person(\"Julien\", \"Barnier\", role = \"ctb\"),\n person(\"Kaiyin\", \"Zhong\", role = \"ctb\"),\n person(\"Kamil\", \"Slowikowski\", role = \"ctb\"),\n person(\"Karl\", \"Forner\", role = \"ctb\"),\n person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"),\n person(\"Kirill\", \"Mueller\", role = \"ctb\"),\n person(\"Kohske\", \"Takahashi\", role = \"ctb\"),\n person(\"Lorenz\", \"Walthert\", role = \"ctb\"),\n person(\"Lucas\", \"Gallindo\", role = \"ctb\"),\n person(\"Marius\", \"Hofert\", role = \"ctb\"),\n person(\"Martin\", \"Modrák\", role = \"ctb\"),\n person(\"Michael\", \"Chirico\", role = \"ctb\"),\n person(\"Michael\", \"Friendly\", role = \"ctb\"),\n person(\"Michal\", \"Bojanowski\", role = \"ctb\"),\n person(\"Michel\", \"Kuhlmann\", role = \"ctb\"),\n person(\"Miller\", \"Patrick\", role = \"ctb\"),\n person(\"Nacho\", \"Caballero\", role = \"ctb\"),\n person(\"Nick\", \"Salkowski\", role = \"ctb\"),\n person(\"Niels Richard\", \"Hansen\", role = \"ctb\"),\n person(\"Noam\", \"Ross\", role = \"ctb\"),\n person(\"Obada\", \"Mahdi\", role = \"ctb\"),\n person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")),\n person(\"Pedro\", \"Faria\", role = \"ctb\"),\n person(\"Qiang\", \"Li\", role = \"ctb\"),\n person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"),\n person(\"Richard\", \"Cotton\", role = \"ctb\"),\n person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"),\n person(\"Rodrigo\", \"Copetti\", role = \"ctb\"),\n person(\"Romain\", \"Francois\", role = \"ctb\"),\n person(\"Ruaridh\", \"Williamson\", role = \"ctb\"),\n person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")),\n person(\"Scott\", \"Kostyshak\", role = \"ctb\"),\n person(\"Sebastian\", \"Meyer\", role = \"ctb\"),\n person(\"Sietse\", \"Brouwer\", role = \"ctb\"),\n person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"),\n person(\"Sylvain\", \"Rousseau\", role = \"ctb\"),\n person(\"Taiyun\", \"Wei\", role = \"ctb\"),\n person(\"Thibaut\", \"Assus\", role = \"ctb\"),\n person(\"Thibaut\", \"Lamadon\", role = \"ctb\"),\n person(\"Thomas\", \"Leeper\", role = \"ctb\"),\n person(\"Tim\", \"Mastny\", role = \"ctb\"),\n person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"),\n person(\"Trevor\", \"Davis\", role = \"ctb\"),\n person(\"Viktoras\", \"Veitas\", role = \"ctb\"),\n person(\"Weicheng\", \"Zhu\", role = \"ctb\"),\n person(\"Wush\", \"Wu\", role = \"ctb\"),\n person(\"Zachary\", \"Foster\", role = \"ctb\"),\n person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\"))\n )", + "Description": "Provides a general-purpose tool for dynamic report generation in R\n using Literate Programming techniques.", + "Depends": "R (>= 3.3.0)", + "Imports": "evaluate (>= 0.15), highr, methods, yaml (>= 2.1.19), xfun (>=\n0.34), tools", + "Suggests": "markdown (>= 1.3), formatR, testit, digest, rgl (>=\n0.95.1201), codetools, rmarkdown, htmlwidgets (>= 0.7),\nwebshot, tikzDevice (>= 0.10), tinytex, reticulate (>= 1.4),\nJuliaCall (>= 0.11.1), magick, png, jpeg, gifski, xml2 (>=\n1.2.0), httr, DBI (>= 0.4-1), showtext, tibble, sass, bslib,\nragg, gridSVG, styler (>= 1.2.0), targets (>= 0.6.0)", + "License": "GPL", + "URL": "https://yihui.org/knitr/", + "BugReports": "https://github.com/yihui/knitr/issues", + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "SystemRequirements": "Package vignettes based on R Markdown v2 or\nreStructuredText require Pandoc (http://pandoc.org). The\nfunction rst2pdf() requires rst2pdf\n(https://github.com/rst2pdf/rst2pdf).", + "Collate": "'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R'\n'plot.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R'\n'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R'\n'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R'\n'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R'\n'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R'\n'template.R' 'utils-conversion.R' 'utils-rd2html.R'\n'utils-string.R' 'utils-sweave.R' 'utils-upload.R'\n'utils-vignettes.R' 'zzz.R'", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2023-01-20 05:51:44 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Abhraneel Sarma [ctb],\n Adam Vogt [ctb],\n Alastair Andrew [ctb],\n Alex Zvoleff [ctb],\n Amar Al-Zubaidi [ctb],\n Andre Simon [ctb] (the CSS files under inst/themes/ were derived from\n the Highlight package http://www.andre-simon.de),\n Aron Atkins [ctb],\n Aaron Wolen [ctb],\n Ashley Manton [ctb],\n Atsushi Yasumoto [ctb] (),\n Ben Baumer [ctb],\n Brian Diggs [ctb],\n Brian Zhang [ctb],\n Bulat Yapparov [ctb],\n Cassio Pereira [ctb],\n Christophe Dervieux [ctb],\n David Hall [ctb],\n David Hugh-Jones [ctb],\n David Robinson [ctb],\n Doug Hemken [ctb],\n Duncan Murdoch [ctb],\n Elio Campitelli [ctb],\n Ellis Hughes [ctb],\n Emily Riederer [ctb],\n Fabian Hirschmann [ctb],\n Fitch Simeon [ctb],\n Forest Fang [ctb],\n Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty),\n Garrick Aden-Buie [ctb],\n Gregoire Detrez [ctb],\n Hadley Wickham [ctb],\n Hao Zhu [ctb],\n Heewon Jeon [ctb],\n Henrik Bengtsson [ctb],\n Hiroaki Yutani [ctb],\n Ian Lyttle [ctb],\n Hodges Daniel [ctb],\n Jacob Bien [ctb],\n Jake Burkhead [ctb],\n James Manton [ctb],\n Jared Lander [ctb],\n Jason Punyon [ctb],\n Javier Luraschi [ctb],\n Jeff Arnold [ctb],\n Jenny Bryan [ctb],\n Jeremy Ashkenas [ctb, cph] (the CSS file at\n inst/misc/docco-classic.css),\n Jeremy Stephens [ctb],\n Jim Hester [ctb],\n Joe Cheng [ctb],\n Johannes Ranke [ctb],\n John Honaker [ctb],\n John Muschelli [ctb],\n Jonathan Keane [ctb],\n JJ Allaire [ctb],\n Johan Toloe [ctb],\n Jonathan Sidi [ctb],\n Joseph Larmarange [ctb],\n Julien Barnier [ctb],\n Kaiyin Zhong [ctb],\n Kamil Slowikowski [ctb],\n Karl Forner [ctb],\n Kevin K. Smith [ctb],\n Kirill Mueller [ctb],\n Kohske Takahashi [ctb],\n Lorenz Walthert [ctb],\n Lucas Gallindo [ctb],\n Marius Hofert [ctb],\n Martin Modrák [ctb],\n Michael Chirico [ctb],\n Michael Friendly [ctb],\n Michal Bojanowski [ctb],\n Michel Kuhlmann [ctb],\n Miller Patrick [ctb],\n Nacho Caballero [ctb],\n Nick Salkowski [ctb],\n Niels Richard Hansen [ctb],\n Noam Ross [ctb],\n Obada Mahdi [ctb],\n Pavel N. Krivitsky [ctb] (),\n Pedro Faria [ctb],\n Qiang Li [ctb],\n Ramnath Vaidyanathan [ctb],\n Richard Cotton [ctb],\n Robert Krzyzanowski [ctb],\n Rodrigo Copetti [ctb],\n Romain Francois [ctb],\n Ruaridh Williamson [ctb],\n Sagiru Mati [ctb] (),\n Scott Kostyshak [ctb],\n Sebastian Meyer [ctb],\n Sietse Brouwer [ctb],\n Simon de Bernard [ctb],\n Sylvain Rousseau [ctb],\n Taiyun Wei [ctb],\n Thibaut Assus [ctb],\n Thibaut Lamadon [ctb],\n Thomas Leeper [ctb],\n Tim Mastny [ctb],\n Tom Torsney-Weir [ctb],\n Trevor Davis [ctb],\n Viktoras Veitas [ctb],\n Weicheng Zhu [ctb],\n Wush Wu [ctb],\n Zachary Foster [ctb],\n Zhian N. Kamvar [ctb] ()", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-01-25 10:20:08 UTC", + "Built": "R 4.3.0; ; 2023-04-12 11:17:12 UTC; unix" + } + }, + "lifecycle": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "lifecycle", + "Title": "Manage the Life Cycle of your Package Functions", + "Version": "1.0.3", + "Authors@R": "c(\n person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\",\n comment = c(ORCID = \"0000-0003-4757-117X\")),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Manage the life cycle of your exported functions with shared\n conventions, documentation badges, and user-friendly deprecation\n warnings.", + "License": "MIT + file LICENSE", + "URL": "https://lifecycle.r-lib.org/, https://github.com/r-lib/lifecycle", + "BugReports": "https://github.com/r-lib/lifecycle/issues", + "Depends": "R (>= 3.4)", + "Imports": "cli (>= 3.4.0), glue, rlang (>= 1.0.6)", + "Suggests": "covr, crayon, knitr, lintr, rmarkdown, testthat (>= 3.0.1),\ntibble, tidyverse, tools, vctrs, withr", + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Packaged": "2022-10-07 08:50:55 UTC; lionel", + "Author": "Lionel Henry [aut, cre],\n Hadley Wickham [aut] (),\n RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2022-10-07 09:50:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 06:43:28 UTC; unix" + } + }, + "magrittr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "magrittr", + "Title": "A Forward-Pipe Operator for R", + "Version": "2.0.3", + "Authors@R": "c(\n person(\"Stefan Milton\", \"Bache\", , \"stefan@stefanbache.dk\", role = c(\"aut\", \"cph\"),\n comment = \"Original author and creator of magrittr\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"),\n person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = \"cre\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Provides a mechanism for chaining commands with a new\n forward-pipe operator, %>%. This operator will forward a value, or the\n result of an expression, into the next function call/expression.\n There is flexible support for the type of right-hand side expressions.\n For more information, see package vignette. To quote Rene Magritte,\n \"Ceci n'est pas un pipe.\"", + "License": "MIT + file LICENSE", + "URL": "https://magrittr.tidyverse.org,\nhttps://github.com/tidyverse/magrittr", + "BugReports": "https://github.com/tidyverse/magrittr/issues", + "Depends": "R (>= 3.4.0)", + "Suggests": "covr, knitr, rlang, rmarkdown, testthat", + "VignetteBuilder": "knitr", + "ByteCompile": "Yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Packaged": "2022-03-29 09:34:37 UTC; lionel", + "Author": "Stefan Milton Bache [aut, cph] (Original author and creator of\n magrittr),\n Hadley Wickham [aut],\n Lionel Henry [cre],\n RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2022-03-30 07:30:09 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:07:22 UTC; unix", + "Archs": "magrittr.so.dSYM" + } + }, + "memoise": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "memoise", + "Title": "'Memoisation' of Functions", + "Version": "2.0.1", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = \"aut\",\n email = \"hadley@rstudio.com\"),\n person(given = \"Jim\",\n family = \"Hester\",\n role = \"aut\"),\n person(given = \"Winston\",\n family = \"Chang\",\n role = c(\"aut\", \"cre\"),\n email = \"winston@rstudio.com\"),\n person(given = \"Kirill\",\n family = \"Müller\",\n role = \"aut\",\n email = \"krlmlr+r@mailbox.org\"),\n person(given = \"Daniel\",\n family = \"Cook\",\n role = \"aut\",\n email = \"danielecook@gmail.com\"),\n person(given = \"Mark\",\n family = \"Edmondson\",\n role = \"ctb\",\n email = \"r@sunholo.com\"))", + "Description": "Cache the results of a function so that when you\n call it again with the same arguments it returns the previously computed\n value.", + "License": "MIT + file LICENSE", + "URL": "https://memoise.r-lib.org, https://github.com/r-lib/memoise", + "BugReports": "https://github.com/r-lib/memoise/issues", + "Imports": "rlang (>= 0.4.10), cachem", + "Suggests": "digest, aws.s3, covr, googleAuthR, googleCloudStorageR, httr,\ntestthat", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "no", + "Packaged": "2021-11-24 21:24:50 UTC; jhester", + "Author": "Hadley Wickham [aut],\n Jim Hester [aut],\n Winston Chang [aut, cre],\n Kirill Müller [aut],\n Daniel Cook [aut],\n Mark Edmondson [ctb]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2021-11-26 16:11:10 UTC", + "Built": "R 4.3.0; ; 2023-04-17 22:23:05 UTC; unix" + } + }, + "mime": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "mime", + "Type": "Package", + "Title": "Map Filenames to MIME Types", + "Version": "0.12", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Jeffrey\", \"Horner\", role = \"ctb\"),\n person(\"Beilei\", \"Bian\", role = \"ctb\")\n )", + "Description": "Guesses the MIME type from a filename extension using the data\n derived from /etc/mime.types in UNIX-type systems.", + "Imports": "tools", + "License": "GPL", + "URL": "https://github.com/yihui/mime", + "BugReports": "https://github.com/yihui/mime/issues", + "RoxygenNote": "7.1.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2021-09-28 02:06:04 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Jeffrey Horner [ctb],\n Beilei Bian [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2021-09-28 05:00:05 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:16 UTC; unix", + "Archs": "mime.so.dSYM" + } + }, + "rappdirs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "rappdirs", + "Title": "Application Directories: Determine Where to Save Data, Caches,\nand Logs", + "Version": "0.3.3", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = c(\"trl\", \"cre\", \"cph\"),\n email = \"hadley@rstudio.com\"),\n person(given = \"RStudio\",\n role = \"cph\"),\n person(given = \"Sridhar\",\n family = \"Ratnakumar\",\n role = \"aut\"),\n person(given = \"Trent\",\n family = \"Mick\",\n role = \"aut\"),\n person(given = \"ActiveState\",\n role = \"cph\",\n comment = \"R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs\"),\n person(given = \"Eddy\",\n family = \"Petrisor\",\n role = \"ctb\"),\n person(given = \"Trevor\",\n family = \"Davis\",\n role = c(\"trl\", \"aut\")),\n person(given = \"Gabor\",\n family = \"Csardi\",\n role = \"ctb\"),\n person(given = \"Gregory\",\n family = \"Jefferis\",\n role = \"ctb\"))", + "Description": "An easy way to determine which directories on the\n users computer you should use to save data, caches and logs. A port of\n Python's 'Appdirs' () to\n R.", + "License": "MIT + file LICENSE", + "URL": "https://rappdirs.r-lib.org, https://github.com/r-lib/rappdirs", + "BugReports": "https://github.com/r-lib/rappdirs/issues", + "Depends": "R (>= 3.2)", + "Suggests": "roxygen2, testthat (>= 3.0.0), covr, withr", + "Copyright": "Original python appdirs module copyright (c) 2010\nActiveState Software Inc. R port copyright Hadley Wickham,\nRStudio. See file LICENSE for details.", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Packaged": "2021-01-28 22:29:57 UTC; hadley", + "Author": "Hadley Wickham [trl, cre, cph],\n RStudio [cph],\n Sridhar Ratnakumar [aut],\n Trent Mick [aut],\n ActiveState [cph] (R/appdir.r, R/cache.r, R/data.r, R/log.r translated\n from appdirs),\n Eddy Petrisor [ctb],\n Trevor Davis [trl, aut],\n Gabor Csardi [ctb],\n Gregory Jefferis [ctb]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2021-01-31 05:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:10:28 UTC; unix", + "Archs": "rappdirs.so.dSYM" + } + }, + "rlang": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "rlang", + "Version": "1.1.1", + "Title": "Functions for Base Types and Core R and 'Tidyverse' Features", + "Description": "A toolbox for working with base types, core R features\n like the condition system, and core 'Tidyverse' features like tidy\n evaluation.", + "Authors@R": "c(\n person(\"Lionel\", \"Henry\", ,\"lionel@posit.co\", c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", ,\"hadley@posit.co\", \"aut\"),\n person(given = \"mikefc\",\n email = \"mikefc@coolbutuseless.com\", \n role = \"cph\", \n comment = \"Hash implementation based on Mike's xxhashlite\"),\n person(given = \"Yann\",\n family = \"Collet\",\n role = \"cph\", \n comment = \"Author of the embedded xxHash library\"),\n person(given = \"Posit, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "License": "MIT + file LICENSE", + "ByteCompile": "true", + "Biarch": "true", + "Depends": "R (>= 3.5.0)", + "Imports": "utils", + "Suggests": "cli (>= 3.1.0), covr, crayon, fs, glue, knitr, magrittr,\nmethods, pillar, rmarkdown, stats, testthat (>= 3.0.0), tibble,\nusethis, vctrs (>= 0.2.3), withr", + "Enhances": "winch", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "URL": "https://rlang.r-lib.org, https://github.com/r-lib/rlang", + "BugReports": "https://github.com/r-lib/rlang/issues", + "Config/testthat/edition": "3", + "Config/Needs/website": "dplyr, tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Packaged": "2023-04-28 10:48:43 UTC; lionel", + "Author": "Lionel Henry [aut, cre],\n Hadley Wickham [aut],\n mikefc [cph] (Hash implementation based on Mike's xxhashlite),\n Yann Collet [cph] (Author of the embedded xxHash library),\n Posit, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2023-04-28 22:30:03 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-30 06:48:25 UTC; unix", + "Archs": "rlang.so.dSYM" + } + }, + "rmarkdown": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "rmarkdown", + "Title": "Dynamic Documents for R", + "Version": "2.21", + "Authors@R": "c(\n person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\"),\n person(\"Yihui\", \"Xie\", , \"xie@yihui.name\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Jonathan\", \"McPherson\", , \"jonathan@posit.co\", role = \"aut\"),\n person(\"Javier\", \"Luraschi\", role = \"aut\"),\n person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"aut\"),\n person(\"Aron\", \"Atkins\", , \"aron@posit.co\", role = \"aut\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"),\n person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"),\n person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\"),\n person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Andrew\", \"Dunning\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0464-5036\")),\n person(\"Atsushi\", \"Yasumoto\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-8335-495X\", cph = \"Number sections Lua filter\")),\n person(\"Barret\", \"Schloerke\", role = \"ctb\"),\n person(\"Carson\", \"Sievert\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4958-2844\")), \n person(\"Devon\", \"Ryan\", , \"dpryan79@gmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8549-0971\")),\n person(\"Frederik\", \"Aust\", , \"frederik.aust@uni-koeln.de\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4900-788X\")),\n person(\"Jeff\", \"Allen\", , \"jeff@posit.co\", role = \"ctb\"), \n person(\"JooYoung\", \"Seo\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4064-6012\")),\n person(\"Malcolm\", \"Barrett\", role = \"ctb\"),\n person(\"Rob\", \"Hyndman\", , \"Rob.Hyndman@monash.edu\", role = \"ctb\"),\n person(\"Romain\", \"Lesur\", role = \"ctb\"),\n person(\"Roy\", \"Storey\", role = \"ctb\"),\n person(\"Ruben\", \"Arslan\", , \"ruben.arslan@uni-goettingen.de\", role = \"ctb\"),\n person(\"Sergio\", \"Oller\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person(, \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/rmd/h/jqueryui-AUTHORS.txt\"),\n person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"),\n person(\"Alexander\", \"Farkas\", role = c(\"ctb\", \"cph\"), comment = \"html5shiv library\"),\n person(\"Scott\", \"Jehl\", role = c(\"ctb\", \"cph\"), comment = \"Respond.js library\"),\n person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"),\n person(\"Greg\", \"Franko\", role = c(\"ctb\", \"cph\"), comment = \"tocify library\"),\n person(\"John\", \"MacFarlane\", role = c(\"ctb\", \"cph\"), comment = \"Pandoc templates\"),\n person(, \"Google, Inc.\", role = c(\"ctb\", \"cph\"), comment = \"ioslides library\"),\n person(\"Dave\", \"Raggett\", role = \"ctb\", comment = \"slidy library\"),\n person(, \"W3C\", role = \"cph\", comment = \"slidy library\"),\n person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome\"),\n person(\"Ben\", \"Sperry\", role = \"ctb\", comment = \"Ionicons\"),\n person(, \"Drifty\", role = \"cph\", comment = \"Ionicons\"),\n person(\"Aidan\", \"Lister\", role = c(\"ctb\", \"cph\"), comment = \"jQuery StickyTabs\"),\n person(\"Benct Philip\", \"Jonsson\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\"),\n person(\"Albert\", \"Krewinkel\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\")\n )", + "Maintainer": "Yihui Xie ", + "Description": "Convert R Markdown documents into a variety of formats.", + "License": "GPL-3", + "URL": "https://github.com/rstudio/rmarkdown,\nhttps://pkgs.rstudio.com/rmarkdown/", + "BugReports": "https://github.com/rstudio/rmarkdown/issues", + "Depends": "R (>= 3.0)", + "Imports": "bslib (>= 0.2.5.1), evaluate (>= 0.13), fontawesome (>=\n0.5.0), htmltools (>= 0.5.1), jquerylib, jsonlite, knitr (>=\n1.22), methods, stringr (>= 1.2.0), tinytex (>= 0.31), tools,\nutils, xfun (>= 0.36), yaml (>= 2.1.19)", + "Suggests": "digest, dygraphs, fs, rsconnect, downlit (>= 0.4.0), katex\n(>= 1.4.0), sass (>= 0.4.0), shiny (>= 1.6.0), testthat (>=\n3.0.3), tibble, vctrs, withr (>= 2.4.2)", + "VignetteBuilder": "knitr", + "Config/Needs/website": "rstudio/quillt, pkgdown", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "pandoc (>= 1.14) - http://pandoc.org", + "NeedsCompilation": "no", + "Packaged": "2023-03-25 21:50:22 UTC; yihui", + "Author": "JJ Allaire [aut],\n Yihui Xie [aut, cre] (),\n Christophe Dervieux [aut] (),\n Jonathan McPherson [aut],\n Javier Luraschi [aut],\n Kevin Ushey [aut],\n Aron Atkins [aut],\n Hadley Wickham [aut],\n Joe Cheng [aut],\n Winston Chang [aut],\n Richard Iannone [aut] (),\n Andrew Dunning [ctb] (),\n Atsushi Yasumoto [ctb, cph] (,\n Number sections Lua filter),\n Barret Schloerke [ctb],\n Carson Sievert [ctb] (),\n Devon Ryan [ctb] (),\n Frederik Aust [ctb] (),\n Jeff Allen [ctb],\n JooYoung Seo [ctb] (),\n Malcolm Barrett [ctb],\n Rob Hyndman [ctb],\n Romain Lesur [ctb],\n Roy Storey [ctb],\n Ruben Arslan [ctb],\n Sergio Oller [ctb],\n Posit Software, PBC [cph, fnd],\n jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in\n inst/rmd/h/jqueryui-AUTHORS.txt),\n Mark Otto [ctb] (Bootstrap library),\n Jacob Thornton [ctb] (Bootstrap library),\n Bootstrap contributors [ctb] (Bootstrap library),\n Twitter, Inc [cph] (Bootstrap library),\n Alexander Farkas [ctb, cph] (html5shiv library),\n Scott Jehl [ctb, cph] (Respond.js library),\n Ivan Sagalaev [ctb, cph] (highlight.js library),\n Greg Franko [ctb, cph] (tocify library),\n John MacFarlane [ctb, cph] (Pandoc templates),\n Google, Inc. [ctb, cph] (ioslides library),\n Dave Raggett [ctb] (slidy library),\n W3C [cph] (slidy library),\n Dave Gandy [ctb, cph] (Font-Awesome),\n Ben Sperry [ctb] (Ionicons),\n Drifty [cph] (Ionicons),\n Aidan Lister [ctb, cph] (jQuery StickyTabs),\n Benct Philip Jonsson [ctb, cph] (pagebreak Lua filter),\n Albert Krewinkel [ctb, cph] (pagebreak Lua filter)", + "Repository": "CRAN", + "Date/Publication": "2023-03-26 22:00:03 UTC", + "Built": "R 4.3.0; ; 2023-05-15 19:16:40 UTC; unix" + } + }, + "sass": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "sass", + "Version": "0.4.6", + "Title": "Syntactically Awesome Style Sheets ('Sass')", + "Description": "An 'SCSS' compiler, powered by the 'LibSass' library. With this,\n R developers can use variables, inheritance, and functions to generate\n dynamic style sheets. The package uses the 'Sass CSS' extension language,\n which is stable, powerful, and CSS compatible.", + "Authors@R": "c(\n person(\"Joe\", \"Cheng\", , \"joe@rstudio.com\", \"aut\"),\n person(\"Timothy\", \"Mastny\", , \"tim.mastny@gmail.com\", \"aut\"),\n person(\"Richard\", \"Iannone\", , \"rich@rstudio.com\", \"aut\",\n comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Barret\", \"Schloerke\", , \"barret@rstudio.com\", \"aut\",\n comment = c(ORCID = \"0000-0001-9986-114X\")),\n person(\"Carson\", \"Sievert\", , \"carson@rstudio.com\", c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@rstudio.com\", c(\"ctb\"),\n comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(family = \"RStudio\", role = c(\"cph\", \"fnd\")),\n person(family = \"Sass Open Source Foundation\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Greter\", \"Marcel\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Mifsud\", \"Michael\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Hampton\", \"Catlin\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Natalie\", \"Weizenbaum\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Chris\", \"Eppstein\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Adams\", \"Joseph\", role = c(\"ctb\", \"cph\"),\n comment = \"json.cpp\"),\n person(\"Trifunovic\", \"Nemanja\", role = c(\"ctb\", \"cph\"),\n comment = \"utf8.h\")\n )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/sass/, https://github.com/rstudio/sass", + "BugReports": "https://github.com/rstudio/sass/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "GNU make", + "Imports": "fs, rlang (>= 0.4.10), htmltools (>= 0.5.1), R6, rappdirs", + "Suggests": "testthat, knitr, rmarkdown, withr, shiny, curl", + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Packaged": "2023-05-03 22:45:10 UTC; cpsievert", + "Author": "Joe Cheng [aut],\n Timothy Mastny [aut],\n Richard Iannone [aut] (),\n Barret Schloerke [aut] (),\n Carson Sievert [aut, cre] (),\n Christophe Dervieux [ctb] (),\n RStudio [cph, fnd],\n Sass Open Source Foundation [ctb, cph] (LibSass library),\n Greter Marcel [ctb, cph] (LibSass library),\n Mifsud Michael [ctb, cph] (LibSass library),\n Hampton Catlin [ctb, cph] (LibSass library),\n Natalie Weizenbaum [ctb, cph] (LibSass library),\n Chris Eppstein [ctb, cph] (LibSass library),\n Adams Joseph [ctb, cph] (json.cpp),\n Trifunovic Nemanja [ctb, cph] (utf8.h)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2023-05-03 23:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-05-04 04:35:51 UTC; unix", + "Archs": "sass.so.dSYM" + } + }, + "stringi": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "stringi", + "Version": "1.7.12", + "Date": "2023-01-09", + "Title": "Fast and Portable Character String Processing Facilities", + "Description": "A collection of character string/text/natural language\n processing tools for pattern searching (e.g., with 'Java'-like regular\n expressions or the 'Unicode' collation algorithm), random string generation,\n case mapping, string transliteration, concatenation, sorting, padding,\n wrapping, Unicode normalisation, date-time formatting and parsing,\n and many more. They are fast, consistent, convenient, and -\n thanks to 'ICU' (International Components for Unicode) -\n portable across all locales and platforms. Documentation about 'stringi' is\n provided via its website at and\n the paper by Gagolewski (2022, ).", + "URL": "https://stringi.gagolewski.com/,\nhttps://github.com/gagolews/stringi, https://icu.unicode.org/", + "BugReports": "https://github.com/gagolews/stringi/issues", + "SystemRequirements": "C++11, ICU4C (>= 55, optional)", + "Type": "Package", + "Depends": "R (>= 3.1)", + "Imports": "tools, utils, stats", + "Biarch": "TRUE", + "License": "file LICENSE", + "Author": "Marek Gagolewski [aut, cre, cph] (),\n Bartek Tartanus [ctb], and others (stringi source code);\n Unicode, Inc. and others (ICU4C source code, Unicode Character Database)", + "Maintainer": "Marek Gagolewski ", + "RoxygenNote": "7.2.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2023-01-09 07:28:38 UTC; gagolews", + "License_is_FOSS": "yes", + "Repository": "CRAN", + "Date/Publication": "2023-01-11 10:10:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:20:49 UTC; unix" + } + }, + "stringr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "stringr", + "Title": "Simple, Consistent Wrappers for Common String Operations", + "Version": "1.5.0", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = c(\"aut\", \"cre\", \"cph\"),\n email = \"hadley@rstudio.com\"),\n person(given = \"RStudio\",\n role = c(\"cph\", \"fnd\")))", + "Description": "A consistent, simple and easy to use set of wrappers around\n the fantastic 'stringi' package. All function and argument names (and\n positions) are consistent, all functions deal with \"NA\"'s and zero\n length vectors in the same way, and the output from one function is\n easy to feed into the input of another.", + "License": "MIT + file LICENSE", + "URL": "https://stringr.tidyverse.org,\nhttps://github.com/tidyverse/stringr", + "BugReports": "https://github.com/tidyverse/stringr/issues", + "Depends": "R (>= 3.3)", + "Imports": "cli, glue (>= 1.6.1), lifecycle (>= 1.0.3), magrittr, rlang\n(>= 1.0.0), stringi (>= 1.5.3), vctrs", + "Suggests": "covr, htmltools, htmlwidgets, knitr, rmarkdown, testthat (>=\n3.0.0)", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Packaged": "2022-12-01 20:53:42 UTC; hadleywickham", + "Author": "Hadley Wickham [aut, cre, cph],\n RStudio [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2022-12-02 10:20:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 12:50:56 UTC; unix" + } + }, + "tinytex": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "tinytex", + "Type": "Package", + "Title": "Helper Functions to Install and Maintain TeX Live, and Compile\nLaTeX Documents", + "Version": "0.45", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Devon\", \"Ryan\", role = \"ctb\", email = \"dpryan79@gmail.com\", comment = c(ORCID = \"0000-0002-8549-0971\")),\n person(\"Ethan\", \"Heinzen\", role = \"ctb\"),\n person(\"Fernando\", \"Cagua\", role = \"ctb\"),\n person()\n )", + "Description": "Helper functions to install and maintain the 'LaTeX' distribution\n named 'TinyTeX' (), a lightweight, cross-platform,\n portable, and easy-to-maintain version of 'TeX Live'. This package also\n contains helper functions to compile 'LaTeX' documents, and install missing\n 'LaTeX' packages automatically.", + "Imports": "xfun (>= 0.29)", + "Suggests": "testit, rstudioapi", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/tinytex", + "BugReports": "https://github.com/rstudio/tinytex/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2023-04-18 13:52:40 UTC; yihui", + "Author": "Yihui Xie [aut, cre, cph] (),\n Posit Software, PBC [cph, fnd],\n Christophe Dervieux [ctb] (),\n Devon Ryan [ctb] (),\n Ethan Heinzen [ctb],\n Fernando Cagua [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-04-18 14:30:07 UTC", + "Built": "R 4.3.0; ; 2023-04-22 00:31:32 UTC; unix" + } + }, + "vctrs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "vctrs", + "Title": "Vector Helpers", + "Version": "0.6.2", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"),\n person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"),\n person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")),\n person(\"data.table team\", role = \"cph\",\n comment = \"Radix sort based on data.table's forder() and their contribution to R's order()\"),\n person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Defines new notions of prototype and size that are used to\n provide tools for consistent and well-founded type-coercion and\n size-recycling, and are in turn connected to ideas of type- and\n size-stability useful for analysing function interfaces.", + "License": "MIT + file LICENSE", + "URL": "https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs", + "BugReports": "https://github.com/r-lib/vctrs/issues", + "Depends": "R (>= 3.5.0)", + "Imports": "cli (>= 3.4.0), glue, lifecycle (>= 1.0.3), rlang (>= 1.1.0)", + "Suggests": "bit64, covr, crayon, dplyr (>= 0.8.5), generics, knitr,\npillar (>= 1.4.4), pkgdown (>= 2.0.1), rmarkdown, testthat (>=\n3.0.0), tibble (>= 3.1.3), waldo (>= 0.2.0), withr, xml2,\nzeallot", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "Language": "en-GB", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Packaged": "2023-04-19 18:24:24 UTC; davis", + "Author": "Hadley Wickham [aut],\n Lionel Henry [aut],\n Davis Vaughan [aut, cre],\n data.table team [cph] (Radix sort based on data.table's forder() and\n their contribution to R's order()),\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN", + "Date/Publication": "2023-04-19 19:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-22 00:48:35 UTC; unix", + "Archs": "vctrs.so.dSYM" + } + }, + "xfun": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "xfun", + "Type": "Package", + "Title": "Supporting Functions for Packages Maintained by 'Yihui Xie'", + "Version": "0.39", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Wush\", \"Wu\", role = \"ctb\"),\n person(\"Daijiang\", \"Li\", role = \"ctb\"),\n person(\"Xianying\", \"Tan\", role = \"ctb\"),\n person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person()\n )", + "Description": "Miscellaneous functions commonly used in other packages maintained by 'Yihui Xie'.", + "Imports": "stats, tools", + "Suggests": "testit, parallel, codetools, rstudioapi, tinytex (>= 0.30),\nmime, markdown (>= 1.5), knitr (>= 1.42), htmltools, remotes,\npak, rhub, renv, curl, jsonlite, magick, yaml, rmarkdown", + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/xfun", + "BugReports": "https://github.com/yihui/xfun/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "VignetteBuilder": "knitr", + "NeedsCompilation": "yes", + "Packaged": "2023-04-19 22:17:10 UTC; yihui", + "Author": "Yihui Xie [aut, cre, cph] (),\n Wush Wu [ctb],\n Daijiang Li [ctb],\n Xianying Tan [ctb],\n Salim Brüggemann [ctb] (),\n Christophe Dervieux [ctb],\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-04-20 12:50:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-22 00:00:24 UTC; unix", + "Archs": "xfun.so.dSYM" + } + }, + "yaml": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "yaml", + "Type": "Package", + "Title": "Methods to Convert R Data to YAML and Back", + "Date": "2023-01-18", + "Version": "2.3.7", + "Suggests": "RUnit", + "Author": "Shawn P Garbett [aut], Jeremy Stephens [aut, cre], Kirill Simonov [aut], Yihui Xie [ctb],\n Zhuoer Dong [ctb], Hadley Wickham [ctb], Jeffrey Horner [ctb], reikoch [ctb],\n Will Beasley [ctb], Brendan O'Connor [ctb], Gregory R. Warnes [ctb],\n Michael Quinn [ctb], Zhian N. Kamvar [ctb]", + "Maintainer": "Shawn Garbett ", + "License": "BSD_3_clause + file LICENSE", + "Description": "Implements the 'libyaml' 'YAML' 1.1 parser and emitter\n () for R.", + "URL": "https://github.com/vubiostat/r-yaml/", + "BugReports": "https://github.com/vubiostat/r-yaml/issues", + "NeedsCompilation": "yes", + "Packaged": "2023-01-18 17:20:16 UTC; garbetsp", + "Repository": "CRAN", + "Date/Publication": "2023-01-23 18:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-08 21:18:13 UTC; unix", + "Archs": "yaml.so.dSYM" + } + } + }, + "files": { + "_site.yml": { + "checksum": "68b329da9893e34099c7d8ad5cb9c940" + }, + ".Rprofile": { + "checksum": "0b7556db576037033836dad462da03f7" + }, + "another.Rmd": { + "checksum": "3ff73b227b8d15e2b39172402234a0b6" + }, + "article.Rmd": { + "checksum": "c41a63e581ccf14e6e00ef8dab979765" + }, + "index.Rmd": { + "checksum": "c85dc46c45a93df8010830d238e4ff75" + }, + "meta.yaml": { + "checksum": "0824e67d283b321ee84d16fd194625d8" + } + }, + "users": null +} diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/meta.yaml b/internal/inspect/detectors/testdata/rmd-site-no-meta/meta.yaml new file mode 100644 index 000000000..21c54d290 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/meta.yaml @@ -0,0 +1,10 @@ +tags: + - provisioner + - r + - rmd + - site + - static + - dev-env + - small-dev-env + - regression + - all diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/renv.lock b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv.lock new file mode 100644 index 000000000..54fd9f537 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv.lock @@ -0,0 +1,398 @@ +{ + "R": { + "Version": "4.3.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://packagemanager.posit.co/cran/latest" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bslib": { + "Package": "bslib", + "Version": "0.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9" + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "c35768291560ce302c0a6589f92e837d" + }, + "cli": { + "Package": "cli", + "Version": "3.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + }, + "digest": { + "Package": "digest", + "Version": "0.6.35", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "rlang" + ], + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.22", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "66f39c7a21e03c4dcb2c2d21d738d603" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f7736a18de97dea803bde0a2daaafb27" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + }, + "fs": { + "Package": "fs", + "Version": "1.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" + }, + "glue": { + "Package": "glue", + "Version": "1.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "e0b3a53876554bd45879e596cdb10a52" + }, + "highr": { + "Package": "highr", + "Version": "0.10", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "06230136b2d2b9ba5805e1963fa6e890" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "ellipsis", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "a2326a66919a3311f7fbb1e3bf568283" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "e1b9c55281c5adc4dd113652d9e26768" + }, + "knitr": { + "Package": "knitr", + "Version": "1.44", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "60885b9f746c9dfaef110d070b5f7dc0" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "b8552d117e1b808b09a832f589b79035" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "7ce2733a9826b3aeb1775d56fd305472" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "renv": { + "Package": "renv", + "Version": "1.0.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "397b7b2a265bc5a7a06852524dabae20" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.25", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "stringr", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "d65e35823c817f09f4de424fcdfa812a" + }, + "sass": { + "Package": "sass", + "Version": "0.4.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "6bd4d33b50ff927191ec9acbf52fd056" + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stats", + "tools", + "utils" + ], + "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ], + "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.47", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "8d4ccb733843e513c1c1cdd66a759f0d" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "c03fa420630029418f7e6da3667aac4a" + }, + "xfun": { + "Package": "xfun", + "Version": "0.40", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "stats", + "tools" + ], + "Hash": "be07d23211245fc7d4209f54c4e4ffc8" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "29240487a071f535f5e5d5a323b7afbd" + } + } +} diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/.gitignore b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/.gitignore new file mode 100644 index 000000000..0ec0cbba2 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/activate.R b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/activate.R new file mode 100644 index 000000000..d13f9932a --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/activate.R @@ -0,0 +1,1220 @@ + +local({ + + # the requested version of renv + version <- "1.0.7" + attr(version, "sha") <- NULL + + # the project directory + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() + + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + + # figure out whether the autoloader is enabled + enabled <- local({ + + # first, check config option + override <- getOption("renv.config.autoloader.enabled") + if (!is.null(override)) + return(override) + + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + + # next, check environment variables + # TODO: prefer using the configuration one in the future + envvars <- c( + "RENV_CONFIG_AUTOLOADER_ENABLED", + "RENV_AUTOLOADER_ENABLED", + "RENV_ACTIVATE_PROJECT" + ) + + for (envvar in envvars) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(tolower(envval) %in% c("true", "t", "1")) + } + + # enable by default + TRUE + + }) + + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + + return(FALSE) + + } + + # avoid recursion + if (identical(getOption("renv.autoloader.running"), TRUE)) { + warning("ignoring recursive attempt to run renv autoloader") + return(invisible(TRUE)) + } + + # signal that we're loading renv during R startup + options(renv.autoloader.running = TRUE) + on.exit(options(renv.autoloader.running = NULL), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # unload renv if it's already been loaded + if ("renv" %in% loadedNamespaces()) + unloadNamespace("renv") + + # load bootstrap tools + `%||%` <- function(x, y) { + if (is.null(x)) y else x + } + + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + paste(substring(lines, common), collapse = "\n") + + } + + startswith <- function(string, prefix) { + substring(string, 1, nchar(prefix)) == prefix + } + + bootstrap <- function(version, library) { + + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + + # attempt to download renv + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) + + # now attempt to install + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + + return(invisible()) + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # get CRAN repository + cran <- getOption("renv.repos.cran", "https://cloud.r-project.org") + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) { + + # check for RSPM; if set, use a fallback repository for renv + rspm <- Sys.getenv("RSPM", unset = NA) + if (identical(rspm, repos)) + repos <- c(RSPM = rspm, CRAN = cran) + + return(repos) + + } + + # check for lockfile repositories + repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) + if (!inherits(repos, "error") && length(repos)) + return(repos) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- cran + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_repos_lockfile <- function() { + + lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") + if (!file.exists(lockpath)) + return(NULL) + + lockfile <- tryCatch(renv_json_read(lockpath), error = identity) + if (inherits(lockfile, "error")) { + warning(lockfile) + return(NULL) + } + + repos <- lockfile$R$Repositories + if (length(repos) == 0) + return(NULL) + + keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) + vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) + names(vals) <- keys + + return(vals) + + } + + renv_bootstrap_download <- function(version) { + + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) + ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } + + for (method in methods) { + path <- tryCatch(method(), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("All download methods failed") + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + args <- list( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos + + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") + + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (inherits(status, "condition")) + return(FALSE) + + # report success and return + destfile + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # retrieve package database + db <- tryCatch( + as.data.frame( + utils::available.packages(type = type, repos = repos), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) + return(destfile) + + } + + return(FALSE) + + } + + renv_bootstrap_download_tarball <- function(version) { + + # if the user has provided the path to a tarball via + # an environment variable, then use it + tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) + if (is.na(tarball)) + return() + + # allow directories + if (dir.exists(tarball)) { + name <- sprintf("renv_%s.tar.gz", version) + tarball <- file.path(tarball, name) + } + + # bail if it doesn't exist + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail + return() + + } + + catf("- Using local tarball '%s'.", tarball) + tarball + + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + pat <- Sys.getenv("GITHUB_PAT") + if (nzchar(Sys.which("curl")) && nzchar(pat)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) + return(FALSE) + + renv_bootstrap_download_augment(destfile) + + return(destfile) + + } + + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + R <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + system2(R, args, stdout = TRUE, stderr = TRUE) + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version, description = NULL) { + + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") + + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) + else + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + else + paste("renv", description[["Version"]], sep = "@") + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = if (dev) description[["RemoteSha"]] + ) + + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) + + FALSE + + } + + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # execute renv load hooks, if any + hooks <- getHook("renv::autoload") + for (hook in hooks) + if (is.function(hook)) + tryCatch(hook(), error = warnify) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + renv_json_read <- function(file = NULL, text = NULL) { + + jlerr <- NULL + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) { + + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + jlerr <- json + + } + + # otherwise, fall back to the default JSON reader + json <- tryCatch(renv_json_read_default(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + # report an error + if (!is.null(jlerr)) + stop(jlerr) + else + stop(json) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # find strings in the JSON + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + + # if any are found, replace them with placeholders + replaced <- text + strings <- character() + replacements <- character() + + if (!identical(c(locs), -1L)) { + + # get the string values + starts <- locs + ends <- locs + attr(locs, "match.length") - 1L + strings <- substring(text, starts, ends) + + # only keep those requiring escaping + strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + + # compute replacements + replacements <- sprintf('"\032%i\032"', seq_along(strings)) + + # replace the strings + mapply(function(string, replacement) { + replaced <<- sub(string, replacement, replaced, fixed = TRUE) + }, strings, replacements) + + } + + # transform the JSON into something the R parser understands + transformed <- replaced + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) + transformed <- gsub(":", "=", transformed, fixed = TRUE) + text <- paste(transformed, collapse = "\n") + + # parse it + json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + + # construct map between source strings, replaced strings + map <- as.character(parse(text = strings)) + names(map) <- as.character(parse(text = replacements)) + + # convert to list + map <- as.list(map) + + # remap strings in object + remapped <- renv_json_read_remap(json, map) + + # evaluate + eval(remapped, envir = baseenv()) + + } + + renv_json_read_remap <- function(json, map) { + + # fix names + if (!is.null(names(json))) { + lhs <- match(names(json), names(map), nomatch = 0L) + rhs <- match(names(map), names(json), nomatch = 0L) + names(json)[rhs] <- map[lhs] + } + + # fix values + if (is.character(json)) + return(map[[json]] %||% json) + + # handle true, false, null + if (is.name(json)) { + text <- as.character(json) + if (text == "true") + return(TRUE) + else if (text == "false") + return(FALSE) + else if (text == "null") + return(NULL) + } + + # recurse + if (is.recursive(json)) { + for (i in seq_along(json)) { + json[i] <- list(renv_json_read_remap(json[[i]], map)) + } + } + + json + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) + + invisible() + +}) diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/settings.json b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/settings.json new file mode 100644 index 000000000..d5590a960 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/renv/settings.json @@ -0,0 +1,15 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [], + "package.dependency.fields": ["Imports", "Depends", "LinkingTo"], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "implicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/internal/inspect/detectors/testdata/rmd-site-no-meta/rmd-site.Rproj b/internal/inspect/detectors/testdata/rmd-site-no-meta/rmd-site.Rproj new file mode 100644 index 000000000..827cca17d --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site-no-meta/rmd-site.Rproj @@ -0,0 +1,15 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Website diff --git a/internal/inspect/detectors/testdata/rmd-site/_site.yml b/internal/inspect/detectors/testdata/rmd-site/_site.yml new file mode 100644 index 000000000..e69de29bb diff --git a/internal/inspect/detectors/testdata/rmd-site/another.Rmd b/internal/inspect/detectors/testdata/rmd-site/another.Rmd new file mode 100644 index 000000000..9dd657a91 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/another.Rmd @@ -0,0 +1,3 @@ +# Another + +Here is another page. It links to [index](index.html) and [article](article.html). diff --git a/internal/inspect/detectors/testdata/rmd-site/article.Rmd b/internal/inspect/detectors/testdata/rmd-site/article.Rmd new file mode 100644 index 000000000..138030660 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/article.Rmd @@ -0,0 +1,3 @@ +# Article + +This is an article. It has a link to [index](index.html) and [another](another.html). diff --git a/internal/inspect/detectors/testdata/rmd-site/images/mario-jump.gif b/internal/inspect/detectors/testdata/rmd-site/images/mario-jump.gif new file mode 100644 index 000000000..230986665 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/images/mario-jump.gif differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index.Rmd b/internal/inspect/detectors/testdata/rmd-site/index.Rmd new file mode 100644 index 000000000..039cede7e --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/index.Rmd @@ -0,0 +1,31 @@ +--- +title: "Testing RMD Site" +--- + +# R Markdown site + +This is the index page. It has a link to [article](article.html) and [another](another.html). + +### A huge plot (scatter plot matrix) + +One disadvantage of `recordPlot()` is that it may not be able to record huge plots due to memory limits, e.g. a scatter plot matrix of tens of thousands of points: + +```{r gen-data, cache=TRUE} +# generate some random data +dat = matrix(runif(100000), ncol=5) +dat[, 3] = -.2 * dat[, 1] + .8 * dat[, 2] # to make the plot less boring +pairs(dat) +``` + +But scatter plots with such a large number of points are usually difficult to read (basically you can see nothing), so we'd better use some alternative ways to visualize them. For example, we can use 2D density estimates and draw contour plots, or just plot the LOWESS curve. + +```{r line-contour, cache=TRUE, dependson='gen-data'} +dens2d = function(x, y, ...) { + library(MASS) + res = kde2d(x, y) + with(res, contour(x, y, z, add = TRUE)) +} +pairs(dat, lower.panel = dens2d, upper.panel = function(x, y, ...) { + lines(lowess(y ~ x), col = 'red') +}) +``` diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/__packages b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/__packages new file mode 100644 index 000000000..4ce32c819 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/__packages @@ -0,0 +1 @@ +MASS diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.RData b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.RData new file mode 100644 index 000000000..dfb01c982 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.RData differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdb b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdb new file mode 100644 index 000000000..872519e5c Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdb differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdx b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdx new file mode 100644 index 000000000..ae033d825 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/gen-data_24ff9b2ac5ea45d04d93bc5a7ed5a20f.rdx differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.RData b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.RData new file mode 100644 index 000000000..a1cd6a527 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.RData differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdb b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdb new file mode 100644 index 000000000..ec4ed4056 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdb differ diff --git a/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdx b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdx new file mode 100644 index 000000000..841289e93 Binary files /dev/null and b/internal/inspect/detectors/testdata/rmd-site/index_cache/html/line-contour_c27bf36805d32a6a394e99ac4056f616.rdx differ diff --git a/internal/inspect/detectors/testdata/rmd-site/manifest.json b/internal/inspect/detectors/testdata/rmd-site/manifest.json new file mode 100644 index 000000000..0e2aa6cc8 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/manifest.json @@ -0,0 +1,908 @@ +{ + "version": 1, + "locale": "en_US", + "platform": "4.3.0", + "metadata": { + "appmode": "rmd-static", + "primary_rmd": "index.Rmd", + "primary_html": null, + "content_category": "site", + "has_parameters": false + }, + "packages": { + "R6": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "R6", + "Title": "Encapsulated Classes with Reference Semantics", + "Version": "2.5.1", + "Authors@R": "person(\"Winston\", \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@stdout.org\")", + "Description": "Creates classes with reference semantics, similar to R's built-in\n reference classes. Compared to reference classes, R6 classes are simpler\n and lighter-weight, and they are not built on S4 classes so they do not\n require the methods package. These classes allow public and private\n members, and they support inheritance, even when the classes are defined in\n different packages.", + "Depends": "R (>= 3.0)", + "Suggests": "testthat, pryr", + "License": "MIT + file LICENSE", + "URL": "https://r6.r-lib.org, https://github.com/r-lib/R6/", + "BugReports": "https://github.com/r-lib/R6/issues", + "RoxygenNote": "7.1.1", + "NeedsCompilation": "no", + "Packaged": "2021-08-06 20:18:46 UTC; winston", + "Author": "Winston Chang [aut, cre]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2021-08-19 14:00:05 UTC", + "Built": "R 4.3.0; ; 2023-04-11 20:07:58 UTC; unix" + } + }, + "base64enc": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "base64enc", + "Version": "0.1-3", + "Title": "Tools for base64 encoding", + "Author": "Simon Urbanek ", + "Maintainer": "Simon Urbanek ", + "Depends": "R (>= 2.9.0)", + "Enhances": "png", + "Description": "This package provides tools for handling base64 encoding. It is more flexible than the orphaned base64 package.", + "License": "GPL-2 | GPL-3", + "URL": "http://www.rforge.net/base64enc", + "NeedsCompilation": "yes", + "Packaged": "2015-02-04 20:31:00 UTC; svnuser", + "Repository": "CRAN", + "Date/Publication": "2015-07-28 08:03:37", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:42 UTC; unix", + "Archs": "base64enc.so.dSYM" + } + }, + "bslib": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "bslib", + "Title": "Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'", + "Version": "0.4.2", + "Authors@R": "c(\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\"),\n person(family = \"Bootstrap contributors\", role = \"ctb\",\n comment = \"Bootstrap library\"),\n person(family = \"Twitter, Inc\", role = \"cph\",\n comment = \"Bootstrap library\"),\n person(\"Javi\", \"Aguilar\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootstrap colorpicker library\"),\n person(\"Thomas\", \"Park\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootswatch library\"),\n person(family = \"PayPal\", role = c(\"ctb\", \"cph\"),\n comment = \"Bootstrap accessibility plugin\")\n )", + "Description": "Simplifies custom 'CSS' styling of both 'shiny' and 'rmarkdown' via 'Bootstrap' 'Sass'. Supports 'Bootstrap' 3, 4 and 5 as well as their various 'Bootswatch' themes. An interactive widget is also provided for previewing themes in real time.", + "Depends": "R (>= 2.10)", + "Imports": "grDevices, htmltools (>= 0.5.4), jsonlite, sass (>= 0.4.0),\njquerylib (>= 0.1.3), rlang, cachem, memoise (>= 2.0.1),\nbase64enc, mime", + "Suggests": "shiny (>= 1.6.0), rmarkdown (>= 2.7), thematic, knitr,\ntestthat, withr, rappdirs, curl, magrittr, fontawesome, bsicons", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Collate": "'bootswatch.R' 'bs-current-theme.R' 'bs-dependencies.R'\n'bs-global.R' 'bs-remove.R' 'bs-theme-layers.R' 'utils.R'\n'bs-theme-preview.R' 'bs-theme-update.R' 'bs-theme.R' 'card.R'\n'deprecated.R' 'files.R' 'imports.R' 'layout.R' 'nav-items.R'\n'nav-update.R' 'navs-legacy.R' 'navs.R' 'onLoad.R' 'page.R'\n'precompiled.R' 'print.R' 'shiny-devmode.R' 'staticimports.R'\n'utils-shiny.R' 'utils-tags.R' 'value-box.R'\n'version-default.R' 'versions.R'", + "URL": "https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib", + "BugReports": "https://github.com/rstudio/bslib/issues", + "Config/testthat/edition": "3", + "Config/Needs/routine": "desc, renv", + "Config/Needs/website": "brio, dplyr, glue, purrr, rprojroot, stringr,\ntidyr, DT, leaflet, plotly, htmlwidgets, shiny, ggplot2,\nsvglite", + "Config/Needs/deploy": "BH, DT, ggplot2, hexbin, lattice, lubridate,\ndplyr, modelr, nycflights13, histoslider, reactable, rprojroot,\nrsconnect, plotly, leaflet, gt, shiny, htmlwidgets", + "NeedsCompilation": "no", + "Packaged": "2022-12-15 16:02:29 UTC; cpsievert", + "Author": "Carson Sievert [aut, cre] (),\n Joe Cheng [aut],\n RStudio [cph],\n Bootstrap contributors [ctb] (Bootstrap library),\n Twitter, Inc [cph] (Bootstrap library),\n Javi Aguilar [ctb, cph] (Bootstrap colorpicker library),\n Thomas Park [ctb, cph] (Bootswatch library),\n PayPal [ctb, cph] (Bootstrap accessibility plugin)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2022-12-16 10:30:06 UTC", + "Built": "R 4.3.0; ; 2023-04-17 22:45:58 UTC; unix" + } + }, + "cachem": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "cachem", + "Version": "1.0.8", + "Title": "Cache R Objects with Automatic Pruning", + "Description": "Key-value stores with automatic pruning. Caches can limit\n either their total size or the age of the oldest object (or both),\n automatically pruning objects to maintain the constraints.", + "Authors@R": "c(\n person(\"Winston\", \"Chang\", , \"winston@rstudio.com\", c(\"aut\", \"cre\")),\n person(family = \"RStudio\", role = c(\"cph\", \"fnd\")))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "ByteCompile": "true", + "URL": "https://cachem.r-lib.org/, https://github.com/r-lib/cachem", + "Imports": "rlang, fastmap (>= 1.1.1)", + "Suggests": "testthat", + "RoxygenNote": "7.2.3", + "Config/Needs/routine": "lobstr", + "Config/Needs/website": "pkgdown", + "NeedsCompilation": "yes", + "Packaged": "2023-05-01 15:38:38 UTC; winston", + "Author": "Winston Chang [aut, cre],\n RStudio [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2023-05-01 16:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-05-03 23:25:36 UTC; unix", + "Archs": "cachem.so.dSYM" + } + }, + "cli": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "cli", + "Title": "Helpers for Developing Command Line Interfaces", + "Version": "3.6.1", + "Authors@R": "c(\n person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", role = \"ctb\"),\n person(\"Kirill\", \"Müller\", role = \"ctb\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "A suite of tools to build attractive command line interfaces\n ('CLIs'), from semantic elements: headings, lists, alerts, paragraphs,\n etc. Supports custom themes via a 'CSS'-like language. It also\n contains a number of lower level 'CLI' elements: rules, boxes, trees,\n and 'Unicode' symbols with 'ASCII' alternatives. It support ANSI\n colors and text styles as well.", + "License": "MIT + file LICENSE", + "URL": "https://cli.r-lib.org, https://github.com/r-lib/cli#readme", + "BugReports": "https://github.com/r-lib/cli/issues", + "Depends": "R (>= 3.4)", + "Imports": "utils", + "Suggests": "callr, covr, crayon, digest, glue (>= 1.6.0), grDevices,\nhtmltools, htmlwidgets, knitr, methods, mockery, processx, ps\n(>= 1.3.4.9000), rlang (>= 1.0.2.9003), rmarkdown, rprojroot,\nrstudioapi, testthat, tibble, whoami, withr", + "Config/Needs/website": "r-lib/asciicast, bench, brio, cpp11, decor, desc,\nfansi, prettyunits, sessioninfo, tidyverse/tidytemplate,\nusethis, vctrs", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1.9000", + "NeedsCompilation": "yes", + "Packaged": "2023-03-22 13:59:32 UTC; gaborcsardi", + "Author": "Gábor Csárdi [aut, cre],\n Hadley Wickham [ctb],\n Kirill Müller [ctb],\n RStudio [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN", + "Date/Publication": "2023-03-23 12:52:05 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:08:33 UTC; unix", + "Archs": "cli.so.dSYM" + } + }, + "digest": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "digest", + "Author": "Dirk Eddelbuettel with contributions\n by Antoine Lucas, Jarek Tuszynski, Henrik Bengtsson, Simon Urbanek,\n Mario Frasca, Bryan Lewis, Murray Stokely, Hannes Muehleisen,\n Duncan Murdoch, Jim Hester, Wush Wu, Qiang Kou, Thierry Onkelinx,\n Michel Lang, Viliam Simko, Kurt Hornik, Radford Neal, Kendon Bell,\n Matthew de Queljoe, Ion Suruceanu, Bill Denney, Dirk Schumacher,\n and Winston Chang.", + "Version": "0.6.31", + "Date": "2022-12-10", + "Maintainer": "Dirk Eddelbuettel ", + "Title": "Create Compact Hash Digests of R Objects", + "Description": "Implementation of a function 'digest()' for the creation of hash\n digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32',\n 'xxhash', 'murmurhash', 'spookyhash' and 'blake3' algorithms) permitting easy\n comparison of R language objects, as well as functions such as'hmac()' to\n create hash-based message authentication code. Please note that this package\n is not meant to be deployed for cryptographic purposes for which more\n comprehensive (and widely tested) libraries such as 'OpenSSL' should be\n used.", + "URL": "https://github.com/eddelbuettel/digest,\nhttp://dirk.eddelbuettel.com/code/digest.html", + "BugReports": "https://github.com/eddelbuettel/digest/issues", + "Depends": "R (>= 3.3.0)", + "Imports": "utils", + "License": "GPL (>= 2)", + "Suggests": "tinytest, simplermarkdown", + "VignetteBuilder": "simplermarkdown", + "NeedsCompilation": "yes", + "Packaged": "2022-12-10 18:30:14 UTC; edd", + "Repository": "CRAN", + "Date/Publication": "2022-12-11 07:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:54 UTC; unix", + "Archs": "digest.so.dSYM" + } + }, + "ellipsis": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "ellipsis", + "Version": "0.3.2", + "Title": "Tools for Working with ...", + "Description": "The ellipsis is a powerful tool for extending functions. Unfortunately \n this power comes at a cost: misspelled arguments will be silently ignored. \n The ellipsis package provides a collection of functions to catch problems\n and alert the user.", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(\"RStudio\", role = \"cph\")\n )", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "URL": "https://ellipsis.r-lib.org, https://github.com/r-lib/ellipsis", + "BugReports": "https://github.com/r-lib/ellipsis/issues", + "Depends": "R (>= 3.2)", + "Imports": "rlang (>= 0.3.0)", + "Suggests": "covr, testthat", + "NeedsCompilation": "yes", + "Packaged": "2021-04-29 12:06:44 UTC; lionel", + "Author": "Hadley Wickham [aut, cre],\n RStudio [cph]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2021-04-29 12:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:17:48 UTC; unix", + "Archs": "ellipsis.so.dSYM" + } + }, + "evaluate": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "evaluate", + "Type": "Package", + "Title": "Parsing and Evaluation Tools that Provide More Details than the\nDefault", + "Version": "0.21", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", role = \"aut\"),\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Michael\", \"Lawrence\", role = \"ctb\"),\n person(\"Thomas\", \"Kluyver\", role = \"ctb\"),\n person(\"Jeroen\", \"Ooms\", role = \"ctb\"),\n person(\"Barret\", \"Schloerke\", role = \"ctb\"),\n person(\"Adam\", \"Ryczkowski\", role = \"ctb\"),\n person(\"Hiroaki\", \"Yutani\", role = \"ctb\"),\n person(\"Michel\", \"Lang\", role = \"ctb\"),\n person(\"Karolis\", \"Koncevičius\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Parsing and evaluation tools that make it easy to recreate the\n command line behaviour of R.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/evaluate", + "BugReports": "https://github.com/r-lib/evaluate/issues", + "Depends": "R (>= 3.0.2)", + "Imports": "methods", + "Suggests": "covr, ggplot2, lattice, rlang, testthat (>= 3.0.0), withr", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Packaged": "2023-05-01 21:56:45 UTC; yihui", + "Author": "Hadley Wickham [aut],\n Yihui Xie [aut, cre] (),\n Michael Lawrence [ctb],\n Thomas Kluyver [ctb],\n Jeroen Ooms [ctb],\n Barret Schloerke [ctb],\n Adam Ryczkowski [ctb],\n Hiroaki Yutani [ctb],\n Michel Lang [ctb],\n Karolis Koncevičius [ctb],\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-05-05 23:30:02 UTC", + "Built": "R 4.3.0; ; 2023-05-05 23:40:19 UTC; unix" + } + }, + "fastmap": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "fastmap", + "Title": "Fast Data Structures", + "Version": "1.1.1", + "Authors@R": "c(\n person(\"Winston\", \"Chang\", email = \"winston@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(given = \"RStudio\", role = c(\"cph\", \"fnd\")),\n person(given = \"Tessil\", role = \"cph\", comment = \"hopscotch_map library\")\n )", + "Description": "Fast implementation of data structures, including a key-value\n store, stack, and queue. Environments are commonly used as key-value stores\n in R, but every time a new key is used, it is added to R's global symbol\n table, causing a small amount of memory leakage. This can be problematic in\n cases where many different keys are used. Fastmap avoids this memory leak\n issue by implementing the map using data structures in C++.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Suggests": "testthat (>= 2.1.1)", + "URL": "https://r-lib.github.io/fastmap/, https://github.com/r-lib/fastmap", + "BugReports": "https://github.com/r-lib/fastmap/issues", + "NeedsCompilation": "yes", + "Packaged": "2023-02-24 16:01:27 UTC; winston", + "Author": "Winston Chang [aut, cre],\n RStudio [cph, fnd],\n Tessil [cph] (hopscotch_map library)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2023-02-24 16:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:53 UTC; unix", + "Archs": "fastmap.so.dSYM" + } + }, + "fontawesome": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "fontawesome", + "Version": "0.5.1", + "Title": "Easily Work with 'Font Awesome' Icons", + "Description": "Easily and flexibly insert 'Font Awesome' icons into 'R Markdown'\n documents and 'Shiny' apps. These icons can be inserted into HTML content\n through inline 'SVG' tags or 'i' tags. There is also a utility function for\n exporting 'Font Awesome' icons as 'PNG' images for those situations where\n raster graphics are needed.", + "Authors@R": "c(\n person(\"Richard\", \"Iannone\", , \"rich@posit.co\", c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"ctb\",\n comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"ctb\"),\n person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"),\n comment = \"Font-Awesome font\"),\n person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/fontawesome,\nhttps://rstudio.github.io/fontawesome/", + "BugReports": "https://github.com/rstudio/fontawesome/issues", + "Encoding": "UTF-8", + "ByteCompile": "true", + "RoxygenNote": "7.2.3", + "Depends": "R (>= 3.3.0)", + "Imports": "rlang (>= 1.0.6), htmltools (>= 0.5.1.1)", + "Suggests": "covr, dplyr (>= 1.0.8), knitr (>= 1.31), testthat (>= 3.0.0),\nrsvg", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Packaged": "2023-04-18 17:20:05 UTC; rich", + "Author": "Richard Iannone [aut, cre] (),\n Christophe Dervieux [ctb] (),\n Winston Chang [ctb],\n Dave Gandy [ctb, cph] (Font-Awesome font),\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN", + "Date/Publication": "2023-04-18 20:30:02 UTC", + "Built": "R 4.3.0; ; 2023-04-22 00:45:59 UTC; unix" + } + }, + "fs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "fs", + "Title": "Cross-Platform File System Operations Based on 'libuv'", + "Version": "1.6.2", + "Authors@R": "c(\n person(\"Jim\", \"Hester\", role = \"aut\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"),\n person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")),\n person(\"libuv project contributors\", role = \"cph\",\n comment = \"libuv library\"),\n person(\"Joyent, Inc. and other Node contributors\", role = \"cph\",\n comment = \"libuv library\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "A cross-platform interface to file system operations, built\n on top of the 'libuv' C library.", + "License": "MIT + file LICENSE", + "URL": "https://fs.r-lib.org, https://github.com/r-lib/fs,\nhttps://fs.r-lib.org/", + "BugReports": "https://github.com/r-lib/fs/issues", + "Depends": "R (>= 3.4)", + "Imports": "methods", + "Suggests": "covr, crayon, knitr, pillar (>= 1.0.0), rmarkdown, spelling,\ntestthat (>= 3.0.0), tibble (>= 1.1.0), vctrs (>= 0.3.0), withr", + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.1.2", + "SystemRequirements": "GNU make", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Packaged": "2023-04-24 13:43:26 UTC; gaborcsardi", + "Author": "Jim Hester [aut],\n Hadley Wickham [aut],\n Gábor Csárdi [aut, cre],\n libuv project contributors [cph] (libuv library),\n Joyent, Inc. and other Node contributors [cph] (libuv library),\n RStudio [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN", + "Date/Publication": "2023-04-25 08:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-30 06:45:54 UTC; unix", + "Archs": "fs.so.dSYM" + } + }, + "glue": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "glue", + "Title": "Interpreted String Literals", + "Version": "1.6.2", + "Authors@R": "c(\n person(\"Jim\", \"Hester\", role = \"aut\",\n comment = c(ORCID = \"0000-0002-2739-7082\")),\n person(\"Jennifer\", \"Bryan\", , \"jenny@rstudio.com\", role = c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0002-6983-2759\")),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "An implementation of interpreted string literals, inspired by\n Python's Literal String Interpolation\n and Docstrings\n and Julia's Triple-Quoted\n String Literals\n .", + "License": "MIT + file LICENSE", + "URL": "https://github.com/tidyverse/glue, https://glue.tidyverse.org/", + "BugReports": "https://github.com/tidyverse/glue/issues", + "Depends": "R (>= 3.4)", + "Imports": "methods", + "Suggests": "covr, crayon, DBI, dplyr, forcats, ggplot2, knitr, magrittr,\nmicrobenchmark, R.utils, rmarkdown, rprintf, RSQLite, stringr,\ntestthat (>= 3.0.0), vctrs (>= 0.3.0), waldo (>= 0.3.0), withr", + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "hadley/emo, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Packaged": "2022-02-23 22:50:40 UTC; jenny", + "Author": "Jim Hester [aut] (),\n Jennifer Bryan [aut, cre] (),\n RStudio [cph, fnd]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN", + "Date/Publication": "2022-02-24 07:50:20 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:07:27 UTC; unix", + "Archs": "glue.so.dSYM" + } + }, + "highr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "highr", + "Type": "Package", + "Title": "Syntax Highlighting for R Source Code", + "Version": "0.10", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Yixuan\", \"Qiu\", role = \"aut\"),\n person(\"Christopher\", \"Gandrud\", role = \"ctb\"),\n person(\"Qiang\", \"Li\", role = \"ctb\")\n )", + "Description": "Provides syntax highlighting for R source code. Currently it\n supports LaTeX and HTML output. Source code of other languages is supported\n via Andre Simon's highlight package ().", + "Depends": "R (>= 3.3.0)", + "Imports": "xfun (>= 0.18)", + "Suggests": "knitr, markdown, testit", + "License": "GPL", + "URL": "https://github.com/yihui/highr", + "BugReports": "https://github.com/yihui/highr/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2022-12-22 06:43:07 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Yixuan Qiu [aut],\n Christopher Gandrud [ctb],\n Qiang Li [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2022-12-22 07:00:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 06:44:58 UTC; unix" + } + }, + "htmltools": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "htmltools", + "Type": "Package", + "Title": "Tools for HTML", + "Version": "0.5.5", + "Authors@R": "c(\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Barret\", \"Schloerke\", role = \"aut\", email = \"barret@rstudio.com\", comment = c(ORCID = \"0000-0001-9986-114X\")),\n person(\"Winston\", \"Chang\", role = \"aut\", email = \"winston@rstudio.com\", comment = c(ORCID = \"0000-0002-1576-2126\")),\n person(\"Yihui\", \"Xie\", role = \"aut\", email = \"yihui@rstudio.com\"),\n person(\"Jeff\", \"Allen\", role = \"aut\", email = \"jeff@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\")\n )", + "Description": "Tools for HTML generation and output.", + "Depends": "R (>= 2.14.1)", + "Imports": "utils, digest, grDevices, base64enc, rlang (>= 0.4.10),\nfastmap (>= 1.1.0), ellipsis", + "Suggests": "markdown, testthat, withr, Cairo, ragg, shiny", + "Enhances": "knitr", + "License": "GPL (>= 2)", + "URL": "https://github.com/rstudio/htmltools,\nhttps://rstudio.github.io/htmltools/", + "BugReports": "https://github.com/rstudio/htmltools/issues", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "Collate": "'colors.R' 'fill.R' 'html_dependency.R' 'html_escape.R'\n'html_print.R' 'images.R' 'known_tags.R' 'selector.R'\n'staticimports.R' 'tag_query.R' 'utils.R' 'tags.R' 'template.R'", + "Config/Needs/website": "rstudio/quillt, bench", + "NeedsCompilation": "yes", + "Packaged": "2023-03-22 22:59:42 UTC; cpsievert", + "Author": "Joe Cheng [aut],\n Carson Sievert [aut, cre] (),\n Barret Schloerke [aut] (),\n Winston Chang [aut] (),\n Yihui Xie [aut],\n Jeff Allen [aut],\n RStudio [cph]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2023-03-23 09:50:06 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-12 06:43:49 UTC; unix", + "Archs": "htmltools.so.dSYM" + } + }, + "jquerylib": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "jquerylib", + "Title": "Obtain 'jQuery' as an HTML Dependency Object", + "Version": "0.1.4", + "Authors@R": "c(\n person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"),\n person(family = \"RStudio\", role = \"cph\"),\n person(family = \"jQuery Foundation\", role = \"cph\",\n comment = \"jQuery library and jQuery UI library\"),\n person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"),\n comment = \"jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt\")\n )", + "Description": "Obtain any major version of 'jQuery' () and use it in any webpage generated by 'htmltools' (e.g. 'shiny', 'htmlwidgets', and 'rmarkdown').\n Most R users don't need to use this package directly, but other R packages (e.g. 'shiny', 'rmarkdown', etc.) depend on this package to avoid bundling redundant copies of 'jQuery'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "RoxygenNote": "7.0.2", + "Imports": "htmltools", + "Suggests": "testthat", + "NeedsCompilation": "no", + "Packaged": "2021-04-26 16:40:21 UTC; cpsievert", + "Author": "Carson Sievert [aut, cre] (),\n Joe Cheng [aut],\n RStudio [cph],\n jQuery Foundation [cph] (jQuery library and jQuery UI library),\n jQuery contributors [ctb, cph] (jQuery library; authors listed in\n inst/lib/jquery-AUTHORS.txt)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2021-04-26 17:10:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 11:15:31 UTC; unix" + } + }, + "jsonlite": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "jsonlite", + "Version": "1.8.4", + "Title": "A Simple and Robust JSON Parser and Generator for R", + "License": "MIT + file LICENSE", + "Depends": "methods", + "Authors@R": "c(\n person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroen@berkeley.edu\",\n comment = c(ORCID = \"0000-0002-4035-0289\")),\n person(\"Duncan\", \"Temple Lang\", role = \"ctb\"),\n person(\"Lloyd\", \"Hilaiel\", role = \"cph\", comment=\"author of bundled libyajl\"))", + "URL": "https://arxiv.org/abs/1403.2805 (paper)", + "BugReports": "https://github.com/jeroen/jsonlite/issues", + "Maintainer": "Jeroen Ooms ", + "VignetteBuilder": "knitr, R.rsp", + "Description": "A reasonably fast JSON parser and generator, optimized for statistical \n data and the web. Offers simple, flexible tools for working with JSON in R, and\n is particularly powerful for building pipelines and interacting with a web API. \n The implementation is based on the mapping described in the vignette (Ooms, 2014).\n In addition to converting JSON data from/to R objects, 'jsonlite' contains \n functions to stream, validate, and prettify JSON data. The unit tests included \n with the package verify that all edge cases are encoded and decoded consistently \n for use with dynamic data in systems and applications.", + "Suggests": "httr, vctrs, testthat, knitr, rmarkdown, R.rsp, sf", + "RoxygenNote": "7.2.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2022-12-05 23:21:23 UTC; jeroen", + "Author": "Jeroen Ooms [aut, cre] (),\n Duncan Temple Lang [ctb],\n Lloyd Hilaiel [cph] (author of bundled libyajl)", + "Repository": "CRAN", + "Date/Publication": "2022-12-06 08:10:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:18:22 UTC; unix", + "Archs": "jsonlite.so.dSYM" + } + }, + "knitr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "knitr", + "Type": "Package", + "Title": "A General-Purpose Package for Dynamic Report Generation in R", + "Version": "1.42", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Abhraneel\", \"Sarma\", role = \"ctb\"),\n person(\"Adam\", \"Vogt\", role = \"ctb\"),\n person(\"Alastair\", \"Andrew\", role = \"ctb\"),\n person(\"Alex\", \"Zvoleff\", role = \"ctb\"),\n person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"),\n person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"),\n person(\"Aron\", \"Atkins\", role = \"ctb\"),\n person(\"Aaron\", \"Wolen\", role = \"ctb\"),\n person(\"Ashley\", \"Manton\", role = \"ctb\"),\n person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")),\n person(\"Ben\", \"Baumer\", role = \"ctb\"),\n person(\"Brian\", \"Diggs\", role = \"ctb\"),\n person(\"Brian\", \"Zhang\", role = \"ctb\"),\n person(\"Bulat\", \"Yapparov\", role = \"ctb\"),\n person(\"Cassio\", \"Pereira\", role = \"ctb\"),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\"),\n person(\"David\", \"Hall\", role = \"ctb\"),\n person(\"David\", \"Hugh-Jones\", role = \"ctb\"),\n person(\"David\", \"Robinson\", role = \"ctb\"),\n person(\"Doug\", \"Hemken\", role = \"ctb\"),\n person(\"Duncan\", \"Murdoch\", role = \"ctb\"),\n person(\"Elio\", \"Campitelli\", role = \"ctb\"),\n person(\"Ellis\", \"Hughes\", role = \"ctb\"),\n person(\"Emily\", \"Riederer\", role = \"ctb\"),\n person(\"Fabian\", \"Hirschmann\", role = \"ctb\"),\n person(\"Fitch\", \"Simeon\", role = \"ctb\"),\n person(\"Forest\", \"Fang\", role = \"ctb\"),\n person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"),\n person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"),\n person(\"Gregoire\", \"Detrez\", role = \"ctb\"),\n person(\"Hadley\", \"Wickham\", role = \"ctb\"),\n person(\"Hao\", \"Zhu\", role = \"ctb\"),\n person(\"Heewon\", \"Jeon\", role = \"ctb\"),\n person(\"Henrik\", \"Bengtsson\", role = \"ctb\"),\n person(\"Hiroaki\", \"Yutani\", role = \"ctb\"),\n person(\"Ian\", \"Lyttle\", role = \"ctb\"),\n person(\"Hodges\", \"Daniel\", role = \"ctb\"),\n person(\"Jacob\", \"Bien\", role = \"ctb\"),\n person(\"Jake\", \"Burkhead\", role = \"ctb\"),\n person(\"James\", \"Manton\", role = \"ctb\"),\n person(\"Jared\", \"Lander\", role = \"ctb\"),\n person(\"Jason\", \"Punyon\", role = \"ctb\"),\n person(\"Javier\", \"Luraschi\", role = \"ctb\"),\n person(\"Jeff\", \"Arnold\", role = \"ctb\"),\n person(\"Jenny\", \"Bryan\", role = \"ctb\"),\n person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"),\n person(\"Jeremy\", \"Stephens\", role = \"ctb\"),\n person(\"Jim\", \"Hester\", role = \"ctb\"),\n person(\"Joe\", \"Cheng\", role = \"ctb\"),\n person(\"Johannes\", \"Ranke\", role = \"ctb\"),\n person(\"John\", \"Honaker\", role = \"ctb\"),\n person(\"John\", \"Muschelli\", role = \"ctb\"),\n person(\"Jonathan\", \"Keane\", role = \"ctb\"),\n person(\"JJ\", \"Allaire\", role = \"ctb\"),\n person(\"Johan\", \"Toloe\", role = \"ctb\"),\n person(\"Jonathan\", \"Sidi\", role = \"ctb\"),\n person(\"Joseph\", \"Larmarange\", role = \"ctb\"),\n person(\"Julien\", \"Barnier\", role = \"ctb\"),\n person(\"Kaiyin\", \"Zhong\", role = \"ctb\"),\n person(\"Kamil\", \"Slowikowski\", role = \"ctb\"),\n person(\"Karl\", \"Forner\", role = \"ctb\"),\n person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"),\n person(\"Kirill\", \"Mueller\", role = \"ctb\"),\n person(\"Kohske\", \"Takahashi\", role = \"ctb\"),\n person(\"Lorenz\", \"Walthert\", role = \"ctb\"),\n person(\"Lucas\", \"Gallindo\", role = \"ctb\"),\n person(\"Marius\", \"Hofert\", role = \"ctb\"),\n person(\"Martin\", \"Modrák\", role = \"ctb\"),\n person(\"Michael\", \"Chirico\", role = \"ctb\"),\n person(\"Michael\", \"Friendly\", role = \"ctb\"),\n person(\"Michal\", \"Bojanowski\", role = \"ctb\"),\n person(\"Michel\", \"Kuhlmann\", role = \"ctb\"),\n person(\"Miller\", \"Patrick\", role = \"ctb\"),\n person(\"Nacho\", \"Caballero\", role = \"ctb\"),\n person(\"Nick\", \"Salkowski\", role = \"ctb\"),\n person(\"Niels Richard\", \"Hansen\", role = \"ctb\"),\n person(\"Noam\", \"Ross\", role = \"ctb\"),\n person(\"Obada\", \"Mahdi\", role = \"ctb\"),\n person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")),\n person(\"Pedro\", \"Faria\", role = \"ctb\"),\n person(\"Qiang\", \"Li\", role = \"ctb\"),\n person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"),\n person(\"Richard\", \"Cotton\", role = \"ctb\"),\n person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"),\n person(\"Rodrigo\", \"Copetti\", role = \"ctb\"),\n person(\"Romain\", \"Francois\", role = \"ctb\"),\n person(\"Ruaridh\", \"Williamson\", role = \"ctb\"),\n person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")),\n person(\"Scott\", \"Kostyshak\", role = \"ctb\"),\n person(\"Sebastian\", \"Meyer\", role = \"ctb\"),\n person(\"Sietse\", \"Brouwer\", role = \"ctb\"),\n person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"),\n person(\"Sylvain\", \"Rousseau\", role = \"ctb\"),\n person(\"Taiyun\", \"Wei\", role = \"ctb\"),\n person(\"Thibaut\", \"Assus\", role = \"ctb\"),\n person(\"Thibaut\", \"Lamadon\", role = \"ctb\"),\n person(\"Thomas\", \"Leeper\", role = \"ctb\"),\n person(\"Tim\", \"Mastny\", role = \"ctb\"),\n person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"),\n person(\"Trevor\", \"Davis\", role = \"ctb\"),\n person(\"Viktoras\", \"Veitas\", role = \"ctb\"),\n person(\"Weicheng\", \"Zhu\", role = \"ctb\"),\n person(\"Wush\", \"Wu\", role = \"ctb\"),\n person(\"Zachary\", \"Foster\", role = \"ctb\"),\n person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\"))\n )", + "Description": "Provides a general-purpose tool for dynamic report generation in R\n using Literate Programming techniques.", + "Depends": "R (>= 3.3.0)", + "Imports": "evaluate (>= 0.15), highr, methods, yaml (>= 2.1.19), xfun (>=\n0.34), tools", + "Suggests": "markdown (>= 1.3), formatR, testit, digest, rgl (>=\n0.95.1201), codetools, rmarkdown, htmlwidgets (>= 0.7),\nwebshot, tikzDevice (>= 0.10), tinytex, reticulate (>= 1.4),\nJuliaCall (>= 0.11.1), magick, png, jpeg, gifski, xml2 (>=\n1.2.0), httr, DBI (>= 0.4-1), showtext, tibble, sass, bslib,\nragg, gridSVG, styler (>= 1.2.0), targets (>= 0.6.0)", + "License": "GPL", + "URL": "https://yihui.org/knitr/", + "BugReports": "https://github.com/yihui/knitr/issues", + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "SystemRequirements": "Package vignettes based on R Markdown v2 or\nreStructuredText require Pandoc (http://pandoc.org). The\nfunction rst2pdf() requires rst2pdf\n(https://github.com/rst2pdf/rst2pdf).", + "Collate": "'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R'\n'plot.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R'\n'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R'\n'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R'\n'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R'\n'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R'\n'template.R' 'utils-conversion.R' 'utils-rd2html.R'\n'utils-string.R' 'utils-sweave.R' 'utils-upload.R'\n'utils-vignettes.R' 'zzz.R'", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2023-01-20 05:51:44 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Abhraneel Sarma [ctb],\n Adam Vogt [ctb],\n Alastair Andrew [ctb],\n Alex Zvoleff [ctb],\n Amar Al-Zubaidi [ctb],\n Andre Simon [ctb] (the CSS files under inst/themes/ were derived from\n the Highlight package http://www.andre-simon.de),\n Aron Atkins [ctb],\n Aaron Wolen [ctb],\n Ashley Manton [ctb],\n Atsushi Yasumoto [ctb] (),\n Ben Baumer [ctb],\n Brian Diggs [ctb],\n Brian Zhang [ctb],\n Bulat Yapparov [ctb],\n Cassio Pereira [ctb],\n Christophe Dervieux [ctb],\n David Hall [ctb],\n David Hugh-Jones [ctb],\n David Robinson [ctb],\n Doug Hemken [ctb],\n Duncan Murdoch [ctb],\n Elio Campitelli [ctb],\n Ellis Hughes [ctb],\n Emily Riederer [ctb],\n Fabian Hirschmann [ctb],\n Fitch Simeon [ctb],\n Forest Fang [ctb],\n Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty),\n Garrick Aden-Buie [ctb],\n Gregoire Detrez [ctb],\n Hadley Wickham [ctb],\n Hao Zhu [ctb],\n Heewon Jeon [ctb],\n Henrik Bengtsson [ctb],\n Hiroaki Yutani [ctb],\n Ian Lyttle [ctb],\n Hodges Daniel [ctb],\n Jacob Bien [ctb],\n Jake Burkhead [ctb],\n James Manton [ctb],\n Jared Lander [ctb],\n Jason Punyon [ctb],\n Javier Luraschi [ctb],\n Jeff Arnold [ctb],\n Jenny Bryan [ctb],\n Jeremy Ashkenas [ctb, cph] (the CSS file at\n inst/misc/docco-classic.css),\n Jeremy Stephens [ctb],\n Jim Hester [ctb],\n Joe Cheng [ctb],\n Johannes Ranke [ctb],\n John Honaker [ctb],\n John Muschelli [ctb],\n Jonathan Keane [ctb],\n JJ Allaire [ctb],\n Johan Toloe [ctb],\n Jonathan Sidi [ctb],\n Joseph Larmarange [ctb],\n Julien Barnier [ctb],\n Kaiyin Zhong [ctb],\n Kamil Slowikowski [ctb],\n Karl Forner [ctb],\n Kevin K. Smith [ctb],\n Kirill Mueller [ctb],\n Kohske Takahashi [ctb],\n Lorenz Walthert [ctb],\n Lucas Gallindo [ctb],\n Marius Hofert [ctb],\n Martin Modrák [ctb],\n Michael Chirico [ctb],\n Michael Friendly [ctb],\n Michal Bojanowski [ctb],\n Michel Kuhlmann [ctb],\n Miller Patrick [ctb],\n Nacho Caballero [ctb],\n Nick Salkowski [ctb],\n Niels Richard Hansen [ctb],\n Noam Ross [ctb],\n Obada Mahdi [ctb],\n Pavel N. Krivitsky [ctb] (),\n Pedro Faria [ctb],\n Qiang Li [ctb],\n Ramnath Vaidyanathan [ctb],\n Richard Cotton [ctb],\n Robert Krzyzanowski [ctb],\n Rodrigo Copetti [ctb],\n Romain Francois [ctb],\n Ruaridh Williamson [ctb],\n Sagiru Mati [ctb] (),\n Scott Kostyshak [ctb],\n Sebastian Meyer [ctb],\n Sietse Brouwer [ctb],\n Simon de Bernard [ctb],\n Sylvain Rousseau [ctb],\n Taiyun Wei [ctb],\n Thibaut Assus [ctb],\n Thibaut Lamadon [ctb],\n Thomas Leeper [ctb],\n Tim Mastny [ctb],\n Tom Torsney-Weir [ctb],\n Trevor Davis [ctb],\n Viktoras Veitas [ctb],\n Weicheng Zhu [ctb],\n Wush Wu [ctb],\n Zachary Foster [ctb],\n Zhian N. Kamvar [ctb] ()", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-01-25 10:20:08 UTC", + "Built": "R 4.3.0; ; 2023-04-12 11:17:12 UTC; unix" + } + }, + "lifecycle": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "lifecycle", + "Title": "Manage the Life Cycle of your Package Functions", + "Version": "1.0.3", + "Authors@R": "c(\n person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\",\n comment = c(ORCID = \"0000-0003-4757-117X\")),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Manage the life cycle of your exported functions with shared\n conventions, documentation badges, and user-friendly deprecation\n warnings.", + "License": "MIT + file LICENSE", + "URL": "https://lifecycle.r-lib.org/, https://github.com/r-lib/lifecycle", + "BugReports": "https://github.com/r-lib/lifecycle/issues", + "Depends": "R (>= 3.4)", + "Imports": "cli (>= 3.4.0), glue, rlang (>= 1.0.6)", + "Suggests": "covr, crayon, knitr, lintr, rmarkdown, testthat (>= 3.0.1),\ntibble, tidyverse, tools, vctrs, withr", + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Packaged": "2022-10-07 08:50:55 UTC; lionel", + "Author": "Lionel Henry [aut, cre],\n Hadley Wickham [aut] (),\n RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2022-10-07 09:50:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 06:43:28 UTC; unix" + } + }, + "magrittr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "magrittr", + "Title": "A Forward-Pipe Operator for R", + "Version": "2.0.3", + "Authors@R": "c(\n person(\"Stefan Milton\", \"Bache\", , \"stefan@stefanbache.dk\", role = c(\"aut\", \"cph\"),\n comment = \"Original author and creator of magrittr\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"),\n person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = \"cre\"),\n person(\"RStudio\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Provides a mechanism for chaining commands with a new\n forward-pipe operator, %>%. This operator will forward a value, or the\n result of an expression, into the next function call/expression.\n There is flexible support for the type of right-hand side expressions.\n For more information, see package vignette. To quote Rene Magritte,\n \"Ceci n'est pas un pipe.\"", + "License": "MIT + file LICENSE", + "URL": "https://magrittr.tidyverse.org,\nhttps://github.com/tidyverse/magrittr", + "BugReports": "https://github.com/tidyverse/magrittr/issues", + "Depends": "R (>= 3.4.0)", + "Suggests": "covr, knitr, rlang, rmarkdown, testthat", + "VignetteBuilder": "knitr", + "ByteCompile": "Yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Packaged": "2022-03-29 09:34:37 UTC; lionel", + "Author": "Stefan Milton Bache [aut, cph] (Original author and creator of\n magrittr),\n Hadley Wickham [aut],\n Lionel Henry [cre],\n RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2022-03-30 07:30:09 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:07:22 UTC; unix", + "Archs": "magrittr.so.dSYM" + } + }, + "memoise": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "memoise", + "Title": "'Memoisation' of Functions", + "Version": "2.0.1", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = \"aut\",\n email = \"hadley@rstudio.com\"),\n person(given = \"Jim\",\n family = \"Hester\",\n role = \"aut\"),\n person(given = \"Winston\",\n family = \"Chang\",\n role = c(\"aut\", \"cre\"),\n email = \"winston@rstudio.com\"),\n person(given = \"Kirill\",\n family = \"Müller\",\n role = \"aut\",\n email = \"krlmlr+r@mailbox.org\"),\n person(given = \"Daniel\",\n family = \"Cook\",\n role = \"aut\",\n email = \"danielecook@gmail.com\"),\n person(given = \"Mark\",\n family = \"Edmondson\",\n role = \"ctb\",\n email = \"r@sunholo.com\"))", + "Description": "Cache the results of a function so that when you\n call it again with the same arguments it returns the previously computed\n value.", + "License": "MIT + file LICENSE", + "URL": "https://memoise.r-lib.org, https://github.com/r-lib/memoise", + "BugReports": "https://github.com/r-lib/memoise/issues", + "Imports": "rlang (>= 0.4.10), cachem", + "Suggests": "digest, aws.s3, covr, googleAuthR, googleCloudStorageR, httr,\ntestthat", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "no", + "Packaged": "2021-11-24 21:24:50 UTC; jhester", + "Author": "Hadley Wickham [aut],\n Jim Hester [aut],\n Winston Chang [aut, cre],\n Kirill Müller [aut],\n Daniel Cook [aut],\n Mark Edmondson [ctb]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN", + "Date/Publication": "2021-11-26 16:11:10 UTC", + "Built": "R 4.3.0; ; 2023-04-17 22:23:05 UTC; unix" + } + }, + "mime": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "mime", + "Type": "Package", + "Title": "Map Filenames to MIME Types", + "Version": "0.12", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Jeffrey\", \"Horner\", role = \"ctb\"),\n person(\"Beilei\", \"Bian\", role = \"ctb\")\n )", + "Description": "Guesses the MIME type from a filename extension using the data\n derived from /etc/mime.types in UNIX-type systems.", + "Imports": "tools", + "License": "GPL", + "URL": "https://github.com/yihui/mime", + "BugReports": "https://github.com/yihui/mime/issues", + "RoxygenNote": "7.1.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2021-09-28 02:06:04 UTC; yihui", + "Author": "Yihui Xie [aut, cre] (),\n Jeffrey Horner [ctb],\n Beilei Bian [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2021-09-28 05:00:05 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:09:16 UTC; unix", + "Archs": "mime.so.dSYM" + } + }, + "rappdirs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "rappdirs", + "Title": "Application Directories: Determine Where to Save Data, Caches,\nand Logs", + "Version": "0.3.3", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = c(\"trl\", \"cre\", \"cph\"),\n email = \"hadley@rstudio.com\"),\n person(given = \"RStudio\",\n role = \"cph\"),\n person(given = \"Sridhar\",\n family = \"Ratnakumar\",\n role = \"aut\"),\n person(given = \"Trent\",\n family = \"Mick\",\n role = \"aut\"),\n person(given = \"ActiveState\",\n role = \"cph\",\n comment = \"R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs\"),\n person(given = \"Eddy\",\n family = \"Petrisor\",\n role = \"ctb\"),\n person(given = \"Trevor\",\n family = \"Davis\",\n role = c(\"trl\", \"aut\")),\n person(given = \"Gabor\",\n family = \"Csardi\",\n role = \"ctb\"),\n person(given = \"Gregory\",\n family = \"Jefferis\",\n role = \"ctb\"))", + "Description": "An easy way to determine which directories on the\n users computer you should use to save data, caches and logs. A port of\n Python's 'Appdirs' () to\n R.", + "License": "MIT + file LICENSE", + "URL": "https://rappdirs.r-lib.org, https://github.com/r-lib/rappdirs", + "BugReports": "https://github.com/r-lib/rappdirs/issues", + "Depends": "R (>= 3.2)", + "Suggests": "roxygen2, testthat (>= 3.0.0), covr, withr", + "Copyright": "Original python appdirs module copyright (c) 2010\nActiveState Software Inc. R port copyright Hadley Wickham,\nRStudio. See file LICENSE for details.", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Packaged": "2021-01-28 22:29:57 UTC; hadley", + "Author": "Hadley Wickham [trl, cre, cph],\n RStudio [cph],\n Sridhar Ratnakumar [aut],\n Trent Mick [aut],\n ActiveState [cph] (R/appdir.r, R/cache.r, R/data.r, R/log.r translated\n from appdirs),\n Eddy Petrisor [ctb],\n Trevor Davis [trl, aut],\n Gabor Csardi [ctb],\n Gregory Jefferis [ctb]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2021-01-31 05:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:10:28 UTC; unix", + "Archs": "rappdirs.so.dSYM" + } + }, + "rlang": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "rlang", + "Version": "1.1.1", + "Title": "Functions for Base Types and Core R and 'Tidyverse' Features", + "Description": "A toolbox for working with base types, core R features\n like the condition system, and core 'Tidyverse' features like tidy\n evaluation.", + "Authors@R": "c(\n person(\"Lionel\", \"Henry\", ,\"lionel@posit.co\", c(\"aut\", \"cre\")),\n person(\"Hadley\", \"Wickham\", ,\"hadley@posit.co\", \"aut\"),\n person(given = \"mikefc\",\n email = \"mikefc@coolbutuseless.com\", \n role = \"cph\", \n comment = \"Hash implementation based on Mike's xxhashlite\"),\n person(given = \"Yann\",\n family = \"Collet\",\n role = \"cph\", \n comment = \"Author of the embedded xxHash library\"),\n person(given = \"Posit, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "License": "MIT + file LICENSE", + "ByteCompile": "true", + "Biarch": "true", + "Depends": "R (>= 3.5.0)", + "Imports": "utils", + "Suggests": "cli (>= 3.1.0), covr, crayon, fs, glue, knitr, magrittr,\nmethods, pillar, rmarkdown, stats, testthat (>= 3.0.0), tibble,\nusethis, vctrs (>= 0.2.3), withr", + "Enhances": "winch", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "URL": "https://rlang.r-lib.org, https://github.com/r-lib/rlang", + "BugReports": "https://github.com/r-lib/rlang/issues", + "Config/testthat/edition": "3", + "Config/Needs/website": "dplyr, tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Packaged": "2023-04-28 10:48:43 UTC; lionel", + "Author": "Lionel Henry [aut, cre],\n Hadley Wickham [aut],\n mikefc [cph] (Hash implementation based on Mike's xxhashlite),\n Yann Collet [cph] (Author of the embedded xxHash library),\n Posit, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN", + "Date/Publication": "2023-04-28 22:30:03 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-30 06:48:25 UTC; unix", + "Archs": "rlang.so.dSYM" + } + }, + "rmarkdown": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "rmarkdown", + "Title": "Dynamic Documents for R", + "Version": "2.21", + "Authors@R": "c(\n person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\"),\n person(\"Yihui\", \"Xie\", , \"xie@yihui.name\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Jonathan\", \"McPherson\", , \"jonathan@posit.co\", role = \"aut\"),\n person(\"Javier\", \"Luraschi\", role = \"aut\"),\n person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"aut\"),\n person(\"Aron\", \"Atkins\", , \"aron@posit.co\", role = \"aut\"),\n person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"),\n person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"),\n person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\"),\n person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Andrew\", \"Dunning\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0464-5036\")),\n person(\"Atsushi\", \"Yasumoto\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-8335-495X\", cph = \"Number sections Lua filter\")),\n person(\"Barret\", \"Schloerke\", role = \"ctb\"),\n person(\"Carson\", \"Sievert\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4958-2844\")), \n person(\"Devon\", \"Ryan\", , \"dpryan79@gmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8549-0971\")),\n person(\"Frederik\", \"Aust\", , \"frederik.aust@uni-koeln.de\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4900-788X\")),\n person(\"Jeff\", \"Allen\", , \"jeff@posit.co\", role = \"ctb\"), \n person(\"JooYoung\", \"Seo\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4064-6012\")),\n person(\"Malcolm\", \"Barrett\", role = \"ctb\"),\n person(\"Rob\", \"Hyndman\", , \"Rob.Hyndman@monash.edu\", role = \"ctb\"),\n person(\"Romain\", \"Lesur\", role = \"ctb\"),\n person(\"Roy\", \"Storey\", role = \"ctb\"),\n person(\"Ruben\", \"Arslan\", , \"ruben.arslan@uni-goettingen.de\", role = \"ctb\"),\n person(\"Sergio\", \"Oller\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person(, \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/rmd/h/jqueryui-AUTHORS.txt\"),\n person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"),\n person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"),\n person(\"Alexander\", \"Farkas\", role = c(\"ctb\", \"cph\"), comment = \"html5shiv library\"),\n person(\"Scott\", \"Jehl\", role = c(\"ctb\", \"cph\"), comment = \"Respond.js library\"),\n person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"),\n person(\"Greg\", \"Franko\", role = c(\"ctb\", \"cph\"), comment = \"tocify library\"),\n person(\"John\", \"MacFarlane\", role = c(\"ctb\", \"cph\"), comment = \"Pandoc templates\"),\n person(, \"Google, Inc.\", role = c(\"ctb\", \"cph\"), comment = \"ioslides library\"),\n person(\"Dave\", \"Raggett\", role = \"ctb\", comment = \"slidy library\"),\n person(, \"W3C\", role = \"cph\", comment = \"slidy library\"),\n person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome\"),\n person(\"Ben\", \"Sperry\", role = \"ctb\", comment = \"Ionicons\"),\n person(, \"Drifty\", role = \"cph\", comment = \"Ionicons\"),\n person(\"Aidan\", \"Lister\", role = c(\"ctb\", \"cph\"), comment = \"jQuery StickyTabs\"),\n person(\"Benct Philip\", \"Jonsson\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\"),\n person(\"Albert\", \"Krewinkel\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\")\n )", + "Maintainer": "Yihui Xie ", + "Description": "Convert R Markdown documents into a variety of formats.", + "License": "GPL-3", + "URL": "https://github.com/rstudio/rmarkdown,\nhttps://pkgs.rstudio.com/rmarkdown/", + "BugReports": "https://github.com/rstudio/rmarkdown/issues", + "Depends": "R (>= 3.0)", + "Imports": "bslib (>= 0.2.5.1), evaluate (>= 0.13), fontawesome (>=\n0.5.0), htmltools (>= 0.5.1), jquerylib, jsonlite, knitr (>=\n1.22), methods, stringr (>= 1.2.0), tinytex (>= 0.31), tools,\nutils, xfun (>= 0.36), yaml (>= 2.1.19)", + "Suggests": "digest, dygraphs, fs, rsconnect, downlit (>= 0.4.0), katex\n(>= 1.4.0), sass (>= 0.4.0), shiny (>= 1.6.0), testthat (>=\n3.0.3), tibble, vctrs, withr (>= 2.4.2)", + "VignetteBuilder": "knitr", + "Config/Needs/website": "rstudio/quillt, pkgdown", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "pandoc (>= 1.14) - http://pandoc.org", + "NeedsCompilation": "no", + "Packaged": "2023-03-25 21:50:22 UTC; yihui", + "Author": "JJ Allaire [aut],\n Yihui Xie [aut, cre] (),\n Christophe Dervieux [aut] (),\n Jonathan McPherson [aut],\n Javier Luraschi [aut],\n Kevin Ushey [aut],\n Aron Atkins [aut],\n Hadley Wickham [aut],\n Joe Cheng [aut],\n Winston Chang [aut],\n Richard Iannone [aut] (),\n Andrew Dunning [ctb] (),\n Atsushi Yasumoto [ctb, cph] (,\n Number sections Lua filter),\n Barret Schloerke [ctb],\n Carson Sievert [ctb] (),\n Devon Ryan [ctb] (),\n Frederik Aust [ctb] (),\n Jeff Allen [ctb],\n JooYoung Seo [ctb] (),\n Malcolm Barrett [ctb],\n Rob Hyndman [ctb],\n Romain Lesur [ctb],\n Roy Storey [ctb],\n Ruben Arslan [ctb],\n Sergio Oller [ctb],\n Posit Software, PBC [cph, fnd],\n jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in\n inst/rmd/h/jqueryui-AUTHORS.txt),\n Mark Otto [ctb] (Bootstrap library),\n Jacob Thornton [ctb] (Bootstrap library),\n Bootstrap contributors [ctb] (Bootstrap library),\n Twitter, Inc [cph] (Bootstrap library),\n Alexander Farkas [ctb, cph] (html5shiv library),\n Scott Jehl [ctb, cph] (Respond.js library),\n Ivan Sagalaev [ctb, cph] (highlight.js library),\n Greg Franko [ctb, cph] (tocify library),\n John MacFarlane [ctb, cph] (Pandoc templates),\n Google, Inc. [ctb, cph] (ioslides library),\n Dave Raggett [ctb] (slidy library),\n W3C [cph] (slidy library),\n Dave Gandy [ctb, cph] (Font-Awesome),\n Ben Sperry [ctb] (Ionicons),\n Drifty [cph] (Ionicons),\n Aidan Lister [ctb, cph] (jQuery StickyTabs),\n Benct Philip Jonsson [ctb, cph] (pagebreak Lua filter),\n Albert Krewinkel [ctb, cph] (pagebreak Lua filter)", + "Repository": "CRAN", + "Date/Publication": "2023-03-26 22:00:03 UTC", + "Built": "R 4.3.0; ; 2023-05-15 19:16:40 UTC; unix" + } + }, + "sass": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Type": "Package", + "Package": "sass", + "Version": "0.4.6", + "Title": "Syntactically Awesome Style Sheets ('Sass')", + "Description": "An 'SCSS' compiler, powered by the 'LibSass' library. With this,\n R developers can use variables, inheritance, and functions to generate\n dynamic style sheets. The package uses the 'Sass CSS' extension language,\n which is stable, powerful, and CSS compatible.", + "Authors@R": "c(\n person(\"Joe\", \"Cheng\", , \"joe@rstudio.com\", \"aut\"),\n person(\"Timothy\", \"Mastny\", , \"tim.mastny@gmail.com\", \"aut\"),\n person(\"Richard\", \"Iannone\", , \"rich@rstudio.com\", \"aut\",\n comment = c(ORCID = \"0000-0003-3925-190X\")),\n person(\"Barret\", \"Schloerke\", , \"barret@rstudio.com\", \"aut\",\n comment = c(ORCID = \"0000-0001-9986-114X\")),\n person(\"Carson\", \"Sievert\", , \"carson@rstudio.com\", c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0002-4958-2844\")),\n person(\"Christophe\", \"Dervieux\", , \"cderv@rstudio.com\", c(\"ctb\"),\n comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(family = \"RStudio\", role = c(\"cph\", \"fnd\")),\n person(family = \"Sass Open Source Foundation\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Greter\", \"Marcel\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Mifsud\", \"Michael\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Hampton\", \"Catlin\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Natalie\", \"Weizenbaum\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Chris\", \"Eppstein\", role = c(\"ctb\", \"cph\"),\n comment = \"LibSass library\"),\n person(\"Adams\", \"Joseph\", role = c(\"ctb\", \"cph\"),\n comment = \"json.cpp\"),\n person(\"Trifunovic\", \"Nemanja\", role = c(\"ctb\", \"cph\"),\n comment = \"utf8.h\")\n )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/sass/, https://github.com/rstudio/sass", + "BugReports": "https://github.com/rstudio/sass/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "GNU make", + "Imports": "fs, rlang (>= 0.4.10), htmltools (>= 0.5.1), R6, rappdirs", + "Suggests": "testthat, knitr, rmarkdown, withr, shiny, curl", + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Packaged": "2023-05-03 22:45:10 UTC; cpsievert", + "Author": "Joe Cheng [aut],\n Timothy Mastny [aut],\n Richard Iannone [aut] (),\n Barret Schloerke [aut] (),\n Carson Sievert [aut, cre] (),\n Christophe Dervieux [ctb] (),\n RStudio [cph, fnd],\n Sass Open Source Foundation [ctb, cph] (LibSass library),\n Greter Marcel [ctb, cph] (LibSass library),\n Mifsud Michael [ctb, cph] (LibSass library),\n Hampton Catlin [ctb, cph] (LibSass library),\n Natalie Weizenbaum [ctb, cph] (LibSass library),\n Chris Eppstein [ctb, cph] (LibSass library),\n Adams Joseph [ctb, cph] (json.cpp),\n Trifunovic Nemanja [ctb, cph] (utf8.h)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN", + "Date/Publication": "2023-05-03 23:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-05-04 04:35:51 UTC; unix", + "Archs": "sass.so.dSYM" + } + }, + "stringi": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "stringi", + "Version": "1.7.12", + "Date": "2023-01-09", + "Title": "Fast and Portable Character String Processing Facilities", + "Description": "A collection of character string/text/natural language\n processing tools for pattern searching (e.g., with 'Java'-like regular\n expressions or the 'Unicode' collation algorithm), random string generation,\n case mapping, string transliteration, concatenation, sorting, padding,\n wrapping, Unicode normalisation, date-time formatting and parsing,\n and many more. They are fast, consistent, convenient, and -\n thanks to 'ICU' (International Components for Unicode) -\n portable across all locales and platforms. Documentation about 'stringi' is\n provided via its website at and\n the paper by Gagolewski (2022, ).", + "URL": "https://stringi.gagolewski.com/,\nhttps://github.com/gagolews/stringi, https://icu.unicode.org/", + "BugReports": "https://github.com/gagolews/stringi/issues", + "SystemRequirements": "C++11, ICU4C (>= 55, optional)", + "Type": "Package", + "Depends": "R (>= 3.1)", + "Imports": "tools, utils, stats", + "Biarch": "TRUE", + "License": "file LICENSE", + "Author": "Marek Gagolewski [aut, cre, cph] (),\n Bartek Tartanus [ctb], and others (stringi source code);\n Unicode, Inc. and others (ICU4C source code, Unicode Character Database)", + "Maintainer": "Marek Gagolewski ", + "RoxygenNote": "7.2.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Packaged": "2023-01-09 07:28:38 UTC; gagolews", + "License_is_FOSS": "yes", + "Repository": "CRAN", + "Date/Publication": "2023-01-11 10:10:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-11 20:20:49 UTC; unix" + } + }, + "stringr": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "stringr", + "Title": "Simple, Consistent Wrappers for Common String Operations", + "Version": "1.5.0", + "Authors@R": "\n c(person(given = \"Hadley\",\n family = \"Wickham\",\n role = c(\"aut\", \"cre\", \"cph\"),\n email = \"hadley@rstudio.com\"),\n person(given = \"RStudio\",\n role = c(\"cph\", \"fnd\")))", + "Description": "A consistent, simple and easy to use set of wrappers around\n the fantastic 'stringi' package. All function and argument names (and\n positions) are consistent, all functions deal with \"NA\"'s and zero\n length vectors in the same way, and the output from one function is\n easy to feed into the input of another.", + "License": "MIT + file LICENSE", + "URL": "https://stringr.tidyverse.org,\nhttps://github.com/tidyverse/stringr", + "BugReports": "https://github.com/tidyverse/stringr/issues", + "Depends": "R (>= 3.3)", + "Imports": "cli, glue (>= 1.6.1), lifecycle (>= 1.0.3), magrittr, rlang\n(>= 1.0.0), stringi (>= 1.5.3), vctrs", + "Suggests": "covr, htmltools, htmlwidgets, knitr, rmarkdown, testthat (>=\n3.0.0)", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Packaged": "2022-12-01 20:53:42 UTC; hadleywickham", + "Author": "Hadley Wickham [aut, cre, cph],\n RStudio [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN", + "Date/Publication": "2022-12-02 10:20:02 UTC", + "Built": "R 4.3.0; ; 2023-04-12 12:50:56 UTC; unix" + } + }, + "tinytex": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "tinytex", + "Type": "Package", + "Title": "Helper Functions to Install and Maintain TeX Live, and Compile\nLaTeX Documents", + "Version": "0.45", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")),\n person(\"Devon\", \"Ryan\", role = \"ctb\", email = \"dpryan79@gmail.com\", comment = c(ORCID = \"0000-0002-8549-0971\")),\n person(\"Ethan\", \"Heinzen\", role = \"ctb\"),\n person(\"Fernando\", \"Cagua\", role = \"ctb\"),\n person()\n )", + "Description": "Helper functions to install and maintain the 'LaTeX' distribution\n named 'TinyTeX' (), a lightweight, cross-platform,\n portable, and easy-to-maintain version of 'TeX Live'. This package also\n contains helper functions to compile 'LaTeX' documents, and install missing\n 'LaTeX' packages automatically.", + "Imports": "xfun (>= 0.29)", + "Suggests": "testit, rstudioapi", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/tinytex", + "BugReports": "https://github.com/rstudio/tinytex/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Packaged": "2023-04-18 13:52:40 UTC; yihui", + "Author": "Yihui Xie [aut, cre, cph] (),\n Posit Software, PBC [cph, fnd],\n Christophe Dervieux [ctb] (),\n Devon Ryan [ctb] (),\n Ethan Heinzen [ctb],\n Fernando Cagua [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-04-18 14:30:07 UTC", + "Built": "R 4.3.0; ; 2023-04-22 00:31:32 UTC; unix" + } + }, + "vctrs": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "vctrs", + "Title": "Vector Helpers", + "Version": "0.6.2", + "Authors@R": "c(\n person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"),\n person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"),\n person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")),\n person(\"data.table team\", role = \"cph\",\n comment = \"Radix sort based on data.table's forder() and their contribution to R's order()\"),\n person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )", + "Description": "Defines new notions of prototype and size that are used to\n provide tools for consistent and well-founded type-coercion and\n size-recycling, and are in turn connected to ideas of type- and\n size-stability useful for analysing function interfaces.", + "License": "MIT + file LICENSE", + "URL": "https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs", + "BugReports": "https://github.com/r-lib/vctrs/issues", + "Depends": "R (>= 3.5.0)", + "Imports": "cli (>= 3.4.0), glue, lifecycle (>= 1.0.3), rlang (>= 1.1.0)", + "Suggests": "bit64, covr, crayon, dplyr (>= 0.8.5), generics, knitr,\npillar (>= 1.4.4), pkgdown (>= 2.0.1), rmarkdown, testthat (>=\n3.0.0), tibble (>= 3.1.3), waldo (>= 0.2.0), withr, xml2,\nzeallot", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "Language": "en-GB", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Packaged": "2023-04-19 18:24:24 UTC; davis", + "Author": "Hadley Wickham [aut],\n Lionel Henry [aut],\n Davis Vaughan [aut, cre],\n data.table team [cph] (Radix sort based on data.table's forder() and\n their contribution to R's order()),\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN", + "Date/Publication": "2023-04-19 19:30:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-22 00:48:35 UTC; unix", + "Archs": "vctrs.so.dSYM" + } + }, + "xfun": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "xfun", + "Type": "Package", + "Title": "Supporting Functions for Packages Maintained by 'Yihui Xie'", + "Version": "0.39", + "Authors@R": "c(\n person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")),\n person(\"Wush\", \"Wu\", role = \"ctb\"),\n person(\"Daijiang\", \"Li\", role = \"ctb\"),\n person(\"Xianying\", \"Tan\", role = \"ctb\"),\n person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")),\n person(\"Christophe\", \"Dervieux\", role = \"ctb\"),\n person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")),\n person()\n )", + "Description": "Miscellaneous functions commonly used in other packages maintained by 'Yihui Xie'.", + "Imports": "stats, tools", + "Suggests": "testit, parallel, codetools, rstudioapi, tinytex (>= 0.30),\nmime, markdown (>= 1.5), knitr (>= 1.42), htmltools, remotes,\npak, rhub, renv, curl, jsonlite, magick, yaml, rmarkdown", + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/xfun", + "BugReports": "https://github.com/yihui/xfun/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "VignetteBuilder": "knitr", + "NeedsCompilation": "yes", + "Packaged": "2023-04-19 22:17:10 UTC; yihui", + "Author": "Yihui Xie [aut, cre, cph] (),\n Wush Wu [ctb],\n Daijiang Li [ctb],\n Xianying Tan [ctb],\n Salim Brüggemann [ctb] (),\n Christophe Dervieux [ctb],\n Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN", + "Date/Publication": "2023-04-20 12:50:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-22 00:00:24 UTC; unix", + "Archs": "xfun.so.dSYM" + } + }, + "yaml": { + "Source": "CRAN", + "Repository": "https://cran.rstudio.com", + "description": { + "Package": "yaml", + "Type": "Package", + "Title": "Methods to Convert R Data to YAML and Back", + "Date": "2023-01-18", + "Version": "2.3.7", + "Suggests": "RUnit", + "Author": "Shawn P Garbett [aut], Jeremy Stephens [aut, cre], Kirill Simonov [aut], Yihui Xie [ctb],\n Zhuoer Dong [ctb], Hadley Wickham [ctb], Jeffrey Horner [ctb], reikoch [ctb],\n Will Beasley [ctb], Brendan O'Connor [ctb], Gregory R. Warnes [ctb],\n Michael Quinn [ctb], Zhian N. Kamvar [ctb]", + "Maintainer": "Shawn Garbett ", + "License": "BSD_3_clause + file LICENSE", + "Description": "Implements the 'libyaml' 'YAML' 1.1 parser and emitter\n () for R.", + "URL": "https://github.com/vubiostat/r-yaml/", + "BugReports": "https://github.com/vubiostat/r-yaml/issues", + "NeedsCompilation": "yes", + "Packaged": "2023-01-18 17:20:16 UTC; garbetsp", + "Repository": "CRAN", + "Date/Publication": "2023-01-23 18:40:02 UTC", + "Built": "R 4.3.0; x86_64-apple-darwin20; 2023-04-08 21:18:13 UTC; unix", + "Archs": "yaml.so.dSYM" + } + } + }, + "files": { + "_site.yml": { + "checksum": "68b329da9893e34099c7d8ad5cb9c940" + }, + ".Rprofile": { + "checksum": "0b7556db576037033836dad462da03f7" + }, + "another.Rmd": { + "checksum": "3ff73b227b8d15e2b39172402234a0b6" + }, + "article.Rmd": { + "checksum": "c41a63e581ccf14e6e00ef8dab979765" + }, + "index.Rmd": { + "checksum": "c85dc46c45a93df8010830d238e4ff75" + }, + "meta.yaml": { + "checksum": "0824e67d283b321ee84d16fd194625d8" + } + }, + "users": null +} diff --git a/internal/inspect/detectors/testdata/rmd-site/meta.yaml b/internal/inspect/detectors/testdata/rmd-site/meta.yaml new file mode 100644 index 000000000..21c54d290 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/meta.yaml @@ -0,0 +1,10 @@ +tags: + - provisioner + - r + - rmd + - site + - static + - dev-env + - small-dev-env + - regression + - all diff --git a/internal/inspect/detectors/testdata/rmd-site/renv.lock b/internal/inspect/detectors/testdata/rmd-site/renv.lock new file mode 100644 index 000000000..54fd9f537 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/renv.lock @@ -0,0 +1,398 @@ +{ + "R": { + "Version": "4.3.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://packagemanager.posit.co/cran/latest" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bslib": { + "Package": "bslib", + "Version": "0.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9" + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "c35768291560ce302c0a6589f92e837d" + }, + "cli": { + "Package": "cli", + "Version": "3.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + }, + "digest": { + "Package": "digest", + "Version": "0.6.35", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "rlang" + ], + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.22", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "66f39c7a21e03c4dcb2c2d21d738d603" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f7736a18de97dea803bde0a2daaafb27" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + }, + "fs": { + "Package": "fs", + "Version": "1.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" + }, + "glue": { + "Package": "glue", + "Version": "1.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "e0b3a53876554bd45879e596cdb10a52" + }, + "highr": { + "Package": "highr", + "Version": "0.10", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "06230136b2d2b9ba5805e1963fa6e890" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "ellipsis", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "a2326a66919a3311f7fbb1e3bf568283" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "e1b9c55281c5adc4dd113652d9e26768" + }, + "knitr": { + "Package": "knitr", + "Version": "1.44", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "60885b9f746c9dfaef110d070b5f7dc0" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "b8552d117e1b808b09a832f589b79035" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "7ce2733a9826b3aeb1775d56fd305472" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "renv": { + "Package": "renv", + "Version": "1.0.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "397b7b2a265bc5a7a06852524dabae20" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.25", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "stringr", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "d65e35823c817f09f4de424fcdfa812a" + }, + "sass": { + "Package": "sass", + "Version": "0.4.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "6bd4d33b50ff927191ec9acbf52fd056" + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stats", + "tools", + "utils" + ], + "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ], + "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.47", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "8d4ccb733843e513c1c1cdd66a759f0d" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "c03fa420630029418f7e6da3667aac4a" + }, + "xfun": { + "Package": "xfun", + "Version": "0.40", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "stats", + "tools" + ], + "Hash": "be07d23211245fc7d4209f54c4e4ffc8" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "29240487a071f535f5e5d5a323b7afbd" + } + } +} diff --git a/internal/inspect/detectors/testdata/rmd-site/renv/.gitignore b/internal/inspect/detectors/testdata/rmd-site/renv/.gitignore new file mode 100644 index 000000000..0ec0cbba2 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ diff --git a/internal/inspect/detectors/testdata/rmd-site/renv/activate.R b/internal/inspect/detectors/testdata/rmd-site/renv/activate.R new file mode 100644 index 000000000..d13f9932a --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/renv/activate.R @@ -0,0 +1,1220 @@ + +local({ + + # the requested version of renv + version <- "1.0.7" + attr(version, "sha") <- NULL + + # the project directory + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() + + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + + # figure out whether the autoloader is enabled + enabled <- local({ + + # first, check config option + override <- getOption("renv.config.autoloader.enabled") + if (!is.null(override)) + return(override) + + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + + # next, check environment variables + # TODO: prefer using the configuration one in the future + envvars <- c( + "RENV_CONFIG_AUTOLOADER_ENABLED", + "RENV_AUTOLOADER_ENABLED", + "RENV_ACTIVATE_PROJECT" + ) + + for (envvar in envvars) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(tolower(envval) %in% c("true", "t", "1")) + } + + # enable by default + TRUE + + }) + + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + + return(FALSE) + + } + + # avoid recursion + if (identical(getOption("renv.autoloader.running"), TRUE)) { + warning("ignoring recursive attempt to run renv autoloader") + return(invisible(TRUE)) + } + + # signal that we're loading renv during R startup + options(renv.autoloader.running = TRUE) + on.exit(options(renv.autoloader.running = NULL), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # unload renv if it's already been loaded + if ("renv" %in% loadedNamespaces()) + unloadNamespace("renv") + + # load bootstrap tools + `%||%` <- function(x, y) { + if (is.null(x)) y else x + } + + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + paste(substring(lines, common), collapse = "\n") + + } + + startswith <- function(string, prefix) { + substring(string, 1, nchar(prefix)) == prefix + } + + bootstrap <- function(version, library) { + + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + + # attempt to download renv + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) + + # now attempt to install + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + + return(invisible()) + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # get CRAN repository + cran <- getOption("renv.repos.cran", "https://cloud.r-project.org") + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) { + + # check for RSPM; if set, use a fallback repository for renv + rspm <- Sys.getenv("RSPM", unset = NA) + if (identical(rspm, repos)) + repos <- c(RSPM = rspm, CRAN = cran) + + return(repos) + + } + + # check for lockfile repositories + repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) + if (!inherits(repos, "error") && length(repos)) + return(repos) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- cran + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_repos_lockfile <- function() { + + lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") + if (!file.exists(lockpath)) + return(NULL) + + lockfile <- tryCatch(renv_json_read(lockpath), error = identity) + if (inherits(lockfile, "error")) { + warning(lockfile) + return(NULL) + } + + repos <- lockfile$R$Repositories + if (length(repos) == 0) + return(NULL) + + keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) + vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) + names(vals) <- keys + + return(vals) + + } + + renv_bootstrap_download <- function(version) { + + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) + ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } + + for (method in methods) { + path <- tryCatch(method(), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("All download methods failed") + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + args <- list( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos + + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") + + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (inherits(status, "condition")) + return(FALSE) + + # report success and return + destfile + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # retrieve package database + db <- tryCatch( + as.data.frame( + utils::available.packages(type = type, repos = repos), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) + return(destfile) + + } + + return(FALSE) + + } + + renv_bootstrap_download_tarball <- function(version) { + + # if the user has provided the path to a tarball via + # an environment variable, then use it + tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) + if (is.na(tarball)) + return() + + # allow directories + if (dir.exists(tarball)) { + name <- sprintf("renv_%s.tar.gz", version) + tarball <- file.path(tarball, name) + } + + # bail if it doesn't exist + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail + return() + + } + + catf("- Using local tarball '%s'.", tarball) + tarball + + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + pat <- Sys.getenv("GITHUB_PAT") + if (nzchar(Sys.which("curl")) && nzchar(pat)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) + return(FALSE) + + renv_bootstrap_download_augment(destfile) + + return(destfile) + + } + + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a 'gzip' magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + R <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + system2(R, args, stdout = TRUE, stderr = TRUE) + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version, description = NULL) { + + # resolve description file + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") + + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) + else + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + else + paste("renv", description[["Version"]], sep = "@") + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = if (dev) description[["RemoteSha"]] + ) + + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) + + FALSE + + } + + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # execute renv load hooks, if any + hooks <- getHook("renv::autoload") + for (hook in hooks) + if (is.function(hook)) + tryCatch(hook(), error = warnify) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + renv_json_read <- function(file = NULL, text = NULL) { + + jlerr <- NULL + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) { + + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + jlerr <- json + + } + + # otherwise, fall back to the default JSON reader + json <- tryCatch(renv_json_read_default(file, text), error = identity) + if (!inherits(json, "error")) + return(json) + + # report an error + if (!is.null(jlerr)) + stop(jlerr) + else + stop(json) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # find strings in the JSON + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + + # if any are found, replace them with placeholders + replaced <- text + strings <- character() + replacements <- character() + + if (!identical(c(locs), -1L)) { + + # get the string values + starts <- locs + ends <- locs + attr(locs, "match.length") - 1L + strings <- substring(text, starts, ends) + + # only keep those requiring escaping + strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + + # compute replacements + replacements <- sprintf('"\032%i\032"', seq_along(strings)) + + # replace the strings + mapply(function(string, replacement) { + replaced <<- sub(string, replacement, replaced, fixed = TRUE) + }, strings, replacements) + + } + + # transform the JSON into something the R parser understands + transformed <- replaced + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) + transformed <- gsub(":", "=", transformed, fixed = TRUE) + text <- paste(transformed, collapse = "\n") + + # parse it + json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + + # construct map between source strings, replaced strings + map <- as.character(parse(text = strings)) + names(map) <- as.character(parse(text = replacements)) + + # convert to list + map <- as.list(map) + + # remap strings in object + remapped <- renv_json_read_remap(json, map) + + # evaluate + eval(remapped, envir = baseenv()) + + } + + renv_json_read_remap <- function(json, map) { + + # fix names + if (!is.null(names(json))) { + lhs <- match(names(json), names(map), nomatch = 0L) + rhs <- match(names(map), names(json), nomatch = 0L) + names(json)[rhs] <- map[lhs] + } + + # fix values + if (is.character(json)) + return(map[[json]] %||% json) + + # handle true, false, null + if (is.name(json)) { + text <- as.character(json) + if (text == "true") + return(TRUE) + else if (text == "false") + return(FALSE) + else if (text == "null") + return(NULL) + } + + # recurse + if (is.recursive(json)) { + for (i in seq_along(json)) { + json[i] <- list(renv_json_read_remap(json[[i]], map)) + } + } + + json + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) + + invisible() + +}) diff --git a/internal/inspect/detectors/testdata/rmd-site/renv/settings.json b/internal/inspect/detectors/testdata/rmd-site/renv/settings.json new file mode 100644 index 000000000..d5590a960 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/renv/settings.json @@ -0,0 +1,15 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [], + "package.dependency.fields": ["Imports", "Depends", "LinkingTo"], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "implicit", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/internal/inspect/detectors/testdata/rmd-site/rmd-site.Rproj b/internal/inspect/detectors/testdata/rmd-site/rmd-site.Rproj new file mode 100644 index 000000000..827cca17d --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/rmd-site.Rproj @@ -0,0 +1,15 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Website diff --git a/internal/inspect/detectors/testdata/rmd-site/sub-dir/another.Rmd b/internal/inspect/detectors/testdata/rmd-site/sub-dir/another.Rmd new file mode 100644 index 000000000..9dd657a91 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/sub-dir/another.Rmd @@ -0,0 +1,3 @@ +# Another + +Here is another page. It links to [index](index.html) and [article](article.html). diff --git a/internal/inspect/detectors/testdata/rmd-site/sub-dir/some.R b/internal/inspect/detectors/testdata/rmd-site/sub-dir/some.R new file mode 100644 index 000000000..9dd657a91 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/sub-dir/some.R @@ -0,0 +1,3 @@ +# Another + +Here is another page. It links to [index](index.html) and [article](article.html). diff --git a/internal/inspect/detectors/testdata/rmd-site/test/.publisher-env b/internal/inspect/detectors/testdata/rmd-site/test/.publisher-env new file mode 100644 index 000000000..d4c977a97 --- /dev/null +++ b/internal/inspect/detectors/testdata/rmd-site/test/.publisher-env @@ -0,0 +1,6 @@ +CONTENT_TYPE=quarto +APP_MODE=quarto-static +ENTRYPOINT=index.Rmd +TITLE="rmd-site" +RENV_REQUIRED=yes +QUARTO_ENGINE=knitr \ No newline at end of file diff --git a/internal/util/files.go b/internal/util/files.go index 4b693bfc1..2a8c30049 100644 --- a/internal/util/files.go +++ b/internal/util/files.go @@ -8,6 +8,8 @@ import ( "strings" ) +var KnownSiteYmlConfigFiles = []string{"_site.yml", "_site.yaml", "_bookdown.yml", "_bookdown.yaml"} + func Chdir(dir string) (string, error) { oldWd, err := os.Getwd() if err != nil {