diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml deleted file mode 100644 index 0b26021..0000000 --- a/.github/workflows/pkgdown.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# 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: - push: - branches: [main, master] - pull_request: - branches: [main, master] - release: - types: [published] - workflow_dispatch: - -name: pkgdown - -jobs: - pkgdown: - runs-on: ubuntu-latest - # Only restrict concurrency for non-PR jobs - concurrency: - group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v2 - - - 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: Deploy to GitHub pages 🚀 - if: github.event_name != 'pull_request' - uses: JamesIves/github-pages-deploy-action@4.1.4 - with: - clean: false - branch: gh-pages - folder: docs diff --git a/DESCRIPTION b/DESCRIPTION index 746e574..f77e5b0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: goodpractice Title: Advice on R Package Building -Version: 1.0.4.010 +Version: 1.0.4.012 Authors@R: c( person(given = "Mark", diff --git a/codemeta.json b/codemeta.json index f8ae0e5..99609b9 100644 --- a/codemeta.json +++ b/codemeta.json @@ -8,7 +8,7 @@ "codeRepository": "https://github.com/ropensci-review-tools/goodpractice", "issueTracker": "https://github.com/ropensci-review-tools/goodpractice/issues", "license": "https://spdx.org/licenses/MIT", - "version": "1.0.4.010", + "version": "1.0.4.012", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", diff --git a/docs/404.html b/docs/404.html deleted file mode 100644 index 6cc38c1..0000000 --- a/docs/404.html +++ /dev/null @@ -1,125 +0,0 @@ - - -
- - - - -YEAR: 2021 -COPYRIGHT HOLDER: Mango Solutions -- -
Copyright (c) 2021 Mango Solutions
-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.
-vignettes/custom_checks.Rmd
- custom_checks.Rmd
By default, the goodpractice()
function and its alias gp()
run all the checks available in the package (use all_checks()
to show all checks implemented). In addition, users can provide their own custom checks.
gp()
?
-The gp()
function essentially carries out two types of steps:
The results of the preparation steps and the checks are added to the return object, also referred to as the state. The print method accesses the check results and prints the advice for the failed checks - or praise if none fail.
-Custom checks can be created with the make_check()
function. As inputs it takes a short description
of the check, the check
itself, and the gp
advice to be given in case the check fails. To illustrate this, let’s use a simplified version of the check on T
and F
instead of TRUE
and FALSE
.
The check
argument is a function which takes the state as the input and carries out the check, returning TRUE
if the check was successful. The state includes the path to the source code of the package and the checkTnF()
function of the tools package can be used to check if T
or F
was used.
-library(goodpractice)
-
-# make a simple version of the T/F check
-check_simple_tf <- make_check(
-
- description = "TRUE and FALSE is used, not T and F",
- gp = "avoid 'T' and 'F', use 'TRUE' and 'FALSE' instead.",
- check = function(state) {
- length(tools::checkTnF(dir = state$path)) == 0
- }
-)
Additional checks can be used in gp()
via the extra_checks
argument. This should be a named list of check
objects as returned by the make_check()
function. All checks to be carried out, regardless of whether they are provided by the goodpractice package or custom checks, must be named in the checks
argument to gp()
.
The check on T
/F
implemented in the package gives more helpful advice than this simplified version and returns which files contain T
and F
so let’s do a quick comparison and run both versions:
-# get path to example package
-pkg_path <- system.file("bad1", package = "goodpractice")
-gp(pkg_path, checks = c("simple_tf", "truefalse_not_tf"),
- extra_checks = list(simple_tf = check_simple_tf))
-#> -- GP badpackage ---------------------------------------------------------------
-#>
-#> It is good practice to
-#>
-#> <U+2716> avoid 'T' and 'F', use 'TRUE' and 'FALSE' instead.
-#> <U+2716> avoid 'T' and 'F', as they are just variables which are set
-#> to the logicals 'TRUE' and 'FALSE' by default, but are not reserved
-#> words and hence can be overwritten by the user. Hence, one should
-#> always use 'TRUE' and 'FALSE' for the logicals.
-#>
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> ... and 4 more lines
-#>
-#> --------------------------------------------------------------------------------
Including a preparation step is optional but can be helpful if several checks require the same preparations upfront. In the following example we check for two different fields to be present in the DESCRIPTION file, the URL field and the BugReports field. Both checks can be carried out easily building on a preparation step with the desc package for handling DESCRIPTION files.
-The checks are linked to the preparation via the prep name: it appears as the name
argument to make_prep()
, as the preps
argument to make_check()
and finally as the name in the list for the extra_preps
argument to gp()
.
-# prep: process DESCRIPTION file
-desc_fun <- function(path, quiet) {
- desc::description$new(path)
-}
-
-prep_desc <- make_prep(name = "desc", func = desc_fun)
-
-# check for an URL field
-check_url <- make_check(
- description = "URL field in DESCRIPTION",
- preps = "desc",
- gp = "have a URL field in DESCRIPTION",
- check = function(state) state$desc$has_fields("URL")
-)
-
-# check for a BugReport field
-check_bugreports <- make_check(
- description = "BugReports in DESCRIPTION",
- preps = "desc",
- gp = "add a BugReports field to DESCRIPTION",
- check = function(state) state$desc$has_fields('BugReports')
-)
-
-# run the two checks with their corresponding prep step
-gp(pkg_path, checks = c("url", "bugreports"),
- extra_preps = list("desc" = prep_desc),
- extra_checks = list("url" = check_url, "bugreports" = check_bugreports))
-#> Preparing: desc
-#> -- GP badpackage ---------------------------------------------------------------
-#>
-#> It is good practice to
-#>
-#> <U+2716> have a URL field in DESCRIPTION
-#> <U+2716> add a BugReports field to DESCRIPTION
-#> --------------------------------------------------------------------------------
More examples for using custom checks can be found in the rOpenSci unconf 2017 project checkers for automated checking of best practices for research compendia.
-vignettes/goodpractice.Rmd
- goodpractice.Rmd
Building an R package is a great way of encapsulating code, documentation and data in a single testable and easily distributable unit.
-For a package to be distributed via CRAN, it needs to pass a set of checks implemented in R CMD check
, such as: Is there minimal documentation, e.g., are all arguments of exported functions documented? Are all dependencies declared?
These checks are helpful in developing a solid R package but they don’t check for several other good practices. For example, a package does not need to contain any tests but is it good practice to include such. Following a coding standard helps readability. Avoiding overly complex functions reduces the risk of bugs. Including an URL for bug reports lets people more easily report bugs if they find any.
-Tools for automatically checking several of these aspects already exist and the goodpractice package bundles the checks from rcmdcheck with code coverage through the covr package, source code linting via the lintr package and cyclomatic complexity via the cyclocomp package and augments it with some further checks on good practice for R package development such as avoiding T
and F
in favour of TRUE
and FALSE
. It provides advice on which practices to follow and which to avoid.
You can use goodpractice checks as a reminder for you and your colleagues - and if you have custom checks to run, you can make goodpractice run those as well! Please see the vignette “Custom Checks” for more details.
-The main function is goodpractice()
and has an alias gp()
which takes the path to the source code of a package as its first argument. The goodpractice package contains the source for a simple package which violates some good practices. We’ll use this for the examples.
library(goodpractice)
-
-# get path to example package
-<- system.file("bad1", package = "goodpractice")
- pkg_path
-# run gp() on it
-<- gp(pkg_path)
- g #> Preparing: covr
-#> Warning in MYPREPS[[prep]](state, quiet = quiet): Prep step for test coverage
-#> failed.
-#> Preparing: cyclocomp
-#> Skipping 1 packages not available: goodpractice
-#>
-
-
- for file 'C:\Users\daniel.debortoli\AppData\Local\Temp\Rtmp6XhRBV\remotesbaccca184\badpackage/DESCRIPTION' ...
- checking
- for file 'C:\Users\daniel.debortoli\AppData\Local\Temp\Rtmp6XhRBV\remotesbaccca184\badpackage/DESCRIPTION' ...
- checking
- 38;5;247mchecking for file 'C:\Users\daniel.debortoli\AppData\Local\Temp\Rtmp6XhRBV\remotesbaccca184\badpackage/DESCRIPTION'
[39m
[36m
[39m
-
[32mv
[39m
[#>
-
-
-
- 38;5;247m-
[39m
[38;5;247m
[39m
[38;5;247mpreparing 'badpackage':
[39m
[36m
[39m
-
[#> checking DESCRIPTION meta-information ...
-
- -information ...
- checking DESCRIPTION meta
- 38;5;247mchecking DESCRIPTION meta-information
[39m
[36m
[39m
-
[32mv
[39m
[#>
-
-
-
- -information ...
- checking vignette meta
- -information ...
- checking vignette meta
- 38;5;247mchecking vignette meta-information
[39m
[36m
[39m
-
[32mv
[39m
[#>
-
-
-
- 38;5;247m-
[39m
[38;5;247m
[39m
[38;5;247mchecking for LF line-endings in source and make files and shell scripts
[39m
[36m
[39m
-
[#>
-
-
-
- 38;5;247m-
[39m
[38;5;247m
[39m
[38;5;247mchecking for empty or unneeded directories
[39m
[36m
[39m
-
[#>
-
-
-
- 38;5;247m-
[39m
[38;5;247m
[39m
[38;5;247mbuilding 'badpackage_1.0.0.tar.gz'
[39m
[36m
[39m
-
[#>
-
-
- #>
-#> Preparing: description
-#> Preparing: lintr
-#> Preparing: namespace
-#> Preparing: rcmdcheck
-#> pdflatex not found! Not building PDF manual.
-
-# show the result
-
- g#>
[33m-- GP badpackage ---------------------------------------------------------------
[39m
-#>
-#>
[1mIt is good practice to
[22m
-#>
-#>
[31m<U+2716>
[39m not use "Depends" in DESCRIPTION, as it can cause name
-#> clashes, and poor interaction with other packages. Use "Imports"
-#> instead.
-#>
[31m<U+2716>
[39m omit "Date" in DESCRIPTION. It is not required and it gets
-#> invalid quite often. A build date will be added to the package when
-#> you perform `R CMD build` on it.
-#>
[31m<U+2716>
[39m add a "URL" field to DESCRIPTION. It helps users find
-#> information about your package online. If your package does not
-#> have a homepage, add an URL to GitHub, or the CRAN package package
-#> page.
-#>
[31m<U+2716>
[39m add a "BugReports" field to DESCRIPTION, and point it to a
-#> bug tracker. Many online code hosting services provide bug trackers
-#> for free, https://github.com, https://gitlab.com, etc.
-#>
[31m<U+2716>
[39m omit trailing semicolons from code lines. They are not
-#> needed and most R coding standards forbid them
-#>
-#>
[34mR\semicolons.R
[39m:
[34m4
[39m:
[34m30
[39m
-#>
[34mR\semicolons.R
[39m:
[34m5
[39m:
[34m29
[39m
-#>
[34mR\semicolons.R
[39m:
[34m9
[39m:
[34m38
[39m
-#>
-#>
[31m<U+2716>
[39m not import packages as a whole, as this can cause name
-#> clashes between the imported packages. Instead, import only the
-#> specific functions you need.
-#>
[31m<U+2716>
[39m fix this R CMD check ERROR: VignetteBuilder package not
-#> declared: 'knitr' See section 'The DESCRIPTION file' in the
-#> 'Writing R Extensions' manual.
-#>
[31m<U+2716>
[39m avoid 'T' and 'F', as they are just variables which are set
-#> to the logicals 'TRUE' and 'FALSE' by default, but are not reserved
-#> words and hence can be overwritten by the user. Hence, one should
-#> always use 'TRUE' and 'FALSE' for the logicals.
-#>
-#>
[34mR/tf.R
[39m:
[34mNA
[39m:
[34mNA
[39m
-#>
[34mR/tf.R
[39m:
[34mNA
[39m:
[34mNA
[39m
-#>
[34mR/tf.R
[39m:
[34mNA
[39m:
[34mNA
[39m
-#>
[34mR/tf.R
[39m:
[34mNA
[39m:
[34mNA
[39m
-#>
[34mR/tf.R
[39m:
[34mNA
[39m:
[34mNA
[39m
-#>
[34m ... and 4 more lines
-#>
[39m
-#>
[33m--------------------------------------------------------------------------------
[39m
So with this package, we’ve done a few things in the DESCRIPTION file for which there are reasons not to do them, have unnecessary trailing semicolons in the code and used T
and F
for TRUE
and FALSE
. The output of gp()
tells you what you did that isn’t considered good practice and if it’s in the R code, it points you the location of your faux-pas. In general, the messages are supposed to not only point out to you what you might want to avoid but also why.
The above example tries to run all 230 checks available, to see the full list use all_checks()
. If you only want to run a subset of the checks, e.g., the one on the URL field in the DESCRIPTION, you can specify the checks by name:
-# what is the name of the check?
-grep("url", all_checks(), value = TRUE)
-#> [1] "description_url"
-
-# run only this check
-g_url <- gp(pkg_path, checks = "description_url")
-#> Preparing: description
-
-g_url
-#> -- GP badpackage ---------------------------------------------------------------
-#>
-#> It is good practice to
-#>
-#> <U+2716> add a "URL" field to DESCRIPTION. It helps users find
-#> information about your package online. If your package does not
-#> have a homepage, add an URL to GitHub, or the CRAN package package
-#> page.
-#> --------------------------------------------------------------------------------
Apart from printing a goodPractice
object as returned by gp()
to access the advice, you can also access which checks were carried out and which of those failed:
-# which checks were carried out?
-checks(g_url)
-#> [1] "description_url"
-
-# which checks failed?
-failed_checks(g)
-#> [1] "no_description_depends"
-#> [2] "no_description_date"
-#> [3] "description_url"
-#> [4] "description_bugreports"
-#> [5] "lintr_trailing_semicolon_linter"
-#> [6] "no_import_package_as_a_whole"
-#> [7] "rcmdcheck_package_dependencies_present"
-#> [8] "truefalse_not_tf"
To access all the checks carried out with their results in a data frame, use results()
on your goodPractice
object.
-# show the first 5 checks carried out and their results
-results(g)[1:5,]
-#> check result
-#> 1 covr NA
-#> 2 cyclocomp TRUE
-#> 3 no_description_depends FALSE
-#> 4 no_description_date FALSE
-#> 5 description_url FALSE
Note that the code coverage could not be calculated. The corresponding check does not show up in the failed checks (because it was not carried out) and the result is NA
. It is also possible to export the results to a JSON file with export_json()
.
Give advice about good practices when building R packages. Advice includes functions and syntax to avoid, package structure, code complexity, code formatting, etc.
-You can install the release version from CRAN
-
-install.packages("goodpractice")
and the development version from GitHub
-
-source("https://install-github.me/MangoTheCat/goodpractice")
-# or
-# install.packages("devtools")
-devtools::install_github("mangothecat/goodpractice")
-library(goodpractice)
-gp("<my-package>")
-library(goodpractice)
-# use example package contained in the goodpractice package
-pkg_path <- system.file("bad1", package = "goodpractice")
-g <- gp(pkg_path)
#>
-#> * checking for file ‘/private/var/folders/f3/gr9my1s97r3654cmvzc6dngm0000gn/T/Rtmp6Kts8C/remotesa3ff1315cc49/badpackage/DESCRIPTION’ ... OK
-#> * preparing ‘badpackage’:
-#> * checking DESCRIPTION meta-information ... OK
-#> * checking vignette meta-information ... OK
-#> * checking for LF line-endings in source and make files and shell scripts
-#> * checking for empty or unneeded directories
-#> * building ‘badpackage_1.0.0.tar.gz’
-g
#> ── GP badpackage ───────────────────────────────────────────────────────────────
-#>
-#> It is good practice to
-#>
-#> ✖ not use "Depends" in DESCRIPTION, as it can cause name clashes, and
-#> poor interaction with other packages. Use "Imports" instead.
-#> ✖ omit "Date" in DESCRIPTION. It is not required and it gets invalid
-#> quite often. A build date will be added to the package when you
-#> perform `R CMD build` on it.
-#> ✖ add a "URL" field to DESCRIPTION. It helps users find information
-#> about your package online. If your package does not have a
-#> homepage, add an URL to GitHub, or the CRAN package package page.
-#> ✖ add a "BugReports" field to DESCRIPTION, and point it to a bug
-#> tracker. Many online code hosting services provide bug trackers for
-#> free, https://github.com, https://gitlab.com, etc.
-#> ✖ omit trailing semicolons from code lines. They are not needed and
-#> most R coding standards forbid them
-#>
-#> R/semicolons.R:4:30
-#> R/semicolons.R:5:29
-#> R/semicolons.R:9:38
-#>
-#> ✖ not import packages as a whole, as this can cause name clashes
-#> between the imported packages. Instead, import only the specific
-#> functions you need.
-#> ✖ fix this R CMD check ERROR: VignetteBuilder package not declared:
-#> ‘knitr’ See section ‘The DESCRIPTION file’ in the ‘Writing R
-#> Extensions’ manual.
-#> ✖ avoid 'T' and 'F', as they are just variables which are set to the
-#> logicals 'TRUE' and 'FALSE' by default, but are not reserved words
-#> and hence can be overwritten by the user. Hence, one should always
-#> use 'TRUE' and 'FALSE' for the logicals.
-#>
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> R/tf.R:NA:NA
-#> ... and 4 more lines
-#>
-#> ────────────────────────────────────────────────────────────────────────────────
-# show all available checks
-# all_checks()
-
-# run only a specific check
-g_url <- gp(pkg_path, checks = "description_url")
-g_url
#> ── GP badpackage ───────────────────────────────────────────────────────────────
-#>
-#> It is good practice to
-#>
-#> ✖ add a "URL" field to DESCRIPTION. It helps users find information
-#> about your package online. If your package does not have a
-#> homepage, add an URL to GitHub, or the CRAN package package page.
-#> ────────────────────────────────────────────────────────────────────────────────
-# which checks were carried out?
-checks(g_url)
#> [1] "description_url"
-# which checks failed?
-failed_checks(g)
#> [1] "no_description_depends"
-#> [2] "no_description_date"
-#> [3] "description_url"
-#> [4] "description_bugreports"
-#> [5] "lintr_trailing_semicolon_linter"
-#> [6] "no_import_package_as_a_whole"
-#> [7] "rcmdcheck_package_dependencies_present"
-#> [8] "truefalse_not_tf"
-# show the first 5 checks carried out and their results
-results(g)[1:5,]
#> check result
-#> 1 covr NA
-#> 2 cyclocomp TRUE
-#> 3 no_description_depends FALSE
-#> 4 no_description_date FALSE
-#> 5 description_url FALSE
NEWS.md
- Additions:
-goodpractice.cyclocomp.limit
option, default 50 (#132, @fabian-s).positions_limit
parameter into print()
- previously it was always 5 lines (#130, @fabian-s).Bugfixes:
-List the names of all checks
-all_checks()
Character vector of checks
-List all checks performed
-checks(gp)
gp
output.
Character vector of check names.
-Other API:
-failed_checks()
,
-results()
path <- system.file("bad1", package = "goodpractice")
-# run a subset of all checks available
-g <- gp(path, checks = all_checks()[3:16])
-#> Preparing: description
-#> Preparing: lintr
-#> Preparing: namespace
-checks(g)
-#> [1] "no_description_depends" "no_description_date"
-#> [3] "description_url" "description_bugreports"
-#> [5] "lintr_assignment_linter" "lintr_line_length_linter"
-#> [7] "lintr_trailing_semicolon_linter" "lintr_attach_detach_linter"
-#> [9] "lintr_setwd_linter" "lintr_sapply_linter"
-#> [11] "lintr_library_require_linter" "lintr_seq_linter"
-#> [13] "no_import_package_as_a_whole" "no_export_pattern"
-
Defining custom preparations and checks
-make_prep(name, func)
-
-make_check(description, check, gp, ...)
Name of the preparation function.
A function that takes two arguments:
-The path
to the root directory of the package, and a logical
-argument: quiet
. If quiet
is true, the preparation function
-may print out diagnostic messages. The output of this function will be
-saved as the " name
" entry of state
, i.e. of the input for
-the check
-functions (see example).
A description of the check.
A function that takes the state
as an argument.
A short description of what is good practice.
Further arguments. Most important: A preps
argument that
-contains the names of all the preparation functions required for the check.
make_prep
: Create a preparation function
make_check
: Create a check function
# make a preparation function
-url_prep <- make_prep(
- name = "desc",
- func = function(path, quiet) desc::description$new(path)
-)
-# and the corresponding check function
-url_chk <- make_check(
- description = "URL field in DESCRIPTION",
- tags = character(),
- preps = "desc",
- gp = "have a URL field in DESCRIPTION",
- check = function(state) state$desc$has_fields("URL")
-)
-# use together in gp():
-# (note that you have to list the name of your custom check in
-# the checks-argument as well....)
-bad1 <- system.file("bad1", package = "goodpractice")
-res <- gp(bad1, checks = c("url", "no_description_depends"),
- extra_preps = list("desc" = url_prep),
- extra_checks = list("url" = url_chk))
-#> Preparing: desc
-#> Preparing: description
-
Default pattern for R files
-default_r_file_pattern()
Regular expression.
-Names of the failed checks
-failed_checks(gp)
gp
output.
Names of the failed checks.
-path <- system.file("bad1", package = "goodpractice")
-# run a subset of all checks available
-g <- gp(path, checks = all_checks()[3:16])
-#> Preparing: description
-#> Preparing: lintr
-#> Preparing: namespace
-failed_checks(g)
-#> [1] "no_description_depends" "no_description_date"
-#> [3] "description_url" "description_bugreports"
-#> [5] "lintr_trailing_semicolon_linter" "no_import_package_as_a_whole"
-
Note that not all checks refer to the source code.
-For these the result will be NULL
.
failed_positions(gp)
gp
output.
A list of lists of positions. See details below.
-For the ones that do, the results is a list, one for each failure.
-Since the same check can fail multiple times. A single failure
-is a list with entries: filename
, line_number
,
-column_number
, ranges
. ranges
is a list of
-pairs of start and end positions for each line involved in the
-check.
Get a marker from the positions of a check
-get_marker(gp, check)
gp()
output
name of the check to extract
Give advice about good practices when building R packages. Advice includes -functions and syntax to avoid, package structure, code complexity, code -formatting, etc.
-Useful links:
To see the results, just print it to the screen.
-gp(
- path = ".",
- checks = all_checks(),
- extra_preps = NULL,
- extra_checks = NULL,
- quiet = TRUE
-)
Path to a package root.
Character vector, the checks to run. Defaults to
-all checks. Use all_checks
to list all checks.
Custom preparation functions. See
-make_prep
on creating preparation functions.
Custom checks. See make_check
on
-creating checks.
Whether to suppress output from the preparation
-functions. Note that not all preparation functions produce output,
-even if this option is set to FALSE
.
A goodpractice object that you can query
-with a simple API. See results
to start.
path <- system.file("bad1", package = "goodpractice")
-# run a subset of all checks available
-g <- gp(path, checks = all_checks()[3:16])
-#> Preparing: description
-#> Preparing: lintr
-#> Preparing: namespace
-g
-#> -- GP badpackage ---------------------------------------------------------------
-#>
-#> It is good practice to
-#>
-#> <U+2716> not use "Depends" in DESCRIPTION, as it can cause name
-#> clashes, and poor interaction with other packages. Use "Imports"
-#> instead.
-#> <U+2716> omit "Date" in DESCRIPTION. It is not required and it gets
-#> invalid quite often. A build date will be added to the package when
-#> you perform `R CMD build` on it.
-#> <U+2716> add a "URL" field to DESCRIPTION. It helps users find
-#> information about your package online. If your package does not
-#> have a homepage, add an URL to GitHub, or the CRAN package package
-#> page.
-#> <U+2716> add a "BugReports" field to DESCRIPTION, and point it to a
-#> bug tracker. Many online code hosting services provide bug trackers
-#> for free, https://github.com, https://gitlab.com, etc.
-#> <U+2716> omit trailing semicolons from code lines. They are not
-#> needed and most R coding standards forbid them
-#>
-#> R\semicolons.R:4:30
-#> R\semicolons.R:5:29
-#> R\semicolons.R:9:38
-#>
-#> <U+2716> not import packages as a whole, as this can cause name
-#> clashes between the imported packages. Instead, import only the
-#> specific functions you need.
-#> --------------------------------------------------------------------------------
-
- All functions- - |
- |
---|---|
- - | -List the names of all checks |
-
- - | -List all checks performed |
-
- - | -Defining custom preparations and checks |
-
- - | -Export failed checks to JSON |
-
- - | -Names of the failed checks |
-
- - | -Positions of check failures in the source code |
-
- - | -goodpractice: Advice on R Package Building |
-
- - | -Run good practice checks |
-
- - | -Print goodpractice results |
-
- - | -Return all check results in a data frame |
-
Create a check function
- -make_check(description, check, gp, ...)- -
description | -A description of the check. |
-
---|---|
check | -A function that takes the |
-
gp | -A short description of what is good practice. |
-
... | -Further arguments. |
-
-# make a preparation function -url_prep <- make_prep( - name = "desc", - func = function(path, quiet) desc::description$new(path) -) -# and the corresponding check function -url_chk <- make_check( - description = "URL field in DESCRIPTION", - tags = character(), - preps = "desc", - gp = "have a URL field in DESCRIPTION", - check = function(state) state$desc$has_fields("URL") -) -# use together in gp() -bad1 <- system.file("bad1", package = "goodpractice") -res <- gp(bad1, checks = "no_description_depends", - extra_preps = list("desc" = url_prep), - extra_checks = list("url" = url_chk))#>
Create a preparation function
- -make_prep(name, func)- -
name | -Name of the preparation function. |
-
---|---|
func | -A function that takes two arguments:
-The |
-
-# make a preparation function -url_prep <- make_prep( - name = "desc", - func = function(path, quiet) desc::description$new(path) -) -# and the corresponding check function -url_chk <- make_check( - description = "URL field in DESCRIPTION", - tags = character(), - preps = "desc", - gp = "have a URL field in DESCRIPTION", - check = function(state) state$desc$has_fields("URL") -) -# use together in gp() -bad1 <- system.file("bad1", package = "goodpractice") -res <- gp(bad1, checks = "no_description_depends", - extra_preps = list("desc" = url_prep), - extra_checks = list("url" = url_chk))#>
Wrapper on make_check, specific to R CMD check
-make_rcmd_check(
- description,
- pattern,
- gp = NULL,
- type = c("warnings", "notes", "errors"),
- tags = NULL,
- preps = NULL,
- ...
-)
A description of the check.
The text pattern identifying the check.
Type of notification, one of "warnings", "notes" or "errors".
Tags to be passed on to make_check.
Preps to be passed on to make_check.
Currently not supported.
NULL
is returned if there is no such field.
package_collate(path = ".")
Path to the package root.
Character scalar or NULL
.
The package must be extracted into the working directory, as usual.
-prep_expressions(state, version = NULL, quiet)
GP state.
Currently ignored.
The modified state, with the closures in a named list.
-We can use lintr to extract the functions, but need to use -our own code (based on similar code in functionMap) to -get the right collation order.
-Print goodpractice results
-# S3 method for goodPractice
-print(x, positions_limit = 5, ...)
Object of class goodPractice
, as returned by gp()
.
How many positions to print at most.
Unused, for compatibility with base::print()
generic method.
R/prep_expressions.R
- r_package_files.Rd
It uses the Collate
entry in the DESCRIPTION
file,
-if there is one. Otherwise the order is alphabetical.
r_package_files(path)
Path to the root of the R package.
A character vector of (relative) file -names in the current collation order.
-Return all check results in a data frame
-results(gp)
gp
output.
Data frame, with columns:
-The name of the check.
Logical, whether it has failed or not.
Other API:
-checks()
,
-failed_checks()
path <- system.file("bad1", package = "goodpractice")
-# run a subset of all checks available
-g <- gp(path, checks = all_checks()[3:16])
-#> Preparing: description
-#> Preparing: lintr
-#> Preparing: namespace
-results(g)
-#> check result
-#> 1 no_description_depends FALSE
-#> 2 no_description_date FALSE
-#> 3 description_url FALSE
-#> 4 description_bugreports FALSE
-#> 5 lintr_assignment_linter TRUE
-#> 6 lintr_line_length_linter TRUE
-#> 7 lintr_trailing_semicolon_linter FALSE
-#> 8 lintr_attach_detach_linter TRUE
-#> 9 lintr_setwd_linter TRUE
-#> 10 lintr_sapply_linter TRUE
-#> 11 lintr_library_require_linter TRUE
-#> 12 lintr_seq_linter TRUE
-#> 13 no_import_package_as_a_whole FALSE
-#> 14 no_export_pattern TRUE
-
Find occurrences of 1:length(x)
, 1:nrow(x)
,
-1:ncol(x)
, 1:NROW(x)
, 1:NCOL(x)
where
-x
is an R expression.
seq_linter(source_file)
Parse data. Passed from lintr.
Lint object.
-