Summary
att_amend_desc() should never drop a version constraint that was already set
by hand in DESCRIPTION. Today, a pinned package can lose its version (or be
removed entirely) when it is no longer detected by the code scan.
Current behaviour
In R/att_to_description.R, att_to_desc_from_is() rebuilds the dependency
list from the packages detected in the scanned code (R/, tests/,
vignettes/), then re-attaches versions with a left join on the previous
DESCRIPTION:
deps_new <- data.frame(type = ..., package = all_packages) %>%
merge(deps_orig[, c("package", "version")],
by = "package", all.x = TRUE, all.y = FALSE)
Consequence: the version is kept only for packages that the scan re-detects.
A package that is pinned in DESCRIPTION but not (or no longer) found by the
scan is not in all_packages, so it is removed from the output entirely, and
its version pin disappears with it, silently.
When it bites
Packages that are real runtime dependencies but live outside the scanned paths,
typically inst/ (which attachment does not scan). A common pattern:
- a deployment entry point
inst/main.R uses pkgA (>= 1.2.0) via pkgA::fn();
pkgA is declared in Imports with the pin so it ends up in the built
image / lockfile;
- running
att_amend_desc() (e.g. from a dev/ maintenance script) rewrites
DESCRIPTION and drops pkgA and its >= 1.2.0, because the scan never saw
it.
More generally, any manually curated version constraint (build/CI-only deps,
packages referenced only by string, packages used only under inst/) is at
risk on the next att_amend_desc() run.
Minimal repro
# DESCRIPTION Imports: somedep (>= 2.0.0), where somedep is used only in inst/main.R
attachment::att_amend_desc()
# -> somedep is removed from Imports; the ">= 2.0.0" pin is lost, no warning
Expected behaviour
att_amend_desc() should not silently discard a version constraint that a
maintainer already set. Options, from least to most invasive:
- Warn when a previously pinned dependency is about to be removed or have
its version dropped, listing the affected packages.
- Preserve the version string for any package that keeps an explicit
version in the current DESCRIPTION, even if the scan did not re-detect it
(i.e. keep the pin rather than resetting to * or dropping the package).
- An opt-in argument (e.g.
keep_versions = TRUE / keep_pinned = TRUE) to
guarantee that existing version constraints survive the amend, for teams that
pin on purpose and scan-detection is incomplete.
The key invariant: a hand-set version in DESCRIPTION should survive
att_amend_desc() unless the maintainer explicitly asks to remove it.
Context
Seen on R packages deployed through a shared factory, where the production
entry point is inst/main.R (outside the scan) and version pins on Imports
are load-bearing for the built image.
Summary
att_amend_desc()should never drop a version constraint that was already setby hand in
DESCRIPTION. Today, a pinned package can lose its version (or beremoved entirely) when it is no longer detected by the code scan.
Current behaviour
In
R/att_to_description.R,att_to_desc_from_is()rebuilds the dependencylist from the packages detected in the scanned code (
R/,tests/,vignettes/), then re-attaches versions with a left join on the previousDESCRIPTION:
Consequence: the version is kept only for packages that the scan re-detects.
A package that is pinned in
DESCRIPTIONbut not (or no longer) found by thescan is not in
all_packages, so it is removed from the output entirely, andits version pin disappears with it, silently.
When it bites
Packages that are real runtime dependencies but live outside the scanned paths,
typically
inst/(whichattachmentdoes not scan). A common pattern:inst/main.RusespkgA (>= 1.2.0)viapkgA::fn();pkgAis declared inImportswith the pin so it ends up in the builtimage / lockfile;
att_amend_desc()(e.g. from adev/maintenance script) rewritesDESCRIPTIONand dropspkgAand its>= 1.2.0, because the scan never sawit.
More generally, any manually curated version constraint (build/CI-only deps,
packages referenced only by string, packages used only under
inst/) is atrisk on the next
att_amend_desc()run.Minimal repro
Expected behaviour
att_amend_desc()should not silently discard a version constraint that amaintainer already set. Options, from least to most invasive:
its version dropped, listing the affected packages.
version in the current
DESCRIPTION, even if the scan did not re-detect it(i.e. keep the pin rather than resetting to
*or dropping the package).keep_versions = TRUE/keep_pinned = TRUE) toguarantee that existing version constraints survive the amend, for teams that
pin on purpose and scan-detection is incomplete.
The key invariant: a hand-set version in
DESCRIPTIONshould surviveatt_amend_desc()unless the maintainer explicitly asks to remove it.Context
Seen on R packages deployed through a shared factory, where the production
entry point is
inst/main.R(outside the scan) and version pins onImportsare load-bearing for the built image.