att_amend_desc() no longer writes nearly every
dependency out of DESCRIPTION when the package carries a
Depends: entry other than R that the code scan
no longer finds. The guard around that branch tested the column
count of a data frame, so it held even with no row kept, and the branch
then took the complement of an empty selection with
x[-which(...), ], which in R keeps nothing rather than
everything. On a package with eleven declared dependencies, two
survived. The only visible trace was a message reading
Package(s) is(are) in category 'Depends' with an empty
list. The guard now counts rows, and the complement is taken by negating
the logical test, which is correct on an empty frame instead of correct
by accident (#146).att_from_rscript() (and therefore
att_amend_desc()) no longer reports a variable name as a
package name. requireNamespace(),
loadNamespace() and the ns argument of
getFromNamespace() take a character string, so a bare
symbol there can only be a variable holding the name, never the name
itself; the same goes for library() and
require() when the call passes
character.only = TRUE. A guard such as
for (pkg in c("callr", "jsonlite")) requireNamespace(pkg, quietly = TRUE)
used to add a package literally called pkg to
DESCRIPTION, which then stopped every renv /
pak install on a package that cannot exist. A symbol is
still read as the package name for library(),
require() and use(), which compute on the
unevaluated argument (#143).library(pkgvar, char = TRUE), went unrecognised and added a
package named after the variable; and an abbreviated package argument,
library(pack = "jsonlite"), was missed altogether. The
formals are read from the running R rather than written down here, and a
formal placed after ... is matched by its exact name only,
which is R’s own rule (#143).att_amend_desc() no longer lets an
Enhances version constraint override the
Imports one for the same package. The rule that picks a
version when a package is pinned under two types ordered the type as
text, and "Enhances" sorts before "Imports",
so Enhances: pkg (>= 9.9.9) replaced
Imports: pkg (>= 2.0.0) and wrote a bound nobody had set
for that type, which can make a package uninstallable. The precedence is
now named explicitly, strongest first: Imports, Depends, LinkingTo,
Suggests, Enhances.att_amend_desc() no longer counts a removal twice, nor
names the package twice, when DESCRIPTION lists it under two dependency
types. The list read by the comparison holds one row per (type, package)
pair, so a package pinned under both Imports and
Suggests produced
[-] 2 package(s) removed: pkgA, pkgA for a single
removal.att_amend_desc() never drops a version constraint set
by hand in DESCRIPTION. A package that no scanned source mentions used
to be removed and its constraint to go with it, and a package listed in
pkg_ignore used to be removed too, although
pkg_ignore means “do not infer this from code” and not
“delete what I wrote”. Such an entry is now kept as declared, with its
type and its version, and reported so the decision is visible. Widening
dir.r makes it a detected dependency again; removing its
constraint lets it go. A bare entry, with no version,
is still removed: there is nothing to lose, and pkg_ignore
stays usable for cleaning a wrong entry out. An Imports
kept this way while no code uses it draws
All declared Imports should be used from R CMD check, which
reports a real defect of the package being amended that dropping the pin
used to conceal (#139).renv::lockfile_read() instead of reaching into renv with
getFromNamespace("lockfile", "renv"), which stopped working
when renv 1.2.4 changed that internal. renv moves from
Suggests: renv (>= 0.8.4) to
renv (>= 1.0.0), the version that introduced the public
lockfile functions.att_amend_desc() now accepts several directories in
dir.r, for example
att_amend_desc(dir.r = c("R", "inst")). This lets you
declare dependencies used only outside the standard package directories,
such as a deployment entry point under inst/, which the
default scan does not reach. Passing a vector previously raised
the condition has length > 1 (#139).att_amend_desc() no longer drops a version constraint
set by hand in DESCRIPTION when the same package is listed under two
types (a pinned Imports and a bare Suggests,
for instance). Previously the version that survived depended on the
order of the rows in DESCRIPTION; the hand-set constraint is now kept,
and when both an Imports and a Suggests row
carry a version the Imports one wins (#140).att_from_examples() (and therefore
att_amend_desc()) no longer chokes on inline R inside
roxygen2 markdown tags such as @param x \r
helper(“x”)`whenhelper()is a package-local function. Previously,att_from_examples()delegated toroxygen2::parse_file(), which evaluated inline R againstbaseenv()(roxygen2's fallback when no package env is registered) — base R is reachable, but package-local helpers are not, so each affected tag emittedcould
not find function “helper”`. Example detection now uses a focused regex
over the source instead of the full roxygen2 tokenizer (#135).att_from_rscript() now walks the R syntax tree instead
of matching the source text with regexes. Dependency detection no longer
produces false positives on :: inside string literals or
comments (e.g. xpath following-sibling::td, CSS
label::after, sprintf('%s::plot()', ...))
(#120, #132).x[, 1], x[1, ], empty switch
alternatives, missing else branches). Earlier development
drafts of the walker crashed with
argument "el" is missing, with no default on any script
containing these patterns, which would have silently degraded every
real-world script to the legacy regex fallback.att_from_rscript() also recognises
use("pkg", ...) (R >= 4.4) (#128),
getFromNamespace("fn", "pkg"),
loadNamespace(), and named-argument forms such as
library(package = "pkg") or
requireNamespace("pkg", lib.loc = "...").base::library(pkg),
base::requireNamespace("pkg"), and
methods::getFromNamespace(fn, "pkg") are now honoured; the
inner package is added to the dependency list.packageVersion(),
getNamespace(), asNamespace(),
attachNamespace()) are intentionally not
treated as dependency introducers to avoid silently widening
Imports on code that only uses them for feature
detection.att_from_rscript() gains an encoding
argument (default getOption("encoding")) so scripts saved
in Latin-1 / Windows-1252 are read with the system locale instead of
being forced to UTF-8.att_from_rscript() now warns when a file fails to parse
as valid R code and the legacy regex-based detector is used as a
fallback, so broken scripts are no longer silently degraded.my_pkg::fn). Previously an underscore
truncated the detected name to the portion after the underscore, so a
single syntax error upstream could corrupt detection across the whole
file.att_from_rmds() infers the vignette engine from the
files actually present: quarto is added when
.qmd files are found, rmarkdown when
.Rmd files are found, both when the directory mixes the
two. Previously rmarkdown was forced in for
.qmd-only projects (#131).att_from_rmd() / att_from_rmds():
inside_rmd now defaults to NULL and is
auto-detected via knitr::opts_knit$get("out.format"), so
users no longer have to think about it (#106).{fusen} development workflow;
R/amend_with_config.R,
R/create_dependencies_file.R,
R/dependencies_file_text.R and their tests are now
hand-maintained.create_renv_for_dev() by removing
'renv' from folder_to_include.dev/manual_detection_edge_cases.R covering ~170 scripted
cases (true positives, false positives, known limitations) to make
future regressions of the detector obvious.att_from_examples() Removed escape characters
(\) from Roxygen examples.att_from_examples() Fixed the selection of
.R files in the source directory. (#124)att_from_examples() to get all packages called in
examples from R filesatt_from_data() to look for functions called in
data loading codeatt_amend_desc amend package DESCRIPTION file
(Suggests) with the list of dependencies extracted from examples in R
files.set_remotes_to_desc() takes into account the
branchatt_from_rmds() and att_from_rscript
doesn’t search in ‘renv’ folder anymorecreate_renv_for_dev can work even outside of an R
packagesatt_amend_desc and att_from_namespace return
messages instead of warnings. (@MurielleDelmotte)When using att_amend_desc() without the default
parameters, like pkg_ignore = "x" will now require
att_amend_desc(pkg_ignore = "x", update.config = TRUE),
otherwise, it will fail. This allows for the use of parameters stored in
the config file when running att_amend_desc() directly in
the console. Recommendation: Run
att_amend_desc(pkg_ignore = "x", update.config = TRUE) if
you have to update your config, run att_amend_desc() daily
as you’ll want to use what is stored in the config file.
create_dependencies_file() gets parameter
install_only_if_missing = FALSE by default to complete the
installation instructions packages only if missing. (@MurielleDelmotte)
att_amend_desc() can run with the last set of
parameters stored in a configuration file, without having to call them
all each time. See vignettes and documentation of parameters
update.config = FALSE, use.config = FALSE and
path.c = "dev/config_attachment.yaml". (@dagousket)create_dependencies_file() now takes other sources into
account (git, gitlab, github, bioc, local). (@MurielleDelmotte)create_dependencies_file(to = NULL) to only get the
output as character and do not create a fileatt_amend_desc() does not modify user
options("warn") level anymore (#94)att_amend_desc() allows “Remotes” field to contain
@ref (#67)find_remotes() now informs when using “r-universe”
repositories.check_if_suggests_is_installed in
att_amend_desc() allow not to check if suggested package is
installed. (thanks to @yogat3ch)create_renv_for_prod() don’t look anymore for suggested
packagesfind_remotes() and set_remotes_to_desc()
now detects github, gitlab, git, bitbucket, local installations to add
to the “Remotes:” part of the DESCRIPTION file (@MurielleDelmotte)att_from_qmds() as
an alias of att_from_rmds().att_amend_desc()
#52create_renv_for_dev() and
create_renv_for_prod() function to create
renv.lock file based on development project (@VincentGuyader and
@statnmap).att_from_rmds().att_amend_desc() now saves file before processing\n will not interfere with package
discoveryatt_to_desc_from_is() can now run
with must.exist = FALSE to be used to fill DESCRIPTION file
during bookdown CI process. CI YAML files must be updated with this
parameter.set_remotes_to_desc(clean = TRUE)set_remotes_to_desc()att_from_rscripts()att_amend_desc(document = TRUE)att_amend_desc()att_from_namespace()att_from_rmd()Breaking changes * att_to_description() deprecated in
favor of att_amend_desc() to be first in autocompletion
list, as this is the most used function of this package. *
att_from_rmd() gets parameter inline = TRUE by
default to explore calls for packages in inline R code. *
att_from_rmd() and att_from_rmds() are not
anymore executed in separate R session by default. You must set
inside_rmd = TRUE to do so.
Minor * Add find_remotes() to help fill Remotes field in
DESCRIPTION * att_to_desc_from_is() add parameter
normalize to avoid problem with {desc}. (See
https://github.com/r-lib/desc/issues/80)
att_amend_desc() is an alias for
att_to_description()att_desc_from_is() amends DESCRIPTION file from
imports/suggests vector of packagesatt_to_desc_from_pkg() is an alias for
att_to_description()att_to_description() shows packages added/removed from
DESCRIPTIONatt_to_description() deals with dependencies in tests/
directoryatt_from_rmds() allows user defined regex to detect Rmd
filesatt_from_rmd adds a temporary encoding parameter as
knitr::purl will only deal with UTF-8 in the future.
Parameter not added in att_from_rmds.att_to_description if {covr} is needed, should be added
in parameter extra.suggestsatt_to_description has a parameter ‘dir.t’ to extract
suggests dependencies from test directory Available by
defaultatt_to_description allows for ‘LinkingTo’ field in
DESCRIPTION with a messageatt_from_rmd now reads yaml headeratt_from_rmd use purl to extract R code in
an other R session using system("Rscript -e ''")att_from_rmd: add warn option to allow
hide messages from purl()att_to_description accept parameter path
for package not being the current projectatt_to_description no error if NAMESPACE is emptycreate_dependencies_file filters base packages that
cannot be installedatt_to_description deals with Remote dependenciesatt_to_description deals with Depends dependenciesatt_to_description keeps versions of packages
previously addedatt_to_description removes option for automatic pkg
versioncreate_dependencies_file deals with github Remotesatt_from_rmds now accept a vector of Rmd filenamesatt_to_description(add_version = TRUE) adds version of
package in DESCRIPTIONatt_to_description(pkg_ignore) adds possibility to
ignore some packagesinstall_from_description to install all
missing packages listed in the description fileatt_to_descriptioncreate_dependencies_file to create a file listing
all packages dependencies to dinstall before your packagepkg::fun calls in R scripts with
att_from_functionsdevtools::document() before
att_from_descriptionNEWS.md file to track changes to the
package.