all_check_groups() and checks_by_group() functions for discovering and selecting checks by category instead of individual names (#239).all_check_groups() to see the 16 available groups and checks_by_group("description") to list checks in a group.describe_check_groups() function, to produce group descriptions in console (#290).print() method, to enable printing only specified groups (#288).goodpractice.exclude_check_groups option or GP_EXCLUDE_CHECK_GROUPS environment variable.default_checks() and tidyverse_checks() helper functions.gp() now defaults to default_checks() instead of all_checks(), keeping optional check sets out of the default run.describe_check() function to print descriptions of all implemented checks (@152)goodpractice.exclude_path option or GP_EXCLUDE_PATH environment variable. Useful for generated code like R/RcppExports.R.gp strings support {.code}, {.fn}, {.pkg}, {.file}, {.field}, and {.url} for consistent styling. Custom checks can use the same markup in their gp strings.gp_advice() gains a type parameter ("error", "info", "warning") to control the output symbol and colour. Checks can return list(status = TRUE, type = "info") to display informational messages without a failure cross.getParseData(). Checks like print_return_invisible, tidyverse_no_missing, and tidyverse_export_order benefit from more robust and faster code analysis.<-, =, <<-), avoiding false matches on arithmetic expressions such as x + function() 1 (#277).ts_parse() now honours the package's declared Encoding when reading source files, preventing mojibake for packages using non-UTF-8 encodings.duplicate_function_bodies check: flags functions with identical bodies across files that should be consolidated into a shared helper (#232).anyDuplicated() vs any(duplicated())), performance (e.g. colSums() vs apply()), readability (e.g. switch() vs long if/else chains), and testthat best practices (e.g. expect_identical() vs expect_equal()). All respect .lintr configuration files (#189).lintr_installed_packages_linter check: flags calls to installed.packages(),
which can be very slow and is rejected by CRAN. Use find.package() or system.file() instead (#278).checks = c(default_checks(), tidyverse_checks()).prep_description defaults Encoding to UTF-8 when absent, so downstream checks always have a concrete value. Unreadable files emit a warning instead of being silently skipped (#277).description_not_start_with_package: Description should not start with "This package"description_urls_in_angle_brackets: URLs in Description must be wrapped in angle bracketsdescription_doi_format: DOIs should use <doi:...> not full URLsdescription_urls_not_http: URLs should use https not httpno_description_duplicate_deps: No duplicate packages across dependency fieldsdescription_valid_roles: Authors@R roles must be valid MARC relator codesdescription_pkgname_single_quoted: Package names in Title/Description must be single-quotedr_file_extension check: flags R scripts using .r or .q instead of .R (#121).print_return_invisible check: flags print methods that don't return invisible(x) (#49).vignette_no_rm_list check: flags rm(list = ls()) in vignettes (#20).vignette_no_setwd check: flags setwd() in vignettes (#21).reverse_dependencies check: queries CRAN for reverse dependencies and advises running revdepcheck::revdep_check() before submission.spelling check: flags misspelled words in documentation via spelling::spell_check_package() (#84).has_readme and has_news checks for package documentation completeness (#45).@inheritParams/@inheritDotParams validation (#197).makefile (#203)goodpractice.cyclocomp_limit option (#150).future.apply package. Set future::plan("multisession") before calling gp() to enable parallel data gathering (#47).gp() now fails if the path provided to it is not a package (does not contain a DESCRIPTION file) (#190, @maelle)run_prep_step() helper. New prep functions can use run_prep_step(state, "name", function() { ... }, quiet) instead of manually wrapping work in try() and emitting warnings on failure.stringsAsFactors = FALSE arguments throughout, relying on the R 4.0 default. Package now requires R >= 4.0.0.use_skill_gp() and learn_skill_gp() functions, plus a bundled goodpractice4agents.md skill in inst/skills/, giving AI agents instructions to fix issues flagged by goodpractice (#308, #312, #313; thanks to @mpadge, @drmowinckels, and @jonthegeek).tidyverse_r_file_names: allow file names containing hyphens (-) but require file extension .R (#307; thanks to @JesseAlderliesten).warning() in ts_parse() to cli::cli_warn(), completing the package-wide move to cli messaging.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:
LICENSE, and LICENSE.md added to clarify that {goodpractice} uses the MIT license (#144).First CRAN release.
First public release.