diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..bfe7068 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,15 @@ +^.*\.Rproj$ +^CITATION\.cff$ +^LICENSE\.md$ +^Meta$ +^README\.Rmd$ +^\.Rproj\.user$ +^\.github$ +^\.lintr$ +^\.pre-commit-config\.yaml$ +^_pkgdown\.yml$ +^codecov\.yml$ +^doc$ +^docs$ +^pkgdown$ +^tools$ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..13d495a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.bib -linguist-detectable diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5766126 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 0000000..38bde78 --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,22 @@ +repository: + # https://probot.github.io/apps/settings/ + allow_merge_commit: false + allow_rebase_merge: true + allow_squash_merge: true + default_branch: main + delete_branch_on_merge: true + # has_discussions: false + has_issues: true + # has_projects: false + # has_wiki: false + # private: false +branches: + - name: main + # https://docs.github.com/en/rest/reference/repos#update-branch-protection + protection: + required_pull_request_reviews: + required_approving_review_count: 0 # (1-6; optionally 0) + dismiss_stale_reviews: true + require_code_owner_reviews: false + required_status_checks: + strict: true diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..62b0eff --- /dev/null +++ b/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,94 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# +# Reproduce locally by running: +# ```r +# pak::pak(c("any::rcmdcheck", "."), dependencies = "Config/Needs/check") +# rcmdcheck::rcmdcheck() +# ``` +on: + push: + branches: [main, master] + paths: + - 'data/**' + - 'R/**' + - 'inst/**' + - 'man/**' + - 'src/**' + - 'tests/**' + - 'vignettes/**' + - 'DESCRIPTION' + - 'NAMESPACE' + - 'LICENSE' + - '.Rbuildignore' + - '.github/workflows/R-CMD-check.yaml' + merge_group: + pull_request: + paths: + - 'data/**' + - 'R/**' + - 'inst/**' + - 'man/**' + - 'src/**' + - 'tests/**' + - 'vignettes/**' + - 'DESCRIPTION' + - 'NAMESPACE' + - 'LICENSE' + - '.Rbuildignore' + - '.github/workflows/R-CMD-check.yaml' + +name: R-CMD-check + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macOS-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + id: rcmdcheck + with: + upload-snapshots: true + error-on: '"note"' + + # fail-fast but only if rcmdcheck step fails + - name: Manual fail-fast + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: always() && steps.rcmdcheck.outcome == 'failure' + run: gh run cancel ${{ github.run_id }} diff --git a/.github/workflows/dependency-change.yaml b/.github/workflows/dependency-change.yaml new file mode 100644 index 0000000..ef26e66 --- /dev/null +++ b/.github/workflows/dependency-change.yaml @@ -0,0 +1,82 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + pull_request: + paths: + - 'DESCRIPTION' + +name: Analyze dependency changes + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + pull-requests: write + +jobs: + dependency-changes: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Setup R + uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - name: Install dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + packages: any::pak, glue, gh + + - name: Analyze dependency changes + shell: Rscript {0} + run: | + deps_base <- pak::pkg_deps("${{ github.repository }}@${{ github.base_ref }}", dependencies = TRUE) |> + subset(!directpkg) |> + subset(is.na(priority)) + # We install from PR number rather than branch to deal with the case + # of PR coming from forks + deps_head <- pak::pkg_deps("${{ github.repository }}#${{ github.event.number }}", dependencies = TRUE) |> + subset(!directpkg) |> + subset(is.na(priority)) + + deps_added <- deps_head |> + subset(!ref %in% deps_base$ref) + + deps_removed <- deps_base |> + subset(!ref %in% deps_head$ref) + + if (nrow(deps_added) + nrow(deps_removed) > 0) { + + message("Dependencies have changed! Analyzing...") + + if (nrow(deps_added) > 0) { + nudge <- "Reach out on slack (`#code-review` or `#help` channels) to double check if there are base R alternatives to the new dependencies.\n" + } else { + nudge <- "" + } + + msg <- glue::glue( + .sep = "\n", + "This pull request:", + "- Adds {nrow(deps_added)} new dependencies (direct and indirect)", + "- Adds {length(unique(deps_added$sysreqs))} new system dependencies", + "- Removes {nrow(deps_removed)} existing dependencies (direct and indirect)", + "- Removes {length(unique(deps_removed$sysreqs))} existing system dependencies", + "", + nudge, + "(Note that results may be inaccurate if you branched from an outdated version of the target branch.)" + ) + + message("Posting results as a pull request comment.") + + gh::gh( + "POST /repos/{repo}/issues/{issue_number}/comments", + repo = "${{ github.repository }}", + issue_number = "${{ github.event.number }}", + body = msg + ) + + } diff --git a/.github/workflows/lint-changed-files.yaml b/.github/workflows/lint-changed-files.yaml new file mode 100644 index 0000000..cf5c34b --- /dev/null +++ b/.github/workflows/lint-changed-files.yaml @@ -0,0 +1,53 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + workflow_dispatch: + pull_request: + branches: [main, master] + paths: + - '**.R' + - '**.Rmd' + - '**/.lintr' + - '**/.lintr.R' + +name: lint-changed-files + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint-changed-files: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: | + any::gh + any::lintr + any::purrr + any::cyclocomp + epiverse-trace/etdev + needs: check + + - name: Install package + run: R CMD INSTALL . + + - name: Extract and lint files changed by this PR + run: | + files <- gh::gh("/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files") + changed_files <- purrr::map_chr(files, "filename") + all_files <- list.files(recursive = TRUE) + exclusions_list <- as.list(setdiff(all_files, changed_files)) + lintr::lint_package(exclusions = exclusions_list) + shell: Rscript {0} + env: + LINTR_ERROR_ON_LINT: true diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 0000000..fc97843 --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,90 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# +# Reproduce locally by running: +# ```r +# pak::pak(c("any::pkgdown", "."), dependencies = "Config/Needs/website") +# pkgdown::build_site() +# ``` +on: + push: + branches: [main, master] + paths: + - 'README.Rmd' + - 'README.md' + - 'index.Rmd' + - 'index.md' + - 'man/**' + - 'vignettes/**' + - '_pkgdown.yml' + - 'pkgdown/**' + - 'DESCRIPTION' + - '.Rbuildignore' + - '.github/**' + merge_group: + pull_request: + paths: + - 'README.Rmd' + - 'README.md' + - 'index.Rmd' + - 'index.md' + - 'man/**' + - 'vignettes/**' + - '_pkgdown.yml' + - 'pkgdown/**' + - 'DESCRIPTION' + - '.Rbuildignore' + - '.github/**' + release: + types: [published] + workflow_dispatch: + +name: pkgdown + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + pkgdown: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Check website links + uses: untitaker/hyperlink@0.1.32 + with: + args: docs/ + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'merge_group' && github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.6.1 + with: + # We clean on releases because we want to remove old vignettes, + # figures, etc. that have been deleted from the `main` branch. + # But we clean ONLY on releases because we want to be able to keep + # both the 'stable' and 'dev' websites. + # Also discussed in https://github.com/r-lib/actions/issues/484 + clean: ${{ github.event_name == 'release' }} + branch: gh-pages + folder: docs diff --git a/.github/workflows/render_readme.yml b/.github/workflows/render_readme.yml new file mode 100644 index 0000000..10f5eaa --- /dev/null +++ b/.github/workflows/render_readme.yml @@ -0,0 +1,96 @@ +# Reproduce locally by running: +# ```r +# pak::pak(c("any::rmarkdown", "any::usethis", ".")) +# writeLines( +# knitr::knit_expand( +# "README.Rmd", +# packagename = read.dcf("DESCRIPTION", "Package"), +# gh_repo = usethis:::github_remote_list()$repo_spec +# ), +# "README_expanded.Rmd" +# ) +# rmarkdown::render( +# "README_expanded.Rmd", +# output_file = "README.md", +# output_dir = "." +# ) +# unlink("README_expanded.Rmd") +# ``` +name: render-readme + +# Controls when the action will run. Triggers include: +# +# - button trigger from github action page +# - on changes to readme.Rmd + +on: + workflow_dispatch: + push: + branches: + # This may seem like a no-op but it prevents triggering on tags + # We use '**' rather '*' to accomodate names like 'dev/branch-1' + - '**' + paths: + - 'README.Rmd' + - '.github/workflows/render_readme.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + render-readme: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout repos + uses: actions/checkout@v4 + + - name: Setup R + uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - name: Setup pandoc + uses: r-lib/actions/setup-pandoc@v2 + + - name: Install dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rmarkdown, local::. + + - name: Compile the readme + run: | + writeLines( + knitr::knit_expand( + "README.Rmd", + packagename = read.dcf("DESCRIPTION", "Package"), + gh_repo = Sys.getenv("GITHUB_REPOSITORY") + ), + "README_expanded.Rmd" + ) + rmarkdown::render( + "README_expanded.Rmd", + output_file = "README.md", + output_dir = "." + ) + shell: Rscript {0} + + - name: Commit files + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add README.md + # Also add README figures if they exist + if [ -d man/figures ] + then + git add man/figures/ + fi + git diff-index --quiet HEAD || git commit -m "Automatic readme update" + git pull --rebase origin ${{ github.ref.name }} + git push origin || echo "No changes to push" diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..afd8f04 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,85 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# +# Reproduce locally by running: +# ```r +# pak::pak("any::covr", dependencies = "Config/Needs/coverage") +# covr::codecov(quiet = FALSE) +# ``` +on: + push: + branches: [main, master] + paths: + - 'R/**' + - 'src/**' + - 'tests/**' + - 'inst/**' + - 'DESCRIPTION' + - '.github/workflows/test-coverage.yaml' + merge_group: + pull_request: + paths: + - 'R/**' + - 'src/**' + - 'tests/**' + - 'inst/**' + - 'DESCRIPTION' + - '.github/workflows/test-coverage.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +name: test-coverage + +permissions: read-all + +jobs: + test-coverage: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr, any::xml2 + needs: coverage + + - name: Test coverage + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + covr::to_cobertura(cov) + shell: Rscript {0} + + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/.github/workflows/update-citation-cff.yaml b/.github/workflows/update-citation-cff.yaml new file mode 100644 index 0000000..82b118a --- /dev/null +++ b/.github/workflows/update-citation-cff.yaml @@ -0,0 +1,59 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# The action runs when: +# - The DESCRIPTION or inst/CITATION are modified +# - Can be run manually +# For customizing the triggers, visit https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows +on: + push: + branches: + - main + paths: + - DESCRIPTION + - inst/CITATION + - .github/workflows/update-citation-cff.yaml + workflow_dispatch: + +name: Update CITATION.cff +permissions: + contents: write + pull-requests: write + +jobs: + update-citation-cff: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + - uses: r-lib/actions/setup-r@v2 + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: | + any::cffr + any::V8 + + - name: Update CITATION.cff + run: | + + library(cffr) + + # Customize with your own code + # See https://docs.ropensci.org/cffr/articles/cffr.html + + # Write your own keys + mykeys <- list() + + # Create your CITATION.cff file + cff_write(keys = mykeys) + + shell: Rscript {0} + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + commit-message: Update `CITATION.cff` + title: Update `CITATION.cff` + body: | + This pull request updates the citation file, ensuring all authors are credited and there are no discrepancies. + + Please verify the changes before merging. + branch: update-citation-cff diff --git a/.github/workflows/update-copyright-year.yml b/.github/workflows/update-copyright-year.yml new file mode 100644 index 0000000..b4633b3 --- /dev/null +++ b/.github/workflows/update-copyright-year.yml @@ -0,0 +1,37 @@ +name: Update copyright year(s) in license file + +on: + workflow_dispatch: + schedule: + - cron: '0 3 1 1 *' + +permissions: + contents: write + pull-requests: write + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: FantasticFiasco/action-update-license-year@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + path: | + LICENSE.md + prBody: > + This PR updates the copyright license for this new year! If you're reading this while you're celebrating, enjoy! Don't worry about this one :blush: + + ![Happy new year!](https://media.giphy.com/media/HyDfNCZlTn5iU/giphy.gif?cid=ecf05e4777yl7dbo1xfha6bx1z5lrl13uq7biv6rs9dqsyoh&ep=v1_gifs_search&rid=giphy.gif&ct=g) + - uses: FantasticFiasco/action-update-license-year@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + path: | + LICENSE + prBody: > + This PR updates the copyright license for this new year! If you're reading this while you're celebrating, enjoy! Don't worry about this one :blush: + + ![Happy new year!](https://media.giphy.com/media/HyDfNCZlTn5iU/giphy.gif?cid=ecf05e4777yl7dbo1xfha6bx1z5lrl13uq7biv6rs9dqsyoh&ep=v1_gifs_search&rid=giphy.gif&ct=g) + transform: (?<=YEAR:\s)(?\d{4})?-?(\d{4})? diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..310a47d --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# History files +.Rhistory +.Rapp.history + +# Session Data files +.RData +.RDataTmp + +# User-specific files +.Ruserdata + +# Example code in package build process +*-Ex.R + +# Output files from R CMD build +/*.tar.gz + +# Output files from R CMD check +/*.Rcheck/ + +# RStudio files +.Rproj.user/ + +# vignette building +/doc/ +/Meta/ + +# produced vignettes +vignettes/*.html +vignettes/*.pdf + +# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 +.httr-oauth + +# knitr and R markdown default cache directories +*_cache/ +/cache/ + +# Temporary files created by R markdown +*.utf8.md +*.knit.md + +# R Environment Variables +.Renviron + +# pkgdown site +docs/ + +# translation temp files +po/*~ + +# RStudio Connect folder +rsconnect/ + +# macOS hidden files +.DS_Store +inst/doc diff --git a/.lintr b/.lintr new file mode 100644 index 0000000..9670d32 --- /dev/null +++ b/.lintr @@ -0,0 +1,39 @@ +linters: all_linters( + packages = c("lintr", "etdev"), + pipe_consistency_linter(pipe = "%>%"), + object_name_linter = NULL, + implicit_integer_linter = NULL, + extraction_operator_linter = NULL, + todo_comment_linter = NULL, + library_call_linter = NULL, + undesirable_function_linter( + modify_defaults( + default_undesirable_functions, + citEntry = "use the more modern bibentry() function", + library = NULL # too many false positive in too many files + ) + ), + function_argument_linter = NULL, + indentation_linter = NULL, # unstable as of lintr 3.1.0 + # Use minimum R declared in DESCRIPTION or fall back to current R version. + # Install etdev package from https://github.com/epiverse-trace/etdev + backport_linter(if (length(x <- etdev::extract_min_r_version())) x else getRversion()) + ) +exclusions: list( + "tests/testthat.R" = list( + unused_import_linter = Inf + ), + "tests" = list( + undesirable_function_linter = Inf + ), + "data-raw" = list( + missing_package_linter = Inf, + namespace_linter = Inf + ), + # RcppExports.R is auto-generated and will not pass many linters. In + # particular, it can create very long lines. + "R/RcppExports.R", + # R/stanmodels.R is auto-generated and will not pass many linters. In + # particular, it uses `sapply()`. + "R/stanmodels.R" + ) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0da7464 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,24 @@ +# All available hooks: https://pre-commit.com/hooks.html +# R specific hooks: https://github.com/lorenzwalthert/precommit +repos: +- repo: https://github.com/lorenzwalthert/precommit + rev: v0.4.2 + hooks: + - id: style-files + args: [--style_pkg=styler, --style_fun=tidyverse_style] + - id: roxygenize + - id: use-tidy-description + - id: parsable-R + - id: no-browser-statement + - id: no-debug-statement + - id: deps-in-desc + - id: pkgdown +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-added-large-files + args: ['--maxkb=700'] + - id: file-contents-sorter + files: '^\.Rbuildignore$' + - id: end-of-file-fixer + exclude: '\.Rd' diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..68c8058 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,37 @@ +Package: packagetemplate +Title: Your Package Title in Titlecase +Version: 0.0.1 +Authors@R: c( + person("James M.", "Azam", , "james.azam@lshtm.ac.uk", role = "aut", + comment = c(ORCID = "0000-0001-5782-7330")), + person("Hugo", "Gruson", , "hugo@data.org", role = c("aut", "cre"), + comment = c(ORCID = "0000-0002-4094-1476")), + person("Pratik", "Gupte", , "pratik.gupte@lshtm.ac.uk", role = "aut", + comment = c(ORCID = "0000-0001-5294-7819")), + person("Joshua W.", "Lambert", , "joshua.lambert@lshtm.ac.uk", role = "aut", + comment = c(ORCID = "0000-0001-5218-3046")), + person("Karim", "Mané", , "karim.mane@lshtm.ac.uk", role = "aut", + comment = c(ORCID = "0000-0002-9892-2999")), + person("Jaime A.", "Pavlich-Mariscal", , "jpavlich@javeriana.edu.co", role = "ctb", + comment = c(ORCID = "0000-0002-3892-6680")), + person("Chris", "Hartgerink", , "chris@data.org", role = "ctb", + comment = c(ORCID = "0000-0003-1050-6809")) + ) +Description: Your package description. It must end with a period (".") and + include relevant bibliographical references if applicable, using the + following format: Author et al. (2023) . +License: MIT + file LICENSE +Suggests: + knitr, + rmarkdown, + spelling, + testthat (>= 3.0.0) +VignetteBuilder: + knitr +Config/Needs/website: epiverse-trace/epiversetheme +Config/testthat/edition: 3 +Config/testthat/parallel: true +Encoding: UTF-8 +Language: en-GB +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c3fc0e --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2022 +COPYRIGHT HOLDER: the package authors diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6599f3f --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2022 the package authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..6ae9268 --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,2 @@ +# Generated by roxygen2: do not edit by hand + diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..d342220 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,5 @@ +# 0.1.0 + +* This project now includes a + [`NEWS.md`](https://r-pkgs.org/other-markdown.html#sec-news) file to inform + users about changes and new features. diff --git a/R/dev-utils.R b/R/dev-utils.R new file mode 100644 index 0000000..b37c5f4 --- /dev/null +++ b/R/dev-utils.R @@ -0,0 +1,11 @@ +# This unexported function adds a custom item to `usethis::use_release_issue()` +release_bullets <- function() { + + c( + "Run `goodpractice::gp()`", + "Review [WORDLIST](https://docs.cran.dev/spelling#wordlist)", + "Check if `# nolint` comments are still needed with recent lintr releases", + "All contributors to this release are acknowledged in some way" + ) + +} diff --git a/R/package.R b/R/package.R new file mode 100644 index 0000000..33c81e2 --- /dev/null +++ b/R/package.R @@ -0,0 +1,8 @@ +# https://usethis.r-lib.org/reference/use_package_doc.html + +#' @keywords internal +"_PACKAGE" + +## usethis namespace: start +## usethis namespace: end +NULL diff --git a/README.Rmd b/README.Rmd new file mode 100644 index 0000000..6ed6f51 --- /dev/null +++ b/README.Rmd @@ -0,0 +1,72 @@ +--- +output: github_document +--- + + + + + + + + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "man/figures/README-", + out.width = "100%" +) +``` + +# {{ packagename }} + + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit/) +[![R-CMD-check](https://github.com/{{ gh_repo }}/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/{{ gh_repo }}/actions/workflows/R-CMD-check.yaml) +[![Codecov test coverage](https://codecov.io/gh/{{ gh_repo }}/branch/main/graph/badge.svg)](https://app.codecov.io/gh/{{ gh_repo }}?branch=main) +[![lifecycle-concept](https://raw.githubusercontent.com/reconverse/reconverse.github.io/master/images/badge-concept.svg)](https://www.reconverse.org/lifecycle.html#concept) + + +{{ packagename }} provides functions to .... + + +{{ packagename }} is developed at the [CENTER|similar](url) at the [UNIVERSITY|similar](url) as part of the [Epiverse-TRACE program](https://data.org/initiatives/epiverse/). + +## Installation + +You can install the development version of {{ packagename }} from +[GitHub](https://github.com/) with: + +``` r +# install.packages("pak") +pak::pak("{{ gh_repo }}") +``` + +## Example + +These examples illustrate some of the current functionalities + + +## Development + +### Lifecycle + +This package is currently a *concept*, as defined by the [RECON software +lifecycle](https://www.reconverse.org/lifecycle.html). This means that essential +features and mechanisms are still being developed, and the package is not ready +for use outside of the development team. + +### Contributions + +Contributions are welcome via [pull requests](https://github.com/{{ gh_repo }}/pulls). + +### Related projects + +This project is related to other existing projects in R or other languages, but also differs from them in the following aspects: + + +### Code of Conduct + +Please note that the {{ packagename }} project is released with a +[Contributor Code of Conduct](https://github.com/epiverse-trace/.github/blob/main/CODE_OF_CONDUCT.md). +By contributing to this project, you agree to abide by its terms. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bb195c5 --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ + + + + + + + +# {{ packagename }} + + + +[![License: +MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit/) +[![R-CMD-check](https://github.com/%7B%7B%20gh_repo%20%7D%7D/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/%7B%7B%20gh_repo%20%7D%7D/actions/workflows/R-CMD-check.yaml) +[![Codecov test +coverage](https://codecov.io/gh/%7B%7B%20gh_repo%20%7D%7D/branch/main/graph/badge.svg)](https://app.codecov.io/gh/%7B%7B%20gh_repo%20%7D%7D?branch=main) +[![lifecycle-concept](https://raw.githubusercontent.com/reconverse/reconverse.github.io/master/images/badge-concept.svg)](https://www.reconverse.org/lifecycle.html#concept) + + +{{ packagename }} provides functions to …. + + + +{{ packagename }} is developed at the CENTER at the UNIVERSITY as part +of the [Epiverse-TRACE program](https://data.org/initiatives/epiverse/). + +## Installation + +You can install the development version of {{ packagename }} from +[GitHub](https://github.com/) with: + +``` r +# install.packages("pak") +pak::pak("{{ gh_repo }}") +``` + +## Example + +These examples illustrate some of the current functionalities + +## Development + +### Lifecycle + +This package is currently a *concept*, as defined by the [RECON software +lifecycle](https://www.reconverse.org/lifecycle.html). This means that +essential features and mechanisms are still being developed, and the +package is not ready for use outside of the development team. + +### Contributions + +Contributions are welcome via [pull +requests](https://github.com/%7B%7B%20gh_repo%20%7D%7D/pulls). + +### Related projects + +This project is related to other existing projects in R or other +languages, but also differs from them in the following aspects: + +- + +### Code of Conduct + +Please note that the {{ packagename }} project is released with a +[Contributor Code of +Conduct](https://github.com/epiverse-trace/.github/blob/main/CODE_OF_CONDUCT.md). +By contributing to this project, you agree to abide by its terms. diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..bfd72c7 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,12 @@ +# FIXME: The url field needs to be updated to contain the URL of the website +# where the package documentation is hosted +# (e.g., https://epiverse-trace.github.io/pkg). +url: ~ +template: + package: epiversetheme + +# It is recommended to add a pkgdown reference index, grouping the different +# function into logical sections (e.g., modules). +# It is also recommended to rely on selector such as `starts_with()` or +# `ends_with()` to create this index as it is a good way to force yourself into +# using a consistent naming convention for your functions. diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..04c5585 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +comment: false + +coverage: + status: + project: + default: + target: auto + threshold: 1% + informational: true + patch: + default: + target: auto + threshold: 1% + informational: true diff --git a/inst/WORDLIST b/inst/WORDLIST new file mode 100644 index 0000000..ad08587 --- /dev/null +++ b/inst/WORDLIST @@ -0,0 +1,21 @@ +CMD +Codecov +Epiverse +Lifecycle +Mariscal +ORCID +Pavlich +RECON +Titlecase +codecov +com +doi +gh +github +io +lifecycle +packagename +svg +tidyverse +yaml +zenodo diff --git a/man/figures/logo.svg b/man/figures/logo.svg new file mode 100644 index 0000000..b1a2f55 --- /dev/null +++ b/man/figures/logo.svg @@ -0,0 +1,1600 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/man/packagetemplate-package.Rd b/man/packagetemplate-package.Rd new file mode 100644 index 0000000..8499b1b --- /dev/null +++ b/man/packagetemplate-package.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/package.R +\docType{package} +\name{packagetemplate-package} +\alias{packagetemplate} +\alias{packagetemplate-package} +\title{packagetemplate: Your Package Title in Titlecase} +\description{ +Your package description. It must end with a period (".") and include relevant bibliographical references if applicable, using the following format: Author et al. (2023) \doi{10.5281/zenodo.6619350}. +} +\author{ +\strong{Maintainer}: Hugo Gruson \email{hugo@data.org} (\href{https://orcid.org/0000-0002-4094-1476}{ORCID}) + +Authors: +\itemize{ + \item James M. Azam \email{james.azam@lshtm.ac.uk} (\href{https://orcid.org/0000-0001-5782-7330}{ORCID}) + \item Pratik Gupte \email{pratik.gupte@lshtm.ac.uk} (\href{https://orcid.org/0000-0001-5294-7819}{ORCID}) + \item Joshua W. Lambert \email{joshua.lambert@lshtm.ac.uk} (\href{https://orcid.org/0000-0001-5218-3046}{ORCID}) + \item Karim Mané \email{karim.mane@lshtm.ac.uk} (\href{https://orcid.org/0000-0002-9892-2999}{ORCID}) +} + +Other contributors: +\itemize{ + \item Jaime A. Pavlich-Mariscal \email{jpavlich@javeriana.edu.co} (\href{https://orcid.org/0000-0002-3892-6680}{ORCID}) [contributor] +} + +} +\keyword{internal} diff --git a/tests/spelling.R b/tests/spelling.R new file mode 100644 index 0000000..647406c --- /dev/null +++ b/tests/spelling.R @@ -0,0 +1,7 @@ +if (requireNamespace("spelling", quietly = TRUE)) { + spelling::spell_check_test( + vignettes = TRUE, + error = TRUE, + skip_on_cran = TRUE + ) +} diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..df57fd9 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,12 @@ +# This file is part of the standard setup for testthat. +# It is recommended that you do not modify it. +# +# Where should you do additional test configuration? +# Learn more about the roles of various files in: +# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview +# * https://testthat.r-lib.org/articles/special-files.html + +library(testthat) +library(packagetemplate) + +test_check("packagetemplate", stop_on_warning = FALSE) diff --git a/tests/testthat/helper-state.R b/tests/testthat/helper-state.R new file mode 100644 index 0000000..4910faa --- /dev/null +++ b/tests/testthat/helper-state.R @@ -0,0 +1,26 @@ +# This helper ensures the package does not modify the session global state. As +# per CRAN policy, packages should not interfere with the user's session state. +# If global settings need to be modified, they should be restored to their +# original values on exit. This can be achieved with the `on.exit()` base +# function, or more conveniently with the `withr` package. +# We add a test on R >= 4.0.0 because some functions such as +# `globalCallingHandlers()` did not exist before. +if (getRversion() >= "4.0.0") { + testthat::set_state_inspector(function() { + list( + attached = search(), + connections = getAllConnections(), + cwd = getwd(), + envvars = Sys.getenv(), + handlers = globalCallingHandlers(), + libpaths = .libPaths(), + locale = Sys.getlocale(), + options = options(), + par = par(), + packages = .packages(all.available = TRUE), + sink = sink.number(), + timezone = Sys.timezone(), + NULL + ) + }) +} diff --git a/tests/testthat/setup-options.R b/tests/testthat/setup-options.R new file mode 100644 index 0000000..4ca3f1c --- /dev/null +++ b/tests/testthat/setup-options.R @@ -0,0 +1,7 @@ +# We want to flag partial matching as part of our testing & continuous +# integration process because it makes code more brittle. +options( + warnPartialMatchAttr = TRUE, + warnPartialMatchDollar = TRUE, + warnPartialMatchArgs = TRUE +) diff --git a/tests/testthat/test-dev-utils.R b/tests/testthat/test-dev-utils.R new file mode 100644 index 0000000..4e0a9a6 --- /dev/null +++ b/tests/testthat/test-dev-utils.R @@ -0,0 +1,5 @@ +test_that("release_bullets() returns what usethis expects", { + + expect_type(release_bullets(), "character") + +}) diff --git a/tools/check.env b/tools/check.env new file mode 100644 index 0000000..b279420 --- /dev/null +++ b/tools/check.env @@ -0,0 +1,18 @@ +# Do not report if package size is larger than 5 megabytes +_R_CHECK_PKG_SIZES_=false + +# Do not check Rd cross references +_R_CHECK_RD_XREFS_=false + +# Do not report if package requires GNU make +# https://github.com/epiverse-trace/packagetemplate/issues/119 +# https://github.com/r-lib/rcmdcheck/pull/219 +_R_CHECK_CRAN_INCOMING_NOTE_GNU_MAKE_=true + +# Do not check non-ASCII strings in datasets +_R_CHECK_PACKAGE_DATASETS_SUPPRESS_NOTES_=true + +# Exists since R 4.3.0 but `false` by default. +# https://bugs.r-project.org/show_bug.cgi?id=18419 +# Warn when using : with an element of length more than one +_R_CHECK_LENGTH_COLON_=true diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/design-principles.Rmd b/vignettes/design-principles.Rmd new file mode 100644 index 0000000..1bdf189 --- /dev/null +++ b/vignettes/design-principles.Rmd @@ -0,0 +1,48 @@ +--- +title: "Design Principles for {packagetemplate}" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Design Principles for {packagetemplate}} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +This vignette outlines the design decisions that have been taken during the development of the `{packagetemplate}` R package, and provides some of the reasoning, and possible pros and cons of each decision. + +This document is primarily intended to be read by those interested in understanding the code within the package and for potential package contributors. + + + +## Scope + +< Outline the aims of the package, potentially mention some of the key exported functions, and maybe how it links with other R packages. It is also possible to mention certain aspects that fall outside of the package's scope. > + +## Naming conventions + +< Description of the scheme and/or conventions used for naming functions and arguments. This can be the use of a prefix on all exported functions, a name mould ("all function are named verb_object"), or any other naming convention that is used throughout the package. > + +## Input/Output/Interoperability + +< Describe the data structures (i.e. vectors, `` or classes) that are given as input to the key functions and what data structures the functions return. The design decisions around these I/O choices could also mention how it enhances interoperability with other R packages or pipelines (e.g. with `%>%`). > + + +## Design decisions + +< A list of bullet points each explaining a design decision and its reasoning. > + +## Dependencies + +< A list of dependencies used by the package with some explanation as to why they are required. Not all dependencies need to be explained and it is best to explain the key dependencies. It can be used to give context to why certain dependencies are used (e.g. "This package is expected to be used in tidyverse pipelines and as such, we consider these tidyverse packages good dependencies that will already be installed on a user's computer."). This section can also mention dependencies that are planned to be removed or added in future development. Suggested dependencies do not need to be explained unless they are unusual and may surprise developers with their inclusion. > + +## Development journey + +< If the package has undergone any large refactoring this section can be used to explain the changes. >