2006-02-08 15:21:16 +02:00
# include "get-drvs.hh"
2006-09-05 00:06:23 +03:00
# include "util.hh"
2012-02-04 15:50:25 +02:00
# include "eval-inline.hh"
2022-03-18 00:29:15 +02:00
# include "derivations.hh"
2020-03-21 17:07:16 +02:00
# include "store-api.hh"
2021-03-02 05:50:41 +02:00
# include "path-with-outputs.hh"
2006-09-05 00:06:23 +03:00
2013-11-19 15:09:03 +02:00
# include <cstring>
2017-04-19 15:18:26 +03:00
# include <regex>
2013-11-19 15:09:03 +02:00
2006-09-05 00:06:23 +03:00
namespace nix {
2006-02-08 15:21:16 +02:00
2022-02-25 17:00:00 +02:00
DrvInfo : : DrvInfo ( EvalState & state , std : : string attrPath , Bindings * attrs )
: state ( & state ) , attrs ( attrs ) , attrPath ( std : : move ( attrPath ) )
2017-07-17 20:02:56 +03:00
{
}
2017-11-24 19:07:29 +02:00
DrvInfo : : DrvInfo ( EvalState & state , ref < Store > store , const std : : string & drvPathWithOutputs )
: state ( & state ) , attrs ( nullptr ) , attrPath ( " " )
{
2021-03-02 03:06:08 +02:00
auto [ drvPath , selectedOutputs ] = parsePathWithOutputs ( * store , drvPathWithOutputs ) ;
2017-11-24 19:07:29 +02:00
2022-03-02 11:57:19 +02:00
this - > drvPath = drvPath ;
2017-11-24 19:07:29 +02:00
auto drv = store - > derivationFromPath ( drvPath ) ;
2019-12-05 20:11:09 +02:00
name = drvPath . name ( ) ;
2017-11-24 19:07:29 +02:00
2019-12-05 20:11:09 +02:00
if ( selectedOutputs . size ( ) > 1 )
2017-11-24 19:07:29 +02:00
throw Error ( " building more than one derivation output is not supported, in '%s' " , drvPathWithOutputs ) ;
outputName =
2019-12-05 20:11:09 +02:00
selectedOutputs . empty ( )
2022-05-04 08:44:32 +03:00
? getOr ( drv . env , " outputName " , " out " )
2019-12-05 20:11:09 +02:00
: * selectedOutputs . begin ( ) ;
2017-11-24 19:07:29 +02:00
auto i = drv . outputs . find ( outputName ) ;
if ( i = = drv . outputs . end ( ) )
2019-12-05 20:11:09 +02:00
throw Error ( " derivation '%s' does not have output '%s' " , store - > printStorePath ( drvPath ) , outputName ) ;
2020-08-14 20:00:13 +03:00
auto & [ outputName , output ] = * i ;
2017-11-24 19:07:29 +02:00
2022-03-02 11:57:19 +02:00
outPath = { output . path ( * store , drv . name , outputName ) } ;
2017-11-24 19:07:29 +02:00
}
2022-02-25 17:00:00 +02:00
std : : string DrvInfo : : queryName ( ) const
2017-07-17 20:02:56 +03:00
{
if ( name = = " " & & attrs ) {
auto i = attrs - > find ( state - > sName ) ;
if ( i = = attrs - > end ( ) ) throw TypeError ( " derivation name missing " ) ;
2023-01-19 14:23:04 +02:00
name = state - > forceStringNoCtx ( * i - > value , noPos , " while evaluating the 'name' attribute of a derivation " ) ;
2017-07-17 20:02:56 +03:00
}
return name ;
}
2022-02-25 17:00:00 +02:00
std : : string DrvInfo : : querySystem ( ) const
2017-07-17 20:02:56 +03:00
{
if ( system = = " " & & attrs ) {
auto i = attrs - > find ( state - > sSystem ) ;
2023-01-19 14:23:04 +02:00
system = i = = attrs - > end ( ) ? " unknown " : state - > forceStringNoCtx ( * i - > value , i - > pos , " while evaluating the 'system' attribute of a derivation " ) ;
2017-07-17 20:02:56 +03:00
}
return system ;
}
2022-03-02 11:57:19 +02:00
std : : optional < StorePath > DrvInfo : : queryDrvPath ( ) const
2006-03-10 18:20:42 +02:00
{
2022-03-02 11:57:19 +02:00
if ( ! drvPath & & attrs ) {
2013-11-19 15:09:03 +02:00
Bindings : : iterator i = attrs - > find ( state - > sDrvPath ) ;
2006-10-16 18:55:34 +03:00
PathSet context ;
2022-03-02 11:57:19 +02:00
if ( i = = attrs - > end ( ) )
drvPath = { std : : nullopt } ;
else
2023-01-19 14:23:04 +02:00
drvPath = { state - > coerceToStorePath ( i - > pos , * i - > value , context , " while evaluating the 'drvPath' attribute of a derivation " ) } ;
2006-03-10 18:20:42 +02:00
}
2022-03-02 11:57:19 +02:00
return drvPath . value_or ( std : : nullopt ) ;
2006-03-10 18:20:42 +02:00
}
2022-03-02 11:57:19 +02:00
StorePath DrvInfo : : requireDrvPath ( ) const
{
if ( auto drvPath = queryDrvPath ( ) )
return * drvPath ;
throw Error ( " derivation does not contain a 'drvPath' attribute " ) ;
}
StorePath DrvInfo : : queryOutPath ( ) const
2006-03-10 18:20:42 +02:00
{
2020-08-07 22:09:26 +03:00
if ( ! outPath & & attrs ) {
2013-11-19 15:09:03 +02:00
Bindings : : iterator i = attrs - > find ( state - > sOutPath ) ;
2006-10-16 18:55:34 +03:00
PathSet context ;
2020-08-07 22:09:26 +03:00
if ( i ! = attrs - > end ( ) )
2023-01-19 14:23:04 +02:00
outPath = state - > coerceToStorePath ( i - > pos , * i - > value , context , " while evaluating the output path of a derivation " ) ;
2006-03-10 18:20:42 +02:00
}
2020-08-07 22:09:26 +03:00
if ( ! outPath )
throw UnimplementedError ( " CA derivations are not yet supported " ) ;
return * outPath ;
2006-03-10 18:20:42 +02:00
}
2022-03-12 14:47:01 +02:00
DrvInfo : : Outputs DrvInfo : : queryOutputs ( bool withPaths , bool onlyOutputsToInstall )
2012-11-28 14:49:44 +02:00
{
if ( outputs . empty ( ) ) {
2016-11-26 01:37:43 +02:00
/* Get the ‘ outputs’ list. */
2013-11-19 15:09:03 +02:00
Bindings : : iterator i ;
if ( attrs & & ( i = attrs - > find ( state - > sOutputs ) ) ! = attrs - > end ( ) ) {
2023-01-19 14:23:04 +02:00
state - > forceList ( * i - > value , i - > pos , " while evaluating the 'outputs' attribute of a derivation " ) ;
2012-11-28 14:49:44 +02:00
/* For each output... */
2021-11-24 21:21:34 +02:00
for ( auto elem : i - > value - > listItems ( ) ) {
2023-01-19 14:23:04 +02:00
std : : string output ( state - > forceStringNoCtx ( * elem , i - > pos , " while evaluating the name of an output of a derivation " ) ) ;
2022-03-12 14:47:01 +02:00
if ( withPaths ) {
/* Evaluate the corresponding set. */
Bindings : : iterator out = attrs - > find ( state - > symbols . create ( output ) ) ;
if ( out = = attrs - > end ( ) ) continue ; // FIXME: throw error?
2023-01-19 14:23:04 +02:00
state - > forceAttrs ( * out - > value , i - > pos , " while evaluating an output of a derivation " ) ;
2022-03-12 14:47:01 +02:00
/* And evaluate its ‘ outPath’ attribute. */
Bindings : : iterator outPath = out - > value - > attrs - > find ( state - > sOutPath ) ;
if ( outPath = = out - > value - > attrs - > end ( ) ) continue ; // FIXME: throw error?
PathSet context ;
2023-01-19 14:23:04 +02:00
outputs . emplace ( output , state - > coerceToStorePath ( outPath - > pos , * outPath - > value , context , " while evaluating an output path of a derivation " ) ) ;
2022-03-12 14:47:01 +02:00
} else
outputs . emplace ( output , std : : nullopt ) ;
2012-11-28 14:49:44 +02:00
}
2013-11-19 15:09:03 +02:00
} else
2022-03-12 14:47:01 +02:00
outputs . emplace ( " out " , withPaths ? std : : optional { queryOutPath ( ) } : std : : nullopt ) ;
2012-11-28 14:49:44 +02:00
}
2022-05-30 12:32:37 +03:00
2016-02-23 15:19:14 +02:00
if ( ! onlyOutputsToInstall | | ! attrs )
return outputs ;
2022-05-30 12:32:37 +03:00
Bindings : : iterator i ;
2023-01-19 14:23:04 +02:00
if ( attrs & & ( i = attrs - > find ( state - > sOutputSpecified ) ) ! = attrs - > end ( ) & & state - > forceBool ( * i - > value , i - > pos , " while evaluating the 'outputSpecified' attribute of a derivation " ) ) {
2022-05-30 12:32:37 +03:00
Outputs result ;
auto out = outputs . find ( queryOutputName ( ) ) ;
if ( out = = outputs . end ( ) )
throw Error ( " derivation does not have output '%s' " , queryOutputName ( ) ) ;
2016-02-23 15:19:14 +02:00
result . insert ( * out ) ;
2022-05-30 12:32:37 +03:00
return result ;
}
else {
/* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
const Value * outTI = queryMeta ( " outputsToInstall " ) ;
if ( ! outTI ) return outputs ;
2022-12-07 13:58:58 +02:00
auto errMsg = Error ( " this derivation has bad 'meta.outputsToInstall' " ) ;
2022-05-30 12:32:37 +03:00
/* ^ this shows during `nix-env -i` right under the bad derivation */
if ( ! outTI - > isList ( ) ) throw errMsg ;
Outputs result ;
for ( auto elem : outTI - > listItems ( ) ) {
if ( elem - > type ( ) ! = nString ) throw errMsg ;
auto out = outputs . find ( elem - > string . s ) ;
if ( out = = outputs . end ( ) ) throw errMsg ;
result . insert ( * out ) ;
}
return result ;
2016-02-23 15:19:14 +02:00
}
2012-11-28 14:49:44 +02:00
}
2022-02-25 17:00:00 +02:00
std : : string DrvInfo : : queryOutputName ( ) const
2012-11-26 18:39:09 +02:00
{
if ( outputName = = " " & & attrs ) {
2013-11-19 15:09:03 +02:00
Bindings : : iterator i = attrs - > find ( state - > sOutputName ) ;
2023-01-19 14:23:04 +02:00
outputName = i ! = attrs - > end ( ) ? state - > forceStringNoCtx ( * i - > value , noPos , " while evaluating the output name of a derivation " ) : " " ;
2012-11-26 18:39:09 +02:00
}
return outputName ;
}
2013-11-19 15:09:03 +02:00
Bindings * DrvInfo : : getMeta ( )
2006-03-10 18:20:42 +02:00
{
2013-11-19 15:09:03 +02:00
if ( meta ) return meta ;
if ( ! attrs ) return 0 ;
Bindings : : iterator a = attrs - > find ( state - > sMeta ) ;
if ( a = = attrs - > end ( ) ) return 0 ;
2023-01-19 14:23:04 +02:00
state - > forceAttrs ( * a - > value , a - > pos , " while evaluating the 'meta' attribute of a derivation " ) ;
2013-11-19 15:09:03 +02:00
meta = a - > value - > attrs ;
2006-03-10 18:20:42 +02:00
return meta ;
}
2013-11-19 15:09:03 +02:00
StringSet DrvInfo : : queryMetaNames ( )
2007-05-01 23:33:18 +03:00
{
2013-11-19 15:09:03 +02:00
StringSet res ;
if ( ! getMeta ( ) ) return res ;
2015-07-17 20:24:28 +03:00
for ( auto & i : * meta )
2022-03-05 15:40:24 +02:00
res . emplace ( state - > symbols [ i . name ] ) ;
2013-11-19 15:09:03 +02:00
return res ;
2007-05-01 23:33:18 +03:00
}
2013-11-19 15:29:39 +02:00
bool DrvInfo : : checkMeta ( Value & v )
{
2022-02-04 01:31:33 +02:00
state - > forceValue ( v , [ & ] ( ) { return v . determinePos ( noPos ) ; } ) ;
2020-12-17 15:45:45 +02:00
if ( v . type ( ) = = nList ) {
2021-11-24 21:21:34 +02:00
for ( auto elem : v . listItems ( ) )
if ( ! checkMeta ( * elem ) ) return false ;
2013-11-19 15:29:39 +02:00
return true ;
}
2020-12-17 15:45:45 +02:00
else if ( v . type ( ) = = nAttrs ) {
2013-11-19 15:29:39 +02:00
Bindings : : iterator i = v . attrs - > find ( state - > sOutPath ) ;
if ( i ! = v . attrs - > end ( ) ) return false ;
2015-07-17 20:24:28 +03:00
for ( auto & i : * v . attrs )
if ( ! checkMeta ( * i . value ) ) return false ;
2013-11-19 15:29:39 +02:00
return true ;
}
2020-12-17 15:45:45 +02:00
else return v . type ( ) = = nInt | | v . type ( ) = = nBool | | v . type ( ) = = nString | |
v . type ( ) = = nFloat ;
2013-11-19 15:29:39 +02:00
}
2022-02-25 17:00:00 +02:00
Value * DrvInfo : : queryMeta ( const std : : string & name )
2007-02-02 03:52:42 +02:00
{
2013-11-19 15:09:03 +02:00
if ( ! getMeta ( ) ) return 0 ;
Bindings : : iterator a = meta - > find ( state - > symbols . create ( name ) ) ;
2013-11-19 15:29:39 +02:00
if ( a = = meta - > end ( ) | | ! checkMeta ( * a - > value ) ) return 0 ;
2013-11-19 15:09:03 +02:00
return a - > value ;
}
2022-02-25 17:00:00 +02:00
std : : string DrvInfo : : queryMetaString ( const std : : string & name )
2013-11-19 15:09:03 +02:00
{
Value * v = queryMeta ( name ) ;
2020-12-17 15:45:45 +02:00
if ( ! v | | v - > type ( ) ! = nString ) return " " ;
2013-11-19 15:09:03 +02:00
return v - > string . s ;
}
2022-02-25 17:00:00 +02:00
NixInt DrvInfo : : queryMetaInt ( const std : : string & name , NixInt def )
2013-11-19 15:09:03 +02:00
{
Value * v = queryMeta ( name ) ;
if ( ! v ) return def ;
2020-12-17 15:45:45 +02:00
if ( v - > type ( ) = = nInt ) return v - > integer ;
if ( v - > type ( ) = = nString ) {
2013-11-19 15:09:03 +02:00
/* Backwards compatibility with before we had support for
integer meta fields . */
2021-01-08 13:22:21 +02:00
if ( auto n = string2Int < NixInt > ( v - > string . s ) )
return * n ;
2013-11-19 15:09:03 +02:00
}
return def ;
}
2022-02-25 17:00:00 +02:00
NixFloat DrvInfo : : queryMetaFloat ( const std : : string & name , NixFloat def )
2016-01-05 01:40:40 +02:00
{
Value * v = queryMeta ( name ) ;
if ( ! v ) return def ;
2020-12-17 15:45:45 +02:00
if ( v - > type ( ) = = nFloat ) return v - > fpoint ;
if ( v - > type ( ) = = nString ) {
2016-01-05 01:40:40 +02:00
/* Backwards compatibility with before we had support for
float meta fields . */
2021-01-08 13:22:21 +02:00
if ( auto n = string2Float < NixFloat > ( v - > string . s ) )
return * n ;
2016-01-05 01:40:40 +02:00
}
return def ;
}
2013-11-19 15:09:03 +02:00
2022-02-25 17:00:00 +02:00
bool DrvInfo : : queryMetaBool ( const std : : string & name , bool def )
2013-11-19 15:09:03 +02:00
{
Value * v = queryMeta ( name ) ;
if ( ! v ) return def ;
2020-12-17 15:45:45 +02:00
if ( v - > type ( ) = = nBool ) return v - > boolean ;
if ( v - > type ( ) = = nString ) {
2013-11-19 15:09:03 +02:00
/* Backwards compatibility with before we had support for
Boolean meta fields . */
if ( strcmp ( v - > string . s , " true " ) = = 0 ) return true ;
if ( strcmp ( v - > string . s , " false " ) = = 0 ) return false ;
}
return def ;
}
2022-02-25 17:00:00 +02:00
void DrvInfo : : setMeta ( const std : : string & name , Value * v )
2013-11-19 15:09:03 +02:00
{
getMeta ( ) ;
2022-01-04 18:39:16 +02:00
auto attrs = state - > buildBindings ( 1 + ( meta ? meta - > size ( ) : 0 ) ) ;
2022-03-05 15:40:24 +02:00
auto sym = state - > symbols . create ( name ) ;
2022-01-04 18:39:16 +02:00
if ( meta )
for ( auto i : * meta )
2014-09-19 17:49:41 +03:00
if ( i . name ! = sym )
2022-01-04 18:39:16 +02:00
attrs . insert ( i ) ;
if ( v ) attrs . insert ( sym , v ) ;
meta = attrs . finish ( ) ;
2010-03-31 22:12:08 +03:00
}
2007-02-02 03:52:42 +02:00
2010-04-01 15:04:57 +03:00
/* Cache for already considered attrsets. */
2022-02-21 17:28:23 +02:00
typedef std : : set < Bindings * > Done ;
2006-02-08 18:15:07 +02:00
2013-10-24 17:41:04 +03:00
/* Evaluate value `v'. If it evaluates to a set of type `derivation',
2016-02-23 15:19:14 +02:00
then put information about it in ` drvs ' ( unless it ' s already in ` done ' ) .
The result boolean indicates whether it makes sense
2013-10-24 17:41:04 +03:00
for the caller to recursively search for derivations in ` v ' . */
2010-03-31 18:38:03 +03:00
static bool getDerivation ( EvalState & state , Value & v ,
2022-02-25 17:00:00 +02:00
const std : : string & attrPath , DrvInfos & drvs , Done & done ,
2012-10-04 22:22:25 +03:00
bool ignoreAssertionFailures )
2006-02-08 15:21:16 +02:00
{
2006-03-08 18:03:58 +02:00
try {
2022-02-04 01:31:33 +02:00
state . forceValue ( v , [ & ] ( ) { return v . determinePos ( noPos ) ; } ) ;
2010-04-07 16:55:46 +03:00
if ( ! state . isDerivation ( v ) ) return true ;
2006-02-08 15:21:16 +02:00
2013-10-24 17:41:04 +03:00
/* Remove spurious duplicates (e.g., a set like `rec { x =
derivation { . . . } ; y = x ; } ' . */
2019-10-09 16:51:52 +03:00
if ( ! done . insert ( v . attrs ) . second ) return false ;
2006-02-08 18:15:07 +02:00
2017-07-17 20:02:56 +03:00
DrvInfo drv ( state , attrPath , v . attrs ) ;
2006-02-08 15:21:16 +02:00
2017-07-17 20:02:56 +03:00
drv . queryName ( ) ;
2006-07-25 19:40:38 +03:00
2006-03-08 18:03:58 +02:00
drvs . push_back ( drv ) ;
2017-07-17 20:02:56 +03:00
2006-03-08 18:03:58 +02:00
return false ;
2012-11-28 14:49:44 +02:00
2006-03-08 18:03:58 +02:00
} catch ( AssertionError & e ) {
2012-10-04 22:22:25 +03:00
if ( ignoreAssertionFailures ) return false ;
throw ;
2006-03-08 18:03:58 +02:00
}
2006-02-08 15:21:16 +02:00
}
2019-02-12 14:43:32 +02:00
std : : optional < DrvInfo > getDerivation ( EvalState & state , Value & v ,
2012-10-04 22:22:25 +03:00
bool ignoreAssertionFailures )
2006-02-08 18:15:07 +02:00
{
2010-04-01 15:04:57 +03:00
Done done ;
2006-02-08 18:15:07 +02:00
DrvInfos drvs ;
2012-10-04 22:22:25 +03:00
getDerivation ( state , v , " " , drvs , done , ignoreAssertionFailures ) ;
2017-07-20 14:32:01 +03:00
if ( drvs . size ( ) ! = 1 ) return { } ;
return std : : move ( drvs . front ( ) ) ;
2006-02-08 18:15:07 +02:00
}
2022-02-25 17:00:00 +02:00
static std : : string addToPath ( const std : : string & s1 , const std : : string & s2 )
2006-07-25 19:40:38 +03:00
{
return s1 . empty ( ) ? s2 : s1 + " . " + s2 ;
}
2017-04-19 15:18:26 +03:00
static std : : regex attrRegex ( " [A-Za-z_][A-Za-z0-9-_+]* " ) ;
2010-04-07 18:47:06 +03:00
static void getDerivations ( EvalState & state , Value & vIn ,
2022-02-25 17:00:00 +02:00
const std : : string & pathPrefix , Bindings & autoArgs ,
2012-10-04 22:22:25 +03:00
DrvInfos & drvs , Done & done ,
bool ignoreAssertionFailures )
2006-02-08 15:21:16 +02:00
{
2010-04-07 18:47:06 +03:00
Value v ;
state . autoCallFunction ( autoArgs , vIn , v ) ;
2012-11-28 14:49:44 +02:00
2006-02-10 19:25:59 +02:00
/* Process the expression. */
2012-10-04 22:22:25 +03:00
if ( ! getDerivation ( state , v , pathPrefix , drvs , done , ignoreAssertionFailures ) ) ;
2006-03-08 18:03:58 +02:00
2020-12-17 15:45:45 +02:00
else if ( v . type ( ) = = nAttrs ) {
2007-05-02 02:16:38 +03:00
2007-09-17 19:08:24 +03:00
/* !!! undocumented hackery to support combining channels in
nix - env . cc . */
2010-04-13 15:25:42 +03:00
bool combineChannels = v . attrs - > find ( state . symbols . create ( " _combineChannels " ) ) ! = v . attrs - > end ( ) ;
2008-08-25 17:15:56 +03:00
2008-08-25 17:31:29 +03:00
/* Consider the attributes in sorted order to get more
deterministic behaviour in nix - env operations ( e . g . when
there are names clashes between derivations , the derivation
bound to the attribute with the " lower " name should take
precedence ) . */
2022-03-05 15:40:24 +02:00
for ( auto & i : v . attrs - > lexicographicOrder ( state . symbols ) ) {
debug ( " evaluating attribute '%1%' " , state . symbols [ i - > name ] ) ;
if ( ! std : : regex_match ( std : : string ( state . symbols [ i - > name ] ) , attrRegex ) )
2017-04-19 15:18:26 +03:00
continue ;
2022-03-05 15:40:24 +02:00
std : : string pathPrefix2 = addToPath ( pathPrefix , state . symbols [ i - > name ] ) ;
2008-08-25 17:15:56 +03:00
if ( combineChannels )
2017-01-25 17:06:50 +02:00
getDerivations ( state , * i - > value , pathPrefix2 , autoArgs , drvs , done , ignoreAssertionFailures ) ;
else if ( getDerivation ( state , * i - > value , pathPrefix2 , drvs , done , ignoreAssertionFailures ) ) {
2013-10-24 17:41:04 +03:00
/* If the value of this attribute is itself a set,
should we recurse into it ? = > Only if it has a
` recurseForDerivations = true ' attribute . */
2020-12-17 15:45:45 +02:00
if ( i - > value - > type ( ) = = nAttrs ) {
2020-06-18 14:44:40 +03:00
Bindings : : iterator j = i - > value - > attrs - > find ( state . sRecurseForDerivations ) ;
2023-01-19 14:23:04 +02:00
if ( j ! = i - > value - > attrs - > end ( ) & & state . forceBool ( * j - > value , j - > pos , " while evaluating the attribute `recurseForDerivations` " ) )
2017-01-25 17:06:50 +02:00
getDerivations ( state , * i - > value , pathPrefix2 , autoArgs , drvs , done , ignoreAssertionFailures ) ;
2006-03-23 18:43:07 +02:00
}
2006-02-10 19:25:59 +02:00
}
2006-02-08 15:21:16 +02:00
}
}
2020-12-17 15:45:45 +02:00
else if ( v . type ( ) = = nList ) {
2021-11-24 21:21:34 +02:00
for ( auto [ n , elem ] : enumerate ( v . listItems ( ) ) ) {
2022-02-25 17:00:00 +02:00
std : : string pathPrefix2 = addToPath ( pathPrefix , fmt ( " %d " , n ) ) ;
2021-11-24 21:21:34 +02:00
if ( getDerivation ( state , * elem , pathPrefix2 , drvs , done , ignoreAssertionFailures ) )
getDerivations ( state , * elem , pathPrefix2 , autoArgs , drvs , done , ignoreAssertionFailures ) ;
2006-02-08 17:22:30 +02:00
}
}
2006-02-08 15:21:16 +02:00
2010-03-31 18:38:03 +03:00
else throw TypeError ( " expression does not evaluate to a derivation (or a set or list of those) " ) ;
2006-02-08 17:22:30 +02:00
}
2006-02-08 18:15:07 +02:00
2022-02-25 17:00:00 +02:00
void getDerivations ( EvalState & state , Value & v , const std : : string & pathPrefix ,
2012-10-04 22:22:25 +03:00
Bindings & autoArgs , DrvInfos & drvs , bool ignoreAssertionFailures )
2006-02-08 18:15:07 +02:00
{
2010-04-01 15:04:57 +03:00
Done done ;
2012-10-04 22:22:25 +03:00
getDerivations ( state , v , pathPrefix , autoArgs , drvs , done , ignoreAssertionFailures ) ;
2006-02-08 18:15:07 +02:00
}
2006-09-05 00:06:23 +03:00
2012-11-28 14:49:44 +02:00
2006-09-05 00:06:23 +03:00
}