{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
#ifdef __GHCIDE__
# define NIX_IS_AT_LEAST(mm,m,p) 1
#endif
module Hercules.CNix.Store
( module Hercules.CNix.Store,
module Hercules.CNix.Store.Context,
)
where
import Control.Exception
import Control.Monad.IO.Unlift
import Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString.Short as SBS
import Data.ByteString.Unsafe (unsafePackMallocCString)
import qualified Data.ByteString.Unsafe as BS
import Data.Coerce (coerce)
import qualified Data.Map as M
import Foreign (alloca, free, nullPtr)
import Foreign.ForeignPtr
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.Storable (peek)
import Hercules.CNix.Encapsulation (HasEncapsulation (..))
import Hercules.CNix.Std.Set (StdSet, stdSetCtx)
import qualified Hercules.CNix.Std.Set as Std.Set
import Hercules.CNix.Std.String (stdStringCtx)
import qualified Hercules.CNix.Std.String as Std.String
import Hercules.CNix.Std.Vector
import qualified Hercules.CNix.Std.Vector as Std.Vector
import Hercules.CNix.Store.Context
( DerivationInputsIterator,
DerivationOutputsIterator,
NixStore,
NixStorePath,
Ref,
SecretKey,
StringPairs,
Strings,
ValidPathInfo,
context,
unsafeMallocBS,
)
import qualified Hercules.CNix.Store.Context as C hiding (context)
import Hercules.CNix.Store.Instances ()
import qualified Language.C.Inline.Cpp as C
import qualified Language.C.Inline.Cpp.Exception as C
import Protolude
import System.IO.Unsafe (unsafePerformIO)
import qualified Prelude
C.context (context <> stdVectorCtx <> stdSetCtx <> stdStringCtx)
C.include "<cstring>"
C.include "<nix/config.h>"
C.include "<nix/shared.hh>"
C.include "<nix/store-api.hh>"
C.include "<nix/get-drvs.hh>"
C.include "<nix/derivations.hh>"
C.include "<nix/globals.hh>"
C.include "<nix/path.hh>"
C.include "<variant>"
C.include "<nix/worker-protocol.hh>"
C.include "<nix/path-with-outputs.hh>"
C.include "hercules-ci-cnix/store.hxx"
C.using "namespace nix"
forNonNull :: Applicative m => Ptr a -> (Ptr a -> m b) -> m (Maybe b)
forNonNull :: forall (m :: * -> *) a b.
Applicative m =>
Ptr a -> (Ptr a -> m b) -> m (Maybe b)
forNonNull = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a b.
Applicative m =>
(Ptr a -> m b) -> Ptr a -> m (Maybe b)
traverseNonNull
traverseNonNull :: Applicative m => (Ptr a -> m b) -> Ptr a -> m (Maybe b)
traverseNonNull :: forall (m :: * -> *) a b.
Applicative m =>
(Ptr a -> m b) -> Ptr a -> m (Maybe b)
traverseNonNull Ptr a -> m b
f Ptr a
p = if Ptr a
p forall a. Eq a => a -> a -> Bool
== forall a. Ptr a
nullPtr then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr a -> m b
f Ptr a
p
newtype Store = Store (Ptr (Ref NixStore))
openStore :: IO Store
openStore :: IO Store
openStore =
coerce :: forall a b. Coercible a b => a -> b
coerce
[C.throwBlock| refStore * {
refStore s = openStore();
return new refStore(s);
} |]
releaseStore :: Store -> IO ()
releaseStore :: Store -> IO ()
releaseStore (Store Ptr (Ref NixStore)
store) = [C.exp| void { delete $(refStore* store) } |]
withStore :: MonadUnliftIO m => (Store -> m a) -> m a
withStore :: forall (m :: * -> *) a. MonadUnliftIO m => (Store -> m a) -> m a
withStore Store -> m a
m = do
UnliftIO forall a. m a -> IO a
ul <- forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall r. (Store -> IO r) -> IO r
withStore' forall a b. (a -> b) -> a -> b
$ \Store
a -> forall a. m a -> IO a
ul (Store -> m a
m Store
a)
withStore' ::
(Store -> IO r) ->
IO r
withStore' :: forall r. (Store -> IO r) -> IO r
withStore' =
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO Store
openStore Store -> IO ()
releaseStore
withStoreFromURI ::
MonadUnliftIO m =>
Text ->
(Store -> m r) ->
m r
withStoreFromURI :: forall (m :: * -> *) r.
MonadUnliftIO m =>
Text -> (Store -> m r) -> m r
withStoreFromURI Text
storeURIText Store -> m r
f = do
let storeURI :: ByteString
storeURI = Text -> ByteString
encodeUtf8 Text
storeURIText
(UnliftIO forall a. m a -> IO a
unlift) <- forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
[C.throwBlock| refStore* {
refStore s = openStore($bs-cstr:storeURI);
return new refStore(s);
}|]
(\Ptr (Ref NixStore)
x -> [C.exp| void { delete $(refStore* x) } |])
(forall a. m a -> IO a
unlift forall b c a. (b -> c) -> (a -> b) -> a -> c
. Store -> m r
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr (Ref NixStore) -> Store
Store)
storeUri :: MonadIO m => Store -> m ByteString
storeUri :: forall (m :: * -> *). MonadIO m => Store -> m ByteString
storeUri (Store Ptr (Ref NixStore)
store) =
forall (m :: * -> *). MonadIO m => IO (Ptr CChar) -> m ByteString
unsafeMallocBS
[C.block| const char* {
std::string uri = (*$(refStore* store))->getUri();
return strdup(uri.c_str());
} |]
storeDir :: MonadIO m => Store -> m ByteString
storeDir :: forall (m :: * -> *). MonadIO m => Store -> m ByteString
storeDir (Store Ptr (Ref NixStore)
store) =
forall (m :: * -> *). MonadIO m => IO (Ptr CChar) -> m ByteString
unsafeMallocBS
[C.block| const char* {
std::string uri = (*$(refStore* store))->storeDir;
return strdup(uri.c_str());
} |]
getStoreProtocolVersion :: Store -> IO Int
getStoreProtocolVersion :: Store -> IO Int
getStoreProtocolVersion (Store Ptr (Ref NixStore)
store) =
forall a b. (Integral a, Num b) => a -> b
fromIntegral
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [C.throwBlock| int {
Store &store = **$(refStore* store);
return store.getProtocol();
} |]
getClientProtocolVersion :: IO Int
getClientProtocolVersion :: IO Int
getClientProtocolVersion =
forall a b. (Integral a, Num b) => a -> b
fromIntegral
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [C.throwBlock| int {
return PROTOCOL_VERSION;
} |]
newtype StorePath = StorePath (ForeignPtr NixStorePath)
instance HasEncapsulation NixStorePath StorePath where
moveToForeignPtrWrapper :: Ptr NixStorePath -> IO StorePath
moveToForeignPtrWrapper = Ptr NixStorePath -> IO StorePath
moveStorePath
finalizeStorePath :: FinalizerPtr NixStorePath
{-# NOINLINE finalizeStorePath #-}
finalizeStorePath :: FinalizerPtr NixStorePath
finalizeStorePath =
forall a. IO a -> a
unsafePerformIO
[C.exp|
void (*)(nix::StorePath *) {
[](StorePath *v) {
delete v;
}
}
|]
moveStorePath :: Ptr NixStorePath -> IO StorePath
moveStorePath :: Ptr NixStorePath -> IO StorePath
moveStorePath Ptr NixStorePath
x = ForeignPtr NixStorePath -> StorePath
StorePath forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr NixStorePath
finalizeStorePath Ptr NixStorePath
x
moveStorePathMaybe :: Ptr NixStorePath -> IO (Maybe StorePath)
moveStorePathMaybe :: Ptr NixStorePath -> IO (Maybe StorePath)
moveStorePathMaybe = forall (m :: * -> *) a b.
Applicative m =>
(Ptr a -> m b) -> Ptr a -> m (Maybe b)
traverseNonNull forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr NixStorePath -> StorePath
StorePath forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr NixStorePath
finalizeStorePath
instance Prelude.Show StorePath where
show :: StorePath -> String
show StorePath
storePath = forall a. IO a -> a
unsafePerformIO do
ByteString
bs <-
Ptr CChar -> IO ByteString
BS.unsafePackMallocCString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.block| const char* {
std::string s($fptr-ptr:(nix::StorePath *storePath)->to_string());
return strdup(s.c_str());
}|]
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. ConvertText a b => a -> b
toS forall a b. (a -> b) -> a -> b
$ OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode ByteString
bs
instance Eq StorePath where
StorePath
a == :: StorePath -> StorePath -> Bool
== StorePath
b = forall a. Ord a => a -> a -> Ordering
compare StorePath
a StorePath
b forall a. Eq a => a -> a -> Bool
== Ordering
EQ
instance Ord StorePath where
compare :: StorePath -> StorePath -> Ordering
compare (StorePath ForeignPtr NixStorePath
a) (StorePath ForeignPtr NixStorePath
b) =
forall a. Ord a => a -> a -> Ordering
compare
CInt
0
[C.pure| int {
$fptr-ptr:(nix::StorePath *a)->to_string().compare($fptr-ptr:(nix::StorePath *b)->to_string())
}|]
parseStorePathBaseName :: ByteString -> IO StorePath
parseStorePathBaseName :: ByteString -> IO StorePath
parseStorePathBaseName ByteString
bs =
Ptr NixStorePath -> IO StorePath
moveStorePath
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| nix::StorePath *{
return new StorePath(std::string($bs-ptr:bs, $bs-len:bs));
}|]
parseStorePath :: Store -> ByteString -> IO StorePath
parseStorePath :: Store -> ByteString -> IO StorePath
parseStorePath (Store Ptr (Ref NixStore)
store) ByteString
bs =
Ptr NixStorePath -> IO StorePath
moveStorePath
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| nix::StorePath *{
return new StorePath(std::move((*$(refStore* store))->parseStorePath(std::string($bs-ptr:bs, $bs-len:bs))));
}|]
getStorePathBaseName :: StorePath -> IO ByteString
getStorePathBaseName :: StorePath -> IO ByteString
getStorePathBaseName (StorePath ForeignPtr NixStorePath
sp) = do
Ptr CChar -> IO ByteString
BS.unsafePackMallocCString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.block| const char *{
std::string s($fptr-ptr:(nix::StorePath *sp)->to_string());
return strdup(s.c_str());
}|]
getStorePathHash :: StorePath -> IO ByteString
getStorePathHash :: StorePath -> IO ByteString
getStorePathHash (StorePath ForeignPtr NixStorePath
sp) = do
Ptr CChar -> IO ByteString
BS.unsafePackMallocCString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.block| const char *{
std::string s($fptr-ptr:(nix::StorePath *sp)->hashPart());
return strdup(s.c_str());
}|]
storePathToPath :: Store -> StorePath -> IO ByteString
storePathToPath :: Store -> StorePath -> IO ByteString
storePathToPath (Store Ptr (Ref NixStore)
store) (StorePath ForeignPtr NixStorePath
sp) =
Ptr CChar -> IO ByteString
BS.unsafePackMallocCString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.block| const char *{
Store & store = **$(refStore* store);
StorePath &sp = *$fptr-ptr:(nix::StorePath *sp);
std::string s(store.printStorePath(sp));
return strdup(s.c_str());
}|]
ensurePath :: Store -> StorePath -> IO ()
ensurePath :: Store -> StorePath -> IO ()
ensurePath (Store Ptr (Ref NixStore)
store) (StorePath ForeignPtr NixStorePath
storePath) =
[C.throwBlock| void {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath);
store.ensurePath(storePath);
} |]
addTemporaryRoot :: Store -> StorePath -> IO ()
addTemporaryRoot :: Store -> StorePath -> IO ()
addTemporaryRoot (Store Ptr (Ref NixStore)
store) StorePath
storePath = do
[C.throwBlock| void {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath);
store.addTempRoot(storePath);
} |]
clearPathInfoCache :: Store -> IO ()
clearPathInfoCache :: Store -> IO ()
clearPathInfoCache (Store Ptr (Ref NixStore)
store) =
[C.throwBlock| void {
(*$(refStore* store))->clearPathInfoCache();
} |]
clearSubstituterCaches :: IO ()
clearSubstituterCaches :: IO ()
clearSubstituterCaches =
[C.throwBlock| void {
auto subs = nix::getDefaultSubstituters();
for (auto sub : subs) {
sub->clearPathInfoCache();
}
} |]
newtype StorePathWithOutputs = StorePathWithOutputs (ForeignPtr C.NixStorePathWithOutputs)
instance HasEncapsulation C.NixStorePathWithOutputs StorePathWithOutputs where
moveToForeignPtrWrapper :: Ptr NixStorePathWithOutputs -> IO StorePathWithOutputs
moveToForeignPtrWrapper Ptr NixStorePathWithOutputs
x = ForeignPtr NixStorePathWithOutputs -> StorePathWithOutputs
StorePathWithOutputs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr NixStorePathWithOutputs
finalizeStorePathWithOutputs Ptr NixStorePathWithOutputs
x
finalizeStorePathWithOutputs :: FinalizerPtr C.NixStorePathWithOutputs
{-# NOINLINE finalizeStorePathWithOutputs #-}
finalizeStorePathWithOutputs :: FinalizerPtr NixStorePathWithOutputs
finalizeStorePathWithOutputs =
forall a. IO a -> a
unsafePerformIO
[C.exp|
void (*)(nix::StorePathWithOutputs *) {
[](StorePathWithOutputs *v) {
delete v;
}
}
|]
newStorePathWithOutputs :: StorePath -> [ByteString] -> IO StorePathWithOutputs
newStorePathWithOutputs :: StorePath -> [ByteString] -> IO StorePathWithOutputs
newStorePathWithOutputs StorePath
storePath [ByteString]
outputs = do
StdSet CStdString
set <- forall a. HasStdSet a => IO (StdSet a)
Std.Set.new
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [ByteString]
outputs (\ByteString
o -> forall a. ByteString -> (Ptr CStdString -> IO a) -> IO a
Std.String.withString ByteString
o (forall a. HasStdSet a => StdSet a -> Ptr a -> IO ()
Std.Set.insertP StdSet CStdString
set))
forall a b. HasEncapsulation a b => Ptr a -> IO b
moveToForeignPtrWrapper
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.exp| nix::StorePathWithOutputs * {
new StorePathWithOutputs {*$fptr-ptr:(nix::StorePath *storePath), *$fptr-ptr:(std::set<std::string>* set)}
}|]
getStorePath :: StorePathWithOutputs -> IO StorePath
getStorePath :: StorePathWithOutputs -> IO StorePath
getStorePath StorePathWithOutputs
swo = forall a. IO a -> IO a
mask_ do
forall a b. HasEncapsulation a b => Ptr a -> IO b
moveToForeignPtrWrapper
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.exp| nix::StorePath * {
new StorePath($fptr-ptr:(nix::StorePathWithOutputs *swo)->path)
}|]
getOutputs :: StorePathWithOutputs -> IO [ByteString]
getOutputs :: StorePathWithOutputs -> IO [ByteString]
getOutputs StorePathWithOutputs
swo = forall a. IO a -> IO a
mask_ do
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Ptr CStdString -> IO ByteString
Std.String.moveToByteString forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. HasStdVector a => StdVector a -> IO [Ptr a]
toListP forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a b. HasEncapsulation a b => Ptr a -> IO b
moveToForeignPtrWrapper
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| std::vector<std::string>* {
auto r = new std::vector<std::string>();
for (auto s : $fptr-ptr:(nix::StorePathWithOutputs *swo)->outputs)
r->push_back(s);
return r;
}|]
buildPaths :: Store -> StdVector C.NixStorePathWithOutputs -> IO ()
buildPaths :: Store -> StdVector NixStorePathWithOutputs -> IO ()
buildPaths (Store Ptr (Ref NixStore)
store) (StdVector ForeignPtr (CStdVector NixStorePathWithOutputs)
paths) = do
[C.throwBlock| void {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
std::vector<StorePathWithOutputs> &paths = *$fptr-ptr:(std::vector<nix::StorePathWithOutputs>* paths);
store.buildPaths(toDerivedPaths(paths));
}|]
buildPath :: Store -> StorePathWithOutputs -> IO ()
buildPath :: Store -> StorePathWithOutputs -> IO ()
buildPath Store
store StorePathWithOutputs
spwo = do
Store -> StdVector NixStorePathWithOutputs -> IO ()
buildPaths Store
store forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a' a.
(Coercible a' (ForeignPtr a), HasStdVector a) =>
[a'] -> IO (StdVector a)
Std.Vector.fromListFP [StorePathWithOutputs
spwo]
newtype Derivation = Derivation (ForeignPtr C.Derivation)
instance HasEncapsulation C.Derivation Derivation where
moveToForeignPtrWrapper :: Ptr Derivation -> IO Derivation
moveToForeignPtrWrapper = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr Derivation -> Derivation
Derivation forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Derivation
finalizeDerivation
finalizeDerivation :: FinalizerPtr C.Derivation
{-# NOINLINE finalizeDerivation #-}
finalizeDerivation :: FinalizerPtr Derivation
finalizeDerivation =
forall a. IO a -> a
unsafePerformIO
[C.exp|
void (*)(Derivation *) {
[](Derivation *v) {
delete v;
}
} |]
getDerivation :: Store -> StorePath -> IO Derivation
getDerivation :: Store -> StorePath -> IO Derivation
getDerivation (Store Ptr (Ref NixStore)
store) (StorePath ForeignPtr NixStorePath
spwo) = do
forall a b. HasEncapsulation a b => Ptr a -> IO b
moveToForeignPtrWrapper
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| Derivation *{
ReceiveInterrupts _;
Store &store = **$(refStore* store);
return new Derivation(
store.derivationFromPath(*$fptr-ptr:(nix::StorePath *spwo))
);
} |]
getDerivationFromString ::
Store ->
ByteString ->
ByteString ->
IO Derivation
getDerivationFromString :: Store -> ByteString -> ByteString -> IO Derivation
getDerivationFromString (Store Ptr (Ref NixStore)
store) ByteString
name ByteString
contents = do
forall a b. HasEncapsulation a b => Ptr a -> IO b
moveToForeignPtrWrapper
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| Derivation *{
Store &store = **$(refStore* store);
std::string name($bs-ptr:name, $bs-len:name);
return new Derivation(parseDerivation(store, std::string($bs-ptr:contents, $bs-len:contents), name));
}|]
getDerivationNameFromPath :: StorePath -> IO ByteString
getDerivationNameFromPath :: StorePath -> IO ByteString
getDerivationNameFromPath StorePath
storePath =
Ptr CChar -> IO ByteString
BS.unsafePackMallocCString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [C.throwBlock| const char *{
StorePath &sp = *$fptr-ptr:(nix::StorePath *storePath);
std::string s(Derivation::nameFromPath(sp));
return strdup(s.c_str());
}|]
data DerivationOutput = DerivationOutput
{ DerivationOutput -> ByteString
derivationOutputName :: !ByteString,
DerivationOutput -> Maybe StorePath
derivationOutputPath :: !(Maybe StorePath),
DerivationOutput -> DerivationOutputDetail
derivationOutputDetail :: !DerivationOutputDetail
}
deriving (DerivationOutput -> DerivationOutput -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DerivationOutput -> DerivationOutput -> Bool
$c/= :: DerivationOutput -> DerivationOutput -> Bool
== :: DerivationOutput -> DerivationOutput -> Bool
$c== :: DerivationOutput -> DerivationOutput -> Bool
Eq, Int -> DerivationOutput -> ShowS
[DerivationOutput] -> ShowS
DerivationOutput -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DerivationOutput] -> ShowS
$cshowList :: [DerivationOutput] -> ShowS
show :: DerivationOutput -> String
$cshow :: DerivationOutput -> String
showsPrec :: Int -> DerivationOutput -> ShowS
$cshowsPrec :: Int -> DerivationOutput -> ShowS
Show)
data DerivationOutputDetail
= DerivationOutputInputAddressed StorePath
| DerivationOutputCAFixed FixedOutputHash StorePath
| DerivationOutputCAFloating FileIngestionMethod HashType
| DerivationOutputDeferred
deriving (DerivationOutputDetail -> DerivationOutputDetail -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DerivationOutputDetail -> DerivationOutputDetail -> Bool
$c/= :: DerivationOutputDetail -> DerivationOutputDetail -> Bool
== :: DerivationOutputDetail -> DerivationOutputDetail -> Bool
$c== :: DerivationOutputDetail -> DerivationOutputDetail -> Bool
Eq, Int -> DerivationOutputDetail -> ShowS
[DerivationOutputDetail] -> ShowS
DerivationOutputDetail -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DerivationOutputDetail] -> ShowS
$cshowList :: [DerivationOutputDetail] -> ShowS
show :: DerivationOutputDetail -> String
$cshow :: DerivationOutputDetail -> String
showsPrec :: Int -> DerivationOutputDetail -> ShowS
$cshowsPrec :: Int -> DerivationOutputDetail -> ShowS
Show)
data FixedOutputHash = FixedOutputHash !FileIngestionMethod {-# UNPACK #-} !Hash
deriving (FixedOutputHash -> FixedOutputHash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FixedOutputHash -> FixedOutputHash -> Bool
$c/= :: FixedOutputHash -> FixedOutputHash -> Bool
== :: FixedOutputHash -> FixedOutputHash -> Bool
$c== :: FixedOutputHash -> FixedOutputHash -> Bool
Eq, Int -> FixedOutputHash -> ShowS
[FixedOutputHash] -> ShowS
FixedOutputHash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FixedOutputHash] -> ShowS
$cshowList :: [FixedOutputHash] -> ShowS
show :: FixedOutputHash -> String
$cshow :: FixedOutputHash -> String
showsPrec :: Int -> FixedOutputHash -> ShowS
$cshowsPrec :: Int -> FixedOutputHash -> ShowS
Show)
data FileIngestionMethod = Flat | Recursive
deriving (FileIngestionMethod -> FileIngestionMethod -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FileIngestionMethod -> FileIngestionMethod -> Bool
$c/= :: FileIngestionMethod -> FileIngestionMethod -> Bool
== :: FileIngestionMethod -> FileIngestionMethod -> Bool
$c== :: FileIngestionMethod -> FileIngestionMethod -> Bool
Eq, Int -> FileIngestionMethod -> ShowS
[FileIngestionMethod] -> ShowS
FileIngestionMethod -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FileIngestionMethod] -> ShowS
$cshowList :: [FileIngestionMethod] -> ShowS
show :: FileIngestionMethod -> String
$cshow :: FileIngestionMethod -> String
showsPrec :: Int -> FileIngestionMethod -> ShowS
$cshowsPrec :: Int -> FileIngestionMethod -> ShowS
Show)
data Hash = Hash !HashType {-# UNPACK #-} !ShortByteString
deriving (Hash -> Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Hash -> Hash -> Bool
$c/= :: Hash -> Hash -> Bool
== :: Hash -> Hash -> Bool
$c== :: Hash -> Hash -> Bool
Eq, Int -> Hash -> ShowS
[Hash] -> ShowS
Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Hash] -> ShowS
$cshowList :: [Hash] -> ShowS
show :: Hash -> String
$cshow :: Hash -> String
showsPrec :: Int -> Hash -> ShowS
$cshowsPrec :: Int -> Hash -> ShowS
Show)
data HashType = MD5 | SHA1 | SHA256 | SHA512
deriving (HashType -> HashType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HashType -> HashType -> Bool
$c/= :: HashType -> HashType -> Bool
== :: HashType -> HashType -> Bool
$c== :: HashType -> HashType -> Bool
Eq, Int -> HashType -> ShowS
[HashType] -> ShowS
HashType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HashType] -> ShowS
$cshowList :: [HashType] -> ShowS
show :: HashType -> String
$cshow :: HashType -> String
showsPrec :: Int -> HashType -> ShowS
$cshowsPrec :: Int -> HashType -> ShowS
Show)
getDerivationOutputs :: Store -> ByteString -> Derivation -> IO [DerivationOutput]
getDerivationOutputs :: Store -> ByteString -> Derivation -> IO [DerivationOutput]
getDerivationOutputs (Store Ptr (Ref NixStore)
store) ByteString
drvName (Derivation ForeignPtr Derivation
derivation) =
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
[C.exp| DerivationOutputsIterator* {
new DerivationOutputsIterator($fptr-ptr:(Derivation *derivation)->outputs.begin())
}|]
Ptr DerivationOutputsIterator -> IO ()
deleteDerivationOutputsIterator
forall a b. (a -> b) -> a -> b
$ \Ptr DerivationOutputsIterator
i -> forall a. (a -> a) -> a
fix forall a b. (a -> b) -> a -> b
$ \IO [DerivationOutput]
continue -> do
Bool
isEnd <- (CBool
0 forall a. Eq a => a -> a -> Bool
/=) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [C.exp| bool { *$(DerivationOutputsIterator *i) == $fptr-ptr:(Derivation *derivation)->outputs.end() }|]
if Bool
isEnd
then forall (f :: * -> *) a. Applicative f => a -> f a
pure []
else
( forall a. IO a -> IO a
mask_ do
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr (Ptr CChar)
nameP -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr (Ptr NixStorePath)
pathP -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr CInt
typP -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr CInt
fimP ->
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr CInt
hashTypeP -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr (Ptr CChar)
hashValueP -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca \Ptr CInt
hashSizeP -> do
[C.throwBlock| void {
Store &store = **$(refStore *store);
std::string drvName = std::string($bs-ptr:drvName, $bs-len:drvName);
nix::DerivationOutputs::iterator &i = *$(DerivationOutputsIterator *i);
const char *&name = *$(const char **nameP);
int &typ = *$(int *typP);
StorePath *& path = *$(nix::StorePath **pathP);
int &fim = *$(int *fimP);
int &hashType = *$(int *hashTypeP);
char *&hashValue = *$(char **hashValueP);
int &hashSize = *$(int *hashSizeP);
std::string nameString = i->first;
name = strdup(nameString.c_str());
path = nullptr;
std::visit(overloaded {
[&](DerivationOutputInputAddressed doi) -> void {
typ = 0;
path = new StorePath(doi.path);
},
[&](DerivationOutputCAFixed dof) -> void {
typ = 1;
path = new StorePath(dof.path(store, $fptr-ptr:(Derivation *derivation)->name, nameString));
#if NIX_IS_AT_LEAST(2, 16, 0)
std::visit(overloaded {
[&](nix::FileIngestionMethod fim_) -> void {
switch (fim_) {
case nix::FileIngestionMethod::Flat:
fim = 0;
break;
case nix::FileIngestionMethod::Recursive:
fim = 1;
break;
default:
fim = -1;
break;
}
},
[&](nix::TextIngestionMethod) -> void {
// FIXME (RFC 92)
fim = -1;
}
}, dof.ca.getMethod().raw);
#else
switch (dof.hash.method) {
case nix::FileIngestionMethod::Flat:
fim = 0;
break;
case nix::FileIngestionMethod::Recursive:
fim = 1;
break;
default:
fim = -1;
break;
}
#endif
#if NIX_IS_AT_LEAST(2, 16, 0)
const Hash & hash = dof.ca.getHash();
#else
const Hash & hash = dof.hash.hash;
#endif
switch (hash.type) {
case htMD5:
hashType = 0;
break;
case htSHA1:
hashType = 1;
break;
case htSHA256:
hashType = 2;
break;
case htSHA512:
hashType = 3;
break;
default:
hashType = -1;
break;
}
hashSize = hash.hashSize;
hashValue = (char*)malloc(hashSize);
std::memcpy((void*)(hashValue),
(void*)(hash.hash),
hashSize);
},
[&](DerivationOutputCAFloating dof) -> void {
typ = 2;
#if NIX_IS_AT_LEAST(2, 16, 0)
std::visit(overloaded {
[&](nix::FileIngestionMethod fim_) -> void {
switch (fim_) {
case nix::FileIngestionMethod::Flat:
fim = 0;
break;
case nix::FileIngestionMethod::Recursive:
fim = 1;
break;
default:
fim = -1;
break;
}
},
[&](nix::TextIngestionMethod) -> void {
// FIXME (RFC 92)
fim = -1;
}
}, dof.method.raw);
#else
switch (dof.method) {
case nix::FileIngestionMethod::Flat:
fim = 0;
break;
case nix::FileIngestionMethod::Recursive:
fim = 1;
break;
default:
fim = -1;
break;
}
#endif
switch (dof.hashType) {
case htMD5:
hashType = 0;
break;
case htSHA1:
hashType = 1;
break;
case htSHA256:
hashType = 2;
break;
case htSHA512:
hashType = 3;
break;
default:
hashType = -1;
break;
}
},
[&](DerivationOutputDeferred) -> void {
typ = 3;
},
#if NIX_IS_AT_LEAST(2,8,0)
[&](DerivationOutputImpure) -> void {
typ = 4;
},
#endif
},
#if NIX_IS_AT_LEAST(2,8,0)
i->second.raw()
#else
i->second.output
#endif
);
i++;
}|]
name <- unsafePackMallocCString =<< peek nameP
path <- moveStorePathMaybe =<< peek pathP
typ <- peek typP
let getFileIngestionMethod = peek fimP <&> \case 0 -> Flat; 1 -> Recursive; _ -> panic "getDerivationOutputs: unknown fim"
getHashType =
peek hashTypeP <&> \case
0 -> MD5
1 -> SHA1
2 -> SHA256
3 -> SHA512
_ -> panic "getDerivationOutputs: unknown hashType"
detail <- case typ of
0 -> pure $ DerivationOutputInputAddressed (fromMaybe (panic "getDerivationOutputs: impossible DOIA path missing") path)
1 -> do
hashValue <- peek hashValueP
hashSize <- peek hashSizeP
hashString <- SBS.packCStringLen (hashValue, fromIntegral hashSize)
free hashValue
hashType <- getHashType
fim <- getFileIngestionMethod
pure $ DerivationOutputCAFixed (FixedOutputHash fim (Hash hashType hashString)) (fromMaybe (panic "getDerivationOutputs: impossible DOCF path missing") path)
2 -> do
hashType <- getHashType
fim <- getFileIngestionMethod
pure $ DerivationOutputCAFloating fim hashType
3 -> pure DerivationOutputDeferred
4 -> panic "getDerivationOutputs: impure derivations not supported yet"
_ -> panic "getDerivationOutputs: impossible getDerivationOutputs typ"
pure
( DerivationOutput
{ derivationOutputName = name,
derivationOutputPath = path,
derivationOutputDetail = detail
}
:
)
)
<*> continue
deleteDerivationOutputsIterator :: Ptr DerivationOutputsIterator -> IO ()
deleteDerivationOutputsIterator a = [C.block| void { delete $(DerivationOutputsIterator *a); }|]
getDerivationPlatform :: Derivation -> IO ByteString
getDerivationPlatform derivation =
unsafeMallocBS
[C.exp| const char* {
strdup($fptr-ptr:(Derivation *derivation)->platform.c_str())
} |]
getDerivationBuilder :: Derivation -> IO ByteString
getDerivationBuilder derivation =
unsafeMallocBS
[C.exp| const char* {
strdup($fptr-ptr:(Derivation *derivation)->builder.c_str())
} |]
getDerivationArguments :: Derivation -> IO [ByteString]
getDerivationArguments derivation =
bracket
[C.throwBlock| Strings* {
Strings *r = new Strings();
for (auto i : $fptr-ptr:(Derivation *derivation)->args) {
r->push_back(i);
}
return r;
}|]
deleteStrings
toByteStrings
getDerivationSources :: Store -> Derivation -> IO [StorePath]
getDerivationSources _ = getDerivationSources'
getDerivationSources' :: Derivation -> IO [StorePath]
getDerivationSources' derivation = mask_ do
vec <-
moveToForeignPtrWrapper
=<< [C.throwBlock| std::vector<nix::StorePath*>* {
auto r = new std::vector<StorePath *>();
for (auto s : $fptr-ptr:(Derivation *derivation)->inputSrcs)
r->push_back(new StorePath(s));
return r;
}|]
traverse moveStorePath =<< Std.Vector.toList vec
getDerivationInputs :: Store -> Derivation -> IO [(StorePath, [ByteString])]
getDerivationInputs _ = getDerivationInputs'
getDerivationInputs' :: Derivation -> IO [(StorePath, [ByteString])]
getDerivationInputs' derivation =
bracket
[C.exp| DerivationInputsIterator* {
new DerivationInputsIterator($fptr-ptr:(Derivation *derivation)->inputDrvs.begin())
}|]
deleteDerivationInputsIterator
$ \i -> fix $ \continue -> do
isEnd <- (0 /=) <$> [C.exp| bool { *$(DerivationInputsIterator *i) == $fptr-ptr:(Derivation *derivation)->inputDrvs.end() }|]
if isEnd
then pure []
else do
name <-
[C.throwBlock| nix::StorePath *{
return new StorePath((*$(DerivationInputsIterator *i))->first);
}|]
>>= moveStorePath
outs <-
bracket
[C.block| Strings*{
Strings *r = new Strings();
for (auto i : (*$(DerivationInputsIterator *i))->second) {
r->push_back(i);
}
return r;
}|]
deleteStrings
toByteStrings
[C.block| void { (*$(DerivationInputsIterator *i))++; }|]
((name, outs) :) <$> continue
deleteDerivationInputsIterator :: Ptr DerivationInputsIterator -> IO ()
deleteDerivationInputsIterator a = [C.block| void { delete $(DerivationInputsIterator *a); }|]
getDerivationEnv :: Derivation -> IO (Map ByteString ByteString)
getDerivationEnv derivation =
[C.exp| StringPairs* { &($fptr-ptr:(Derivation *derivation)->env) }|]
>>= toByteStringMap
getDerivationOutputNames :: ForeignPtr Derivation -> IO [ByteString]
getDerivationOutputNames derivation =
bracket
[C.throwBlock| Strings* {
Strings *r = new Strings();
for (auto i : $fptr-ptr:(Derivation *derivation)->outputs) {
r->push_back(i.first);
}
return r;
}|]
deleteStrings
toByteStrings
deleteStringPairs :: Ptr StringPairs -> IO ()
deleteStringPairs s = [C.block| void { delete $(StringPairs *s); }|]
deleteStrings :: Ptr Strings -> IO ()
deleteStrings s = [C.block| void { delete $(Strings *s); }|]
finalizeStrings :: FinalizerPtr Strings
{-# NOINLINE finalizeStrings #-}
finalizeStrings =
unsafePerformIO
[C.exp|
void (*)(Strings *) {
[](Strings *v) {
delete v;
}
} |]
getStringsLength :: Ptr Strings -> IO C.CSize
getStringsLength strings = [C.exp| size_t { $(Strings *strings)->size() }|]
toByteStrings :: Ptr Strings -> IO [ByteString]
toByteStrings strings = do
i <- [C.exp| StringsIterator *{ new StringsIterator($(Strings *strings)->begin()) } |]
fix $ \go -> do
isEnd <- (0 /=) <$> [C.exp| bool { *$(StringsIterator *i) == $(Strings *strings)->end() }|]
if isEnd
then pure []
else do
s <- [C.exp| const char*{ strdup((*$(StringsIterator *i))->c_str()) }|]
bs <- BS.unsafePackMallocCString s
[C.block| void { (*$(StringsIterator *i))++; }|]
(bs :) <$> go
toByteStringMap :: Ptr StringPairs -> IO (Map ByteString ByteString)
toByteStringMap strings =
M.fromList <$> do
i <- [C.exp| StringPairsIterator *{ new StringPairsIterator($(StringPairs *strings)->begin()) } |]
fix $ \go -> do
isEnd <- (0 /=) <$> [C.exp| bool { *$(StringPairsIterator *i) == $(StringPairs *strings)->end() }|]
if isEnd
then pure []
else do
k <- [C.exp| const char*{ strdup((*$(StringPairsIterator *i))->first.c_str()) }|]
v <- [C.exp| const char*{ strdup((*$(StringPairsIterator *i))->second.c_str()) }|]
bk <- BS.unsafePackMallocCString k
bv <- BS.unsafePackMallocCString v
[C.block| void { (*$(StringPairsIterator *i))++; }|]
((bk, bv) :) <$> go
withStrings :: (Ptr Strings -> IO a) -> IO a
withStrings =
bracket
[C.exp| Strings *{ new Strings() }|]
(\sp -> [C.block| void { delete $(Strings *sp); }|])
withStringsOf :: [ByteString] -> (Ptr Strings -> IO a) -> IO a
withStringsOf paths f =
withStrings \strings -> do
for_ paths (pushString strings)
f strings
pushString :: Ptr Strings -> ByteString -> IO ()
pushString strings s =
[C.block| void { $(Strings *strings)->push_back($bs-cstr:s); }|]
copyClosure :: Store -> Store -> [StorePath] -> IO ()
copyClosure (Store src) (Store dest) pathList = do
(StdVector pathsVector') <- Std.Vector.fromList (pathList <&> \(StorePath c) -> unsafeForeignPtrToPtr c)
withForeignPtr pathsVector' \pathsVector ->
[C.throwBlock| void {
ReceiveInterrupts _;
ref<Store> src = *$(refStore* src);
ref<Store> dest = *$(refStore* dest);
std::vector<nix::StorePath *> &pathsVector = *$(std::vector<nix::StorePath*>* pathsVector);
StorePathSet pathSet;
for (auto spp : pathsVector)
pathSet.insert(*spp);
StorePathSet closurePaths;
src->computeFSClosure(pathSet, closurePaths);
nix::copyPaths(*src, *dest, closurePaths);
}|]
for_ pathList (\(StorePath c) -> touchForeignPtr c)
parseSecretKey :: ByteString -> IO (ForeignPtr SecretKey)
parseSecretKey bs =
[C.throwBlock| SecretKey* {
return new SecretKey($bs-cstr:bs);
}|]
>>= newForeignPtr finalizeSecretKey
finalizeSecretKey :: FinalizerPtr SecretKey
{-# NOINLINE finalizeSecretKey #-}
finalizeSecretKey =
unsafePerformIO
[C.exp|
void (*)(SecretKey *) {
[](SecretKey *v) {
delete v;
}
} |]
signPath ::
Store ->
Ptr SecretKey ->
StorePath ->
IO Bool
signPath (Store store) secretKey (StorePath path) =
(== 1) <$> do
[C.throwBlock| int {
ReceiveInterrupts _;
nix::ref<nix::Store> store = *$(refStore *store);
const StorePath &storePath = *$fptr-ptr:(nix::StorePath *path);
const SecretKey &secretKey = *$(SecretKey *secretKey);
auto currentInfo = store->queryPathInfo(storePath);
auto info2(*currentInfo);
info2.sigs.clear();
info2.sign(*store, secretKey);
assert(!info2.sigs.empty());
auto sig = *info2.sigs.begin();
if (currentInfo->sigs.count(sig)) {
return 0;
} else {
store->addSignatures(storePath, info2.sigs);
return 1;
}
}|]
followLinksToStorePath :: Store -> ByteString -> IO StorePath
followLinksToStorePath (Store store) bs =
moveStorePath
=<< [C.throwBlock| nix::StorePath *{
ReceiveInterrupts _;
Store &store = **$(refStore* store);
std::string s = std::string($bs-ptr:bs, $bs-len:bs);
return new StorePath(store.followLinksToStorePath(s));
}|]
isValidPath :: Store -> StorePath -> IO Bool
isValidPath (Store store) path =
[C.throwBlock| bool {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
StorePath &path = *$fptr-ptr:(nix::StorePath *path);
return store.isValidPath(path);
}|]
<&> (/= 0)
queryPathInfo ::
Store ->
StorePath ->
IO (ForeignPtr (Ref ValidPathInfo))
queryPathInfo (Store store) (StorePath path) = do
vpi <-
[C.throwBlock| refValidPathInfo* {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
StorePath &path = *$fptr-ptr:(nix::StorePath *path);
return new refValidPathInfo(store.queryPathInfo(path));
}|]
newForeignPtr finalizeRefValidPathInfo vpi
finalizeRefValidPathInfo :: FinalizerPtr (Ref ValidPathInfo)
{-# NOINLINE finalizeRefValidPathInfo #-}
finalizeRefValidPathInfo =
unsafePerformIO
[C.exp|
void (*)(refValidPathInfo *) {
[](refValidPathInfo *v){ delete v; }
}|]
validPathInfoNarSize :: ForeignPtr (Ref ValidPathInfo) -> Int64
validPathInfoNarSize vpi =
fromIntegral $
toInteger
[C.pure| long
{ (*$fptr-ptr:(refValidPathInfo* vpi))->narSize }
|]
validPathInfoNarHash32 :: ForeignPtr (Ref ValidPathInfo) -> IO ByteString
validPathInfoNarHash32 vpi =
unsafePackMallocCString
=<< [C.block| const char *{
std::string s((*$fptr-ptr:(refValidPathInfo* vpi))->narHash.to_string(nix::Base32, true));
return strdup(s.c_str()); }
|]
validPathInfoDeriver :: Store -> ForeignPtr (Ref ValidPathInfo) -> IO (Maybe StorePath)
validPathInfoDeriver _ = validPathInfoDeriver'
validPathInfoDeriver' :: ForeignPtr (Ref ValidPathInfo) -> IO (Maybe StorePath)
validPathInfoDeriver' vpi =
moveStorePathMaybe
=<< [C.throwBlock| nix::StorePath * {
std::optional<StorePath> deriver = (*$fptr-ptr:(refValidPathInfo* vpi))->deriver;
return deriver ? new StorePath(*deriver) : nullptr;
}|]
validPathInfoReferences :: Store -> ForeignPtr (Ref ValidPathInfo) -> IO [StorePath]
validPathInfoReferences _ = validPathInfoReferences'
validPathInfoReferences' :: ForeignPtr (Ref ValidPathInfo) -> IO [StorePath]
validPathInfoReferences' vpi = do
sps <-
moveToForeignPtrWrapper
=<< [C.throwBlock| std::vector<nix::StorePath *>* {
auto sps = new std::vector<nix::StorePath *>();
for (auto sp : (*$fptr-ptr:(refValidPathInfo* vpi))->references)
sps->push_back(new StorePath(sp));
return sps;
}|]
l <- Std.Vector.toList sps
for l moveStorePath
data ClosureParams = ClosureParams
{ flipDirection :: Bool,
includeOutputs :: Bool,
includeDerivers :: Bool
}
defaultClosureParams :: ClosureParams
defaultClosureParams =
ClosureParams
{ flipDirection = False,
includeOutputs = False,
includeDerivers = False
}
computeFSClosure :: Store -> ClosureParams -> StdSet NixStorePath -> IO (StdSet NixStorePath)
computeFSClosure (Store store) params (Std.Set.StdSet startingSet) = do
let countTrue :: Bool -> C.CInt
countTrue True = 1
countTrue False = 0
flipDir = countTrue $ flipDirection params
inclOut = countTrue $ includeOutputs params
inclDrv = countTrue $ includeDerivers params
ret@(Std.Set.StdSet retSet) <- Std.Set.new
[C.throwBlock| void {
ReceiveInterrupts _;
Store &store = **$(refStore* store);
StorePathSet &ret = *$fptr-ptr:(std::set<nix::StorePath>* retSet);
store.computeFSClosure(*$fptr-ptr:(std::set<nix::StorePath>* startingSet), ret,
$(int flipDir), $(int inclOut), $(int inclDrv));
}|]
pure ret
withPtr' :: (Coercible a' (ForeignPtr a)) => a' -> (Ptr a -> IO b) -> IO b
withPtr' p = withForeignPtr (coerce p)