#pragma once #include "util.hh" #include "path.hh" #include "outputs-spec.hh" #include "derived-path.hh" #include "eval.hh" #include "store-api.hh" #include "flake/flake.hh" #include "build-result.hh" #include namespace nix { struct DrvInfo; struct SourceExprCommand; namespace eval_cache { class EvalCache; class AttrCursor; } struct App { std::vector context; Path program; // FIXME: add args, sandbox settings, metadata, ... }; struct UnresolvedApp { App unresolved; App resolve(ref evalStore, ref store); }; enum class Realise { /* Build the derivation. Postcondition: the derivation outputs exist. */ Outputs, /* Don't build the derivation. Postcondition: the store derivation exists. */ Derivation, /* Evaluate in dry-run mode. Postcondition: nothing. */ // FIXME: currently unused, but could be revived if we can // evaluate derivations in-memory. Nothing }; /* How to handle derivations in commands that operate on store paths. */ enum class OperateOn { /* Operate on the output path. */ Output, /* Operate on the .drv path. */ Derivation }; struct ExtraPathInfo { std::optional priority; std::optional originalRef; std::optional resolvedRef; std::optional attrPath; // FIXME: merge with DerivedPath's 'outputs' field? std::optional extendedOutputsSpec; }; /* A derived path with any additional info that commands might need from the derivation. */ struct DerivedPathWithInfo { DerivedPath path; ExtraPathInfo info; }; struct BuiltPathWithResult { BuiltPath path; ExtraPathInfo info; std::optional result; }; typedef std::vector DerivedPathsWithInfo; struct Installable { virtual ~Installable() { } virtual std::string what() const = 0; virtual DerivedPathsWithInfo toDerivedPaths() = 0; DerivedPathWithInfo toDerivedPath(); UnresolvedApp toApp(EvalState & state); virtual std::pair toValue(EvalState & state) { throw Error("argument '%s' cannot be evaluated", what()); } /* Return a value only if this installable is a store path or a symlink to it. */ virtual std::optional getStorePath() { return {}; } /* Get a cursor to each value this Installable could refer to. However if none exists, throw exception instead of returning empty vector. */ virtual std::vector> getCursors(EvalState & state); /* Get the first and most preferred cursor this Installable could refer to, or throw an exception if none exists. */ virtual ref getCursor(EvalState & state); virtual FlakeRef nixpkgsFlakeRef() const { return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}}); } static std::vector build( ref evalStore, ref store, Realise mode, const std::vector> & installables, BuildMode bMode = bmNormal); static std::vector, BuiltPathWithResult>> build2( ref evalStore, ref store, Realise mode, const std::vector> & installables, BuildMode bMode = bmNormal); static std::set toStorePaths( ref evalStore, ref store, Realise mode, OperateOn operateOn, const std::vector> & installables); static StorePath toStorePath( ref evalStore, ref store, Realise mode, OperateOn operateOn, std::shared_ptr installable); static std::set toDerivations( ref store, const std::vector> & installables, bool useDeriver = false); static BuiltPaths toBuiltPaths( ref evalStore, ref store, Realise mode, OperateOn operateOn, const std::vector> & installables); }; typedef std::vector> Installables; }