Skip to content

att_amend_desc() should not drop version constraints already set in DESCRIPTION #139

Description

@VincentGuyader

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:

  1. Warn when a previously pinned dependency is about to be removed or have
    its version dropped, listing the affected packages.
  2. 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).
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions