hercules-ci-cnix-expr 0.4.0.0 → 0.5.0.0
raw patch · 7 files changed
+27/−320 lines, 7 files
Files
- CHANGELOG.md +4/−0
- hercules-ci-cnix-expr.cabal +10/−43
- include/hercules-ci-cnix/expr.hxx +0/−4
- src/Hercules/CNix/Expr.hs +13/−227
- src/Hercules/CNix/Expr/Context.hs +0/−6
- src/Hercules/CNix/Expr/Raw.hs +0/−8
- src/Hercules/CNix/Expr/Typed.hs +0/−32
CHANGELOG.md view
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 0.5.0.0 - 2025-07-18++- `init` now installs synchronous signal handlers for you. You may remove your call to `installDefaultSigINTHandler`.+ ## 0.4.0.0 - 2025-05-05 - **REMOVE** `evalArgs`. This removes a dependency on the otherwise unused nix-cmd library. Use `valueFromExpressionString` and a library like `optparse-applicative` instead to create a nicer user experience.
hercules-ci-cnix-expr.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: hercules-ci-cnix-expr-version: 0.4.0.0+version: 0.5.0.0 synopsis: Bindings for the Nix evaluator category: Nix, CI, Testing, DevOps homepage: https://docs.hercules-ci.com@@ -20,39 +20,15 @@ type: git location: https://github.com/hercules-ci/hercules-ci-agent -flag nix-2_8- description: Build for Nix >=2.8- default: True --- Deprecated-flag nix-2_4- description: Build for Nix >=2.4pre*- default: True--flag nix-2_15- description: Build for Nix >=2.5pre*- default: False--flag nix-2_24- description: Build for Nix >=2.24- default: False--flag nix-2_25- description: Build for Nix >=2.25- default: False- flag ide description: Whether to enable IDE workarounds. You shouldn't need this. default: False -- match the C++ language standard Nix is using common cxx-opts- if flag(nix-2_15)- cxx-options:- -std=c++2a- else- cxx-options:- -std=c++17+ cxx-options:+ -std=c++2a cxx-options: -Wall@@ -65,16 +41,11 @@ if impl(ghc >= 8.10) ghc-options: -optcxx-Wall- if flag(nix-2_15)- ghc-options:- -optcxx-std=c++2a- else- ghc-options:- -optcxx-std=c++17+ -optcxx-std=c++2a else -- Remove soon ghc-options:- -optc-std=c++17+ -optc-std=c++2a -optc-Wall if os(darwin) ghc-options: -pgmc=clang++@@ -126,12 +97,11 @@ extra-libraries: boost_context pkgconfig-depends:- nix-store >= 2.4- , nix-expr >= 2.4- , nix-main >= 2.4- if flag(nix-2_24)- pkgconfig-depends:- nix-flake+ nix-store >= 2.28+ , nix-expr >= 2.28+ -- TODO: replace nix-main stack overflow detection?+ , nix-main >= 2.28+ , nix-flake >= 2.28 test-suite hercules-ci-cnix-expr-unit-tests@@ -170,6 +140,3 @@ hspec-discover:hspec-discover == 2.* default-language: Haskell2010 - -- Missing nix-fetchers.pc upstream in Nix 2.24- if flag(nix-2_24) && ! flag(nix-2_25)- extra-libraries: nixfetchers
include/hercules-ci-cnix/expr.hxx view
@@ -1,10 +1,6 @@ #pragma once -#if NIX_IS_AT_LEAST(2,28,0) #include <nix/store/derivations.hh>-#else-#include "derivations.hh"-#endif #include <hercules-ci-cnix/store.hxx>
src/Hercules/CNix/Expr.hs view
@@ -87,6 +87,7 @@ import Hercules.CNix.Expr.Typed import Hercules.CNix.Store import Hercules.CNix.Store.Context+import qualified Hercules.CNix as CNix import qualified Language.C.Inline.Cpp as C import qualified Language.C.Inline.Cpp.Exception as C import Protolude hiding (evalState)@@ -104,8 +105,6 @@ C.include "<math.h>" -#if NIX_IS_AT_LEAST(2, 28, 0)- C.include "<nix/util/config-global.hh>" C.include "<nix/store/store-api.hh>" C.include "<nix/store/globals.hh>"@@ -118,29 +117,6 @@ C.include "<nix/fetchers/fetch-settings.hh>" C.include "<nix/main/shared.hh>" -#else-C.include "<nix/config.h>"-C.include "<nix/shared.hh>"-C.include "<nix/eval.hh>"-C.include "<nix/eval-inline.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/flake/flake.hh>"-C.include "<nix/flake/flakeref.hh>"-# if NIX_IS_AT_LEAST(2,19,0)-C.include "<nix/args/root.hh>"-# endif-# if NIX_IS_AT_LEAST(2,24,0)-C.include "<nix/config-global.hh>"-C.include "<nix/eval-gc.hh>"-C.include "<nix/flake/settings.hh>"-C.include "<nix/fetch-settings.hh>"-C.include "<nix/eval-settings.hh>"-# endif-#endif- C.include "hercules-ci-cnix/expr.hxx" C.include "hercules-ci-cnix/string.hxx"@@ -163,32 +139,18 @@ C.verbatim "nix::EvalSettings evalSettings(readOnlyMode);" init :: IO ()-init =- void- [C.throwBlock| void {- { auto _ = GlobalConfig::Register(&flakeSettings); }- { auto _ = GlobalConfig::Register(&fetchSettings); }- { auto _ = GlobalConfig::Register(&evalSettings); }- nix::initNix();- nix::initGC();-#if NIX_IS_AT_LEAST(2,15,0)- globalConfig.set("extra-experimental-features", "flakes");-#else-#if NIX_IS_AT_LEAST(2,5,0)- std::set<nix::ExperimentalFeature> features(nix::settings.experimentalFeatures.get());- features.insert(nix::ExperimentalFeature::Flakes);-#else- Strings features(nix::settings.experimentalFeatures.get());- features.push_back("flakes");-#endif- nix::settings.experimentalFeatures.assign(features);-#endif-#if NIX_IS_AT_LEAST(2,28,0)- flakeSettings.configureEvalSettings(evalSettings);-#elif NIX_IS_AT_LEAST(2,24,0)- nix::flake::initLib(flakeSettings);-#endif- } |]+init = do+ [C.throwBlock| void {+ { auto _ = GlobalConfig::Register(&flakeSettings); }+ { auto _ = GlobalConfig::Register(&fetchSettings); }+ { auto _ = GlobalConfig::Register(&evalSettings); }+ }|]+ CNix.init+ [C.throwBlock| void {+ nix::initGC();+ globalConfig.set("extra-experimental-features", "flakes");+ flakeSettings.configureEvalSettings(evalSettings);+ }|] -- | Initialize the current (main) thread for stack overflow detection. initThread :: IO ()@@ -246,7 +208,6 @@ -} setExtraStackOverflowHandlerToSleep :: IO () setExtraStackOverflowHandlerToSleep =-#if NIX_IS_AT_LEAST(2,12,0) void [C.throwBlock| void { nix::stackOverflowHandler = [](siginfo_t *info, void *ctx) {@@ -261,9 +222,6 @@ _exit(1); }; }|]-#else- pass-#endif setTalkative :: IO () setTalkative =@@ -303,22 +261,10 @@ -- | (private) Make an EvalState and leak it. newEvalState :: MonadIO m => Store -> m (Ptr EvalState) newEvalState (Store store) = liftIO-#if NIX_IS_AT_LEAST(2,24,0) [C.throwBlock| EvalState* { nix::LookupPath emptyLookupPath; return new EvalState(emptyLookupPath, *$(refStore* store), fetchSettings, evalSettings); } |]-#elif NIX_IS_AT_LEAST(2,17,0)- [C.throwBlock| EvalState* {- nix::SearchPath searchPaths;- return new EvalState(searchPaths, *$(refStore* store));- } |]-#else- [C.throwBlock| EvalState* {- Strings searchPaths;- return new EvalState(searchPaths, *$(refStore* store));- } |]-#endif -- | (private) Don't leak it. deleteEvalState :: MonadIO m => (Ptr EvalState) -> m ()@@ -343,13 +289,7 @@ [C.throwBlock| void { std::string path = std::string($bs-ptr:path, $bs-len:path); EvalState &evalState = *$(EvalState *evalState);-#if NIX_IS_AT_LEAST(2,20,0) evalState.allowPath(path);-#else- if (evalState.allowedPaths) {- evalState.allowedPaths->insert(path);- }-#endif }|] addInternalAllowedPaths :: Ptr EvalState -> IO ()@@ -364,13 +304,7 @@ EvalState & state = *$(EvalState *evalState); Value value; auto cstr = $(const char *filename');-#if NIX_IS_AT_LEAST(2,19,0) SourcePath path {state.rootPath(CanonPath(cstr))};-#elif NIX_IS_AT_LEAST(2,16,0)- SourcePath path = CanonPath(cstr);-#else- std::string path = cstr;-#endif state.evalFile(path, value); return new (NoGC) Value(value); }|]@@ -391,11 +325,7 @@ =<< [C.throwBlock| Value* { Value result; $(EvalState *evalState)->autoCallFunction(-#if NIX_IS_AT_LEAST(2,24,0) const_cast<Bindings &>(*$(Value *autoArgs)->attrs()),-#else- *$(Value *autoArgs)->attrs,-#endif *$(Value *fun), result); return new (NoGC) Value (result);@@ -424,11 +354,7 @@ <$> [C.throwBlock| int { Value *v = $(Value *v); EvalState &evalState = *$(EvalState *evalState);-#if NIX_IS_AT_LEAST(2,24,0) auto attrs = v->attrs();-#else- auto attrs = v->attrs;-#endif // Bindings::const_iterator iter; // 2.24 auto iter = attrs->find(evalState.sRecurseForDerivations); if (iter == attrs->end()) {@@ -438,13 +364,7 @@ // case to return true when it is not a bool. That logic was added // because an empty attrset was found here, observed in // nixpkgs master 67e2de195a4aa0a50ffb1e1ba0b4fb531dca67dc-#if NIX_IS_AT_LEAST(2,14,0) return evalState.forceBool(*iter->value, iter->pos, "while evaluating whether to traverse into an attribute set to find more derivations");-#elif NIX_IS_AT_LEAST(2,9,0)- return evalState.forceBool(*iter->value, iter->pos);-#else- return evalState.forceBool(*iter->value, *iter->pos);-#endif } } |] @@ -455,11 +375,7 @@ Value &v = *$(Value *v); EvalState &evalState = *$(EvalState *evalState); Symbol k = evalState.symbols.create($bs-cstr:k);-#if NIX_IS_AT_LEAST(2,24,0) auto attrs = v.attrs();-#else- auto attrs = v.attrs;-#endif // Bindings::const_iterator iter; // 2.24 auto iter = attrs->find(k); if (iter == attrs->end()) {@@ -476,25 +392,16 @@ getAttrs :: Ptr EvalState -> Value NixAttrs -> IO (Map ByteString RawValue) getAttrs evalState (Value (RawValue v)) = do-#if NIX_IS_AT_LEAST(2,24,0) begin <- [C.exp| const Attr *{ $(Value *v)->attrs()->begin() }|] end <- [C.exp| const Attr *{ $(Value *v)->attrs()->end() }|]-#else- begin <- [C.exp| Attr *{ $(Value *v)->attrs->begin() }|]- end <- [C.exp| Attr *{ $(Value *v)->attrs->end() }|]-#endif let gather :: Map ByteString RawValue -> Ptr Attr' -> IO (Map ByteString RawValue) gather acc i | i == end = pure acc gather acc i = do-#if NIX_IS_AT_LEAST(2,9,0) name <- BS.unsafePackMallocCString =<< [C.block| const char *{ EvalState &evalState = *$(EvalState *evalState); SymbolStr str = evalState.symbols[$(Attr *i)->name]; return stringdup(static_cast<std::string>(str)); }|]-#else- name <- BS.unsafePackMallocCString =<< [C.exp| const char *{ stringdup(static_cast<std::string>($(Attr *i)->name)) } |]-#endif value <- mkRawValue =<< [C.exp| Value *{ new (NoGC) Value(*$(Attr *i)->value) } |] let acc' = M.insert name value acc seq acc' pass@@ -508,18 +415,9 @@ EvalState &state = *$(EvalState *evalState); auto drvInfo = getDerivation(state, *$(Value *v), false); if (!drvInfo)-#if NIX_IS_AT_LEAST(2,24,0) throw EvalError(state, "Not a valid derivation");-#else- throw EvalError("Not a valid derivation");-#endif -#if NIX_IS_AT_LEAST(2,7,0) StorePath storePath = drvInfo->requireDrvPath();-#else- std::string drvPath = drvInfo->queryDrvPath();- StorePath storePath = state.store->parseStorePath(drvPath);-#endif // write it (?) auto drv = state.store->derivationFromPath(storePath);@@ -573,13 +471,7 @@ =<< [C.throwBlock| Value *{ EvalState &evalState = *$(EvalState *evalState); std::string basePathStr = std::string($bs-ptr:basePath, $bs-len:basePath);-#if NIX_IS_AT_LEAST(2,19,0) SourcePath basePath {evalState.rootPath(CanonPath(basePathStr))};-#elif NIX_IS_AT_LEAST(2,16,0)- SourcePath basePath = CanonPath(basePathStr);-#else- auto & basePath = basePathStr;-#endif Expr *expr = evalState.parseExprFromString(std::string($bs-ptr:s, $bs-len:s), basePath); Value *r = new (NoGC) Value(); evalState.eval(expr, *r);@@ -607,22 +499,14 @@ }|] mkPath :: Ptr EvalState -> ByteString -> IO (Value NixPath)-#if NIX_IS_AT_LEAST(2,19,0) mkPath evalState path =-#else-mkPath _evalState path =-#endif Value <$> ( mkRawValue =<< [C.throwBlock| Value *{ Value *r = new (NoGC) Value(); std::string s($bs-ptr:path, $bs-len:path);-#if NIX_IS_AT_LEAST(2,19,0) EvalState & state = *$(EvalState *evalState); r->mkPath(state.rootPath(CanonPath(s)));-#else- r->mkPath(stringdup(s));-#endif return r; }|] )@@ -634,27 +518,19 @@ Value *r = new (NoGC) Value(); std::string flakeRefStr($bs-ptr:flakeRef, $bs-len:flakeRef); auto flakeRef = nix::parseFlakeRef(-#if NIX_IS_AT_LEAST(2,24,0) fetchSettings,-#endif flakeRefStr, {}, true); nix::flake::callFlake(evalState, nix::flake::lockFlake(-#if NIX_IS_AT_LEAST(2,24,0) flakeSettings,-#endif evalState, flakeRef, nix::flake::LockFlags { .updateLockFile = false, .useRegistries = false,-#if NIX_IS_AT_LEAST(2,13,0) .allowUnlocked = false,-#else- .allowMutable = false,-#endif }), *r); return r;@@ -670,27 +546,19 @@ Value *r = new (NoGC) Value(); std::string path($bs-ptr:absPath, $bs-len:absPath); auto flakeRef = nix::parseFlakeRef(-#if NIX_IS_AT_LEAST(2,24,0) fetchSettings,-#endif path, {}, true); nix::flake::callFlake(evalState, nix::flake::lockFlake(-#if NIX_IS_AT_LEAST(2,24,0) flakeSettings,-#endif evalState, flakeRef, nix::flake::LockFlags { .updateLockFile = false, .useRegistries = false,-#if NIX_IS_AT_LEAST(2,13,0) .allowUnlocked = false,-#else- .allowMutable = false,-#endif }), *r); return r;@@ -716,25 +584,17 @@ attrs.emplace("rev", rev); auto flakeRef = nix::FlakeRef::fromAttrs(-#if NIX_IS_AT_LEAST(2,24,0) fetchSettings,-#endif attrs); nix::flake::callFlake(evalState, nix::flake::lockFlake(-#if NIX_IS_AT_LEAST(2,24,0) flakeSettings,-#endif evalState, flakeRef, nix::flake::LockFlags { .updateLockFile = false, .useRegistries = false,-#if NIX_IS_AT_LEAST(2,13,0) .allowUnlocked = false,-#else- .allowMutable = false,-#endif }), *r); return r;@@ -882,7 +742,6 @@ instance ToRawValue a => ToRawValue (Map ByteString a) -#if NIX_IS_AT_LEAST(2,6,0) withBindingsBuilder :: Integral n => Ptr EvalState -> n -> (Ptr BindingsBuilder' -> IO ()) -> IO (Value NixAttrs) withBindingsBuilder evalState n f = do withBindingsBuilder' evalState n \bb -> do@@ -905,12 +764,10 @@ return new BindingsBuilder(evalState, evalState.allocBindings($(int l))); }|] \bb -> [C.block| void { delete $(BindingsBuilder *bb); }|]-#endif instance ToRawValue a => ToValue (Map ByteString a) where type NixTypeFor (Map ByteString a) = NixAttrs -#if NIX_IS_AT_LEAST(2,6,0) toValue evalState attrs = withBindingsBuilder evalState (length attrs) \bb -> do attrs & traverseWithKey_ \k a -> do RawValue aRaw <- toRawValue evalState a@@ -920,30 +777,6 @@ Value &a = *$(Value *aRaw); $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a; }|]-#else- toValue evalState attrs = do- let l :: C.CInt- l = fromIntegral (length attrs)- v <-- [C.block| Value* {- EvalState &evalState = *$(EvalState *evalState);- Value *v = new (NoGC) Value();- evalState.mkAttrs(*v, $(int l));- return v;- }|]- attrs & traverseWithKey_ \k a -> do- RawValue aRaw <- toRawValue evalState a- [C.block| void {- EvalState &evalState = *$(EvalState *evalState);- std::string k($bs-ptr:k, $bs-len:k);- Value &a = *$(Value *aRaw);- *evalState.allocAttr(*$(Value *v), evalState.symbols.create(k)) = a;- }|]- [C.block| void {- $(Value *v)->attrs->sort();- }|]- Value <$> mkRawValue v-#endif instance ToRawValue a => ToRawValue (Map Text a) @@ -984,7 +817,6 @@ instance ToRawValue a => ToValue (H.HashMap Text a) where type NixTypeFor (H.HashMap Text a) = NixAttrs -#if NIX_IS_AT_LEAST(2,6,0) toValue evalState attrs = withBindingsBuilder evalState (length attrs) \bb -> do attrs & hmTraverseWithKey_ \k' a -> do RawValue aRaw <- toRawValue evalState a@@ -995,38 +827,12 @@ Value &a = *$(Value *aRaw); $(BindingsBuilder *bb)->alloc(evalState.symbols.create(k)) = a; }|]-#else- toValue evalState attrs = do- let l :: C.CInt- l = fromIntegral (length attrs)- v <-- [C.block| Value* {- EvalState &evalState = *$(EvalState *evalState);- Value *v = new (NoGC) Value();- evalState.mkAttrs(*v, $(int l));- return v;- }|]- attrs & hmTraverseWithKey_ \k' a -> do- RawValue aRaw <- toRawValue evalState a- let k = encodeUtf8 k'- [C.block| void {- EvalState &evalState = *$(EvalState *evalState);- std::string k($bs-ptr:k, $bs-len:k);- Value &a = *$(Value *aRaw);- *evalState.allocAttr(*$(Value *v), evalState.symbols.create(k)) = a;- }|]- [C.block| void {- $(Value *v)->attrs->sort();- }|]- Value <$> mkRawValue v-#endif instance ToRawValue a => ToRawValue (Vector a) instance ToRawValue a => ToValue (Vector a) where type NixTypeFor (Vector a) = NixList toValue evalState vec =-#if NIX_IS_AT_LEAST(2,24,0) coerce <$> do let l :: C.CInt l = fromIntegral (length vec)@@ -1049,26 +855,6 @@ return v; }|] Value <$> mkRawValue v-#else- coerce <$> do- let l :: C.CInt- l = fromIntegral (length vec)- v <-- [C.block| Value* {- EvalState &evalState = *$(EvalState *evalState);- Value *v = new (NoGC) Value();- evalState.mkList(*v, $(int l));- return v;- }|]- vec & V.imapM_ \i a -> do- RawValue aRaw <- toRawValue evalState a- let ix = fromIntegral i- [C.block| void {- Value &v = *$(Value *v);- v.listElems()[$(int ix)] = $(Value *aRaw);- }|]- Value <$> mkRawValue v-#endif instance ToRawValue a => ToRawValue [a]
src/Hercules/CNix/Expr/Context.hs view
@@ -10,9 +10,7 @@ Value', Attr', BindingsBuilder',-#if NIX_IS_AT_LEAST(2,24,0) ListBuilder',-#endif module Hercules.CNix.Store.Context, (=:), )@@ -33,9 +31,7 @@ data BindingsBuilder' -#if NIX_IS_AT_LEAST(2,24,0) data ListBuilder'-#endif context :: C.Context context =@@ -59,8 +55,6 @@ =: [t|Attr'|] <> C.TypeName "BindingsBuilder" =: [t|BindingsBuilder'|]-#if NIX_IS_AT_LEAST(2,24,0) <> C.TypeName "ListBuilder" =: [t|ListBuilder'|]-#endif }
src/Hercules/CNix/Expr/Raw.hs view
@@ -20,16 +20,8 @@ C.context context -#if NIX_IS_AT_LEAST(2, 28, 0)- C.include "<nix/expr/eval.hh>" C.include "<nix/expr/eval-inline.hh>"--#else-C.include "<nix/config.h>"-C.include "<nix/eval.hh>"-C.include "<nix/eval-inline.hh>"-#endif C.include "<hercules-ci-cnix/expr.hxx>" C.include "<gc/gc.h>"
src/Hercules/CNix/Expr/Typed.hs view
@@ -48,23 +48,9 @@ C.include "<math.h>" -#if NIX_IS_AT_LEAST(2, 28, 0)- C.include "<nix/expr/eval.hh>" C.include "<nix/expr/eval-inline.hh>" -#else-C.include "<nix/config.h>"-C.include "<nix/shared.hh>"-C.include "<nix/eval.hh>"-C.include "<nix/eval-inline.hh>"-C.include "<nix/store-api.hh>"--- C.include "<nix/common-eval-args.hh>"-C.include "<nix/get-drvs.hh>"-C.include "<nix/derivations.hh>"-C.include "<nix/globals.hh>"-#endif- C.include "hercules-ci-cnix/expr.hxx" C.include "<gc/gc.h>"@@ -152,42 +138,24 @@ getBool :: Value Bool -> IO Bool getBool (Value (RawValue v)) = (0 /=) <$>-#if NIX_IS_AT_LEAST(2,24,0) [C.exp| int { $(Value *v)->boolean() ? 1 : 0 }|]-#else- [C.exp| int { $(Value *v)->boolean ? 1 : 0 }|]-#endif getInt :: Value NixInt -> IO Int64 getInt (Value (RawValue v)) =-#if NIX_IS_AT_LEAST(2,27,0) [C.exp| int64_t { $(Value *v)->integer().value }|]-#elif NIX_IS_AT_LEAST(2,24,0)- [C.exp| int64_t { $(Value *v)->integer() }|]-#else- [C.exp| int64_t { $(Value *v)->integer }|]-#endif -- NOT coerceToString getStringIgnoreContext :: Value NixString -> IO ByteString getStringIgnoreContext (Value (RawValue v)) = BS.unsafePackMallocCString =<< [C.exp| const char *{-#if NIX_IS_AT_LEAST(2,19,0) strdup($(Value *v)->c_str())-#else- strdup($(Value *v)->string.s)-#endif }|] hasContext :: Value NixString -> IO Bool hasContext (Value (RawValue v)) = (0 /=) <$>-#if NIX_IS_AT_LEAST(2,24,0) [C.exp| int { $(Value *v)->context() ? 1 : 0 }|]-#else- [C.exp| int { $(Value *v)->string.context ? 1 : 0 }|]-#endif class CheckType a where checkType :: Ptr EvalState -> RawValue -> IO (Maybe (Value a))