Skip to content

--derivation considered harmful, remove it in lieu of ^ and new stuff #7261

@Ericson2314

Description

@Ericson2314

Reasons it is bad

No single meaning

--derivation is a shared flag between all commands, but only some commands care about it at all:

src/nix/diff-closures.cc:        auto beforePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, before);
src/nix/diff-closures.cc:        auto afterPath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, after);
src/nix/why-depends.cc:        auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package);
src/nix/why-depends.cc:        auto dependencyPath = Installable::toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency);

Other commands force one way or the other:

 $ git grep OperateOn src/nix
src/nix/develop.cc:                getEvalStore(), store, Realise::Nothing, OperateOn::Output, {installable});
src/nix/develop.cc:            for (auto & path : Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, {bashInstallable})) {
src/nix/run.cc:        auto outPaths = Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables);

Still other commands force something like --derivation by hand, like nix log:

nix/src/nix/log.cc

Lines 45 to 52 in 499e99d

auto log = std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) {
return logSub.getBuildLog(bo.path);
},
[&](const DerivedPath::Built & bfd) {
return logSub.getBuildLog(bfd.drvPath);
},
}, b.raw());

This makes for unpredictable behavior, which is a frustrating user experience.

Doesn't scale to CA derivations

In the CA derivation world, we cannot assume a path has one unique builder. This is true both for unstable floating CA derivations, and stable fixed CA derivations (fixed output derivations). --derivation fundamentally is meaningless, or non-determinstic (picking one of many builders) in an arbitrary way. This is no good.

nix build myFixedOutput0 # produces /nix/store/asdfasdfdasf-foo
nix build myFixedOutput1 # Also produces /nix/store/asdfasdfdasf-foo
nix log /nix/store/asdfasdfdasf-foo # does what?!

Doesn't scale to RFC 92

Currently, if one passes a BuiltPath derived path, --derivation (and nix log) always exacts the drvPath part. But with RFC 92 the output path could also be a derivation! This makes --derivation confusing for users.

It also leads to a loss of expressive power. Imagine if one wants --derivation for one argument but not another, e.g. for why-depends asking why a computed derivation depends on another derivation:

nix why-depends makeDrvs.anOutputWhichIsADrv gcc # oops cannot get gcc.drvPath which is what I want

What we should do instead

See also

Metadata

Metadata

Assignees

No one assigned

    Labels

    UXThe way in which users interact with Nix. Higher level than UI.featureFeature request or proposalidea approvedThe given proposal has been discussed and approved by the Nix team. An implementation is welcome.new-cliRelating to the "nix" command

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions