2021-04-05 14:33:28 +00:00
# include "derived-path.hh"
2022-03-17 22:29:15 +00:00
# include "derivations.hh"
2021-03-01 05:48:01 +00:00
# include "store-api.hh"
# include <nlohmann/json.hpp>
2022-05-04 05:44:32 +00:00
# include <optional>
2021-03-01 05:48:01 +00:00
namespace nix {
2021-04-05 13:48:18 +00:00
nlohmann : : json DerivedPath : : Opaque : : toJSON ( ref < Store > store ) const {
2021-03-01 05:48:01 +00:00
nlohmann : : json res ;
res [ " path " ] = store - > printStorePath ( path ) ;
return res ;
}
2022-03-17 10:34:31 +00:00
nlohmann : : json DerivedPath : : Built : : toJSON ( ref < Store > store ) const {
nlohmann : : json res ;
res [ " drvPath " ] = store - > printStorePath ( drvPath ) ;
// Fallback for the input-addressed derivation case: We expect to always be
// able to print the output paths, so let’ s do it
2022-05-04 05:44:32 +00:00
const auto knownOutputs = store - > queryPartialDerivationOutputMap ( drvPath ) ;
2022-03-17 10:34:31 +00:00
for ( const auto & output : outputs ) {
2022-05-04 05:44:32 +00:00
auto knownOutput = get ( knownOutputs , output ) ;
res [ " outputs " ] [ output ] = ( knownOutput & & * knownOutput )
? store - > printStorePath ( * * knownOutput )
: nullptr ;
2022-03-17 10:34:31 +00:00
}
return res ;
}
2021-05-12 14:19:51 +00:00
nlohmann : : json BuiltPath : : Built : : toJSON ( ref < Store > store ) const {
2021-03-01 05:48:01 +00:00
nlohmann : : json res ;
res [ " drvPath " ] = store - > printStorePath ( drvPath ) ;
for ( const auto & [ output , path ] : outputs ) {
2021-05-17 06:45:08 +00:00
res [ " outputs " ] [ output ] = store - > printStorePath ( path ) ;
2021-03-01 05:48:01 +00:00
}
return res ;
}
2021-05-17 06:45:08 +00:00
StorePathSet BuiltPath : : outPaths ( ) const
{
return std : : visit (
overloaded {
2021-09-30 21:31:21 +00:00
[ ] ( const BuiltPath : : Opaque & p ) { return StorePathSet { p . path } ; } ,
[ ] ( const BuiltPath : : Built & b ) {
2021-05-17 06:45:08 +00:00
StorePathSet res ;
for ( auto & [ _ , path ] : b . outputs )
res . insert ( path ) ;
return res ;
} ,
} , raw ( )
) ;
}
2022-11-21 09:49:01 +00:00
std : : string DerivedPath : : Opaque : : to_string ( const Store & store ) const
{
2021-03-02 03:50:41 +00:00
return store . printStorePath ( path ) ;
}
2022-11-21 09:49:01 +00:00
std : : string DerivedPath : : Built : : to_string ( const Store & store ) const
{
2021-03-02 03:50:41 +00:00
return store . printStorePath ( drvPath )
+ " ! "
+ ( outputs . empty ( ) ? std : : string { " * " } : concatStringsSep ( " , " , outputs ) ) ;
}
2021-04-05 13:48:18 +00:00
std : : string DerivedPath : : to_string ( const Store & store ) const
2021-03-02 03:50:41 +00:00
{
return std : : visit (
[ & ] ( const auto & req ) { return req . to_string ( store ) ; } ,
2021-04-05 13:24:42 +00:00
this - > raw ( ) ) ;
2021-03-02 03:50:41 +00:00
}
2021-04-05 13:48:18 +00:00
DerivedPath : : Opaque DerivedPath : : Opaque : : parse ( const Store & store , std : : string_view s )
2021-03-02 03:50:41 +00:00
{
return { store . parseStorePath ( s ) } ;
}
2022-05-12 20:10:02 +00:00
DerivedPath : : Built DerivedPath : : Built : : parse ( const Store & store , std : : string_view drvS , std : : string_view outputsS )
2021-03-02 03:50:41 +00:00
{
2022-05-12 20:10:02 +00:00
auto drvPath = store . parseStorePath ( drvS ) ;
2022-02-25 15:00:00 +00:00
std : : set < std : : string > outputs ;
2022-07-15 00:22:46 +00:00
if ( outputsS ! = " * " ) {
2022-02-25 15:00:00 +00:00
outputs = tokenizeString < std : : set < std : : string > > ( outputsS , " , " ) ;
2022-07-15 00:22:46 +00:00
if ( outputs . empty ( ) )
throw Error (
" Explicit list of wanted outputs '%s' must not be empty. Consider using '*' as a wildcard meaning all outputs if no output in particular is wanted. " , outputsS ) ;
}
2021-03-02 03:50:41 +00:00
return { drvPath , outputs } ;
}
2021-04-05 13:48:18 +00:00
DerivedPath DerivedPath : : parse ( const Store & store , std : : string_view s )
2021-03-02 03:50:41 +00:00
{
2022-05-12 20:10:02 +00:00
size_t n = s . rfind ( " ! " ) ;
2021-03-02 03:50:41 +00:00
return n = = s . npos
2021-04-05 13:48:18 +00:00
? ( DerivedPath ) DerivedPath : : Opaque : : parse ( store , s )
2022-05-12 20:10:02 +00:00
: ( DerivedPath ) DerivedPath : : Built : : parse ( store , s . substr ( 0 , n ) , s . substr ( n + 1 ) ) ;
2021-03-02 03:50:41 +00:00
}
2021-05-17 06:45:08 +00:00
RealisedPath : : Set BuiltPath : : toRealisedPaths ( Store & store ) const
{
RealisedPath : : Set res ;
std : : visit (
overloaded {
2021-09-30 21:31:21 +00:00
[ & ] ( const BuiltPath : : Opaque & p ) { res . insert ( p . path ) ; } ,
[ & ] ( const BuiltPath : : Built & p ) {
2021-05-17 06:45:08 +00:00
auto drvHashes =
staticOutputHashes ( store , store . readDerivation ( p . drvPath ) ) ;
for ( auto & [ outputName , outputPath ] : p . outputs ) {
if ( settings . isExperimentalFeatureEnabled (
2021-10-25 13:53:01 +00:00
Xp : : CaDerivations ) ) {
2022-05-04 05:44:32 +00:00
auto drvOutput = get ( drvHashes , outputName ) ;
if ( ! drvOutput )
throw Error (
" the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths) " ,
store . printStorePath ( p . drvPath ) , outputName ) ;
2021-05-17 06:45:08 +00:00
auto thisRealisation = store . queryRealisation (
2022-05-04 05:44:32 +00:00
DrvOutput { * drvOutput , outputName } ) ;
assert ( thisRealisation ) ; // We’ ve built it, so we must
// have the realisation
2021-05-17 06:45:08 +00:00
res . insert ( * thisRealisation ) ;
} else {
res . insert ( outputPath ) ;
}
}
} ,
} ,
raw ( ) ) ;
return res ;
}
2021-03-01 05:48:01 +00:00
}