packages feed

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 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))