packages feed

hercules-ci-cnix-expr 0.3.5.1 → 0.3.6.0

raw patch · 6 files changed

+115/−29 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue Data.ByteString.Internal.ByteString
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue a => Hercules.CNix.Expr.ToRawValue (Data.Map.Internal.Map Data.ByteString.Internal.ByteString a)
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue a => Hercules.CNix.Expr.ToValue (Data.Map.Internal.Map Data.ByteString.Internal.ByteString a)
- Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue Data.ByteString.Internal.ByteString
- Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.FromPSObject Hercules.CNix.Expr.Schema.StringWithoutContext Data.ByteString.Internal.ByteString
+ Hercules.CNix.Expr: allowThreads :: IO ()
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue Data.ByteString.Internal.Type.ByteString
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue a => Hercules.CNix.Expr.ToRawValue (Data.Map.Internal.Map Data.ByteString.Internal.Type.ByteString a)
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToRawValue a => Hercules.CNix.Expr.ToValue (Data.Map.Internal.Map Data.ByteString.Internal.Type.ByteString a)
+ Hercules.CNix.Expr: instance Hercules.CNix.Expr.ToValue Data.ByteString.Internal.Type.ByteString
+ Hercules.CNix.Expr: runGcRegisteredThread :: IO a -> IO a
+ Hercules.CNix.Expr.Schema: instance Hercules.CNix.Expr.Schema.FromPSObject Hercules.CNix.Expr.Schema.StringWithoutContext Data.ByteString.Internal.Type.ByteString
- Hercules.CNix.Expr.Schema: (#.) :: (KnownSymbol s, (as . s) ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: (#.) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject (as . s))
- Hercules.CNix.Expr.Schema: (#?!) :: (KnownSymbol s, (as ? s) ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: (#?!) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject (as ? s))
- Hercules.CNix.Expr.Schema: (#?) :: (KnownSymbol s, (as ? s) ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (Maybe (PSObject b))
+ Hercules.CNix.Expr.Schema: (#?) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (Maybe (PSObject (as ? s)))
- Hercules.CNix.Expr.Schema: ($?) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => PSObject (a ->? b) -> PSObject a -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: ($?) :: (MonadEval m, PossibleTypesForSchema b) => PSObject (a ->? b) -> PSObject a -> m (PSObject b)
- Hercules.CNix.Expr.Schema: (>>$.) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => m (PSObject (a ->. b)) -> m (PSObject a) -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: (>>$.) :: MonadEval m => m (PSObject (a ->. b)) -> m (PSObject a) -> m (PSObject b)
- Hercules.CNix.Expr.Schema: (>>$?) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => m (PSObject (a ->? b)) -> m (PSObject a) -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: (>>$?) :: (MonadEval m, PossibleTypesForSchema b) => m (PSObject (a ->? b)) -> m (PSObject a) -> m (PSObject b)
- Hercules.CNix.Expr.Schema: (>>.) :: (KnownSymbol s, (as . s) ~ b, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (PSObject b)
+ Hercules.CNix.Expr.Schema: (>>.) :: (KnownSymbol s, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (PSObject (as . s))
- Hercules.CNix.Expr.Schema: (>>?) :: (KnownSymbol s, (as ? s) ~ b, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (Maybe (PSObject b))
+ Hercules.CNix.Expr.Schema: (>>?) :: (KnownSymbol s, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (Maybe (PSObject (as ? s)))
- Hercules.CNix.Expr.Schema: (|!) :: forall a b c m. (CheckType (NixTypeForSchema a), MonadIO m, MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => (PSObject a -> m c) -> (PSObject b -> m c) -> PSObject (a |. b) -> m c
+ Hercules.CNix.Expr.Schema: (|!) :: forall a b c m. (CheckType (NixTypeForSchema a), MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => (PSObject a -> m c) -> (PSObject b -> m c) -> PSObject (a |. b) -> m c

Files

CHANGELOG.md view
@@ -5,6 +5,16 @@  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 0.3.6.0 - 2023-06-28++### Added++ - `allowThreads`, `runInGcSafeThread`++ - Nix 2.15 support++ - Nix 2.16 support+ ## 0.3.5.1 - 2023-03-06  ### Added
hercules-ci-cnix-expr.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4  name:           hercules-ci-cnix-expr-version:        0.3.5.1+version:        0.3.6.0 synopsis:       Bindings for the Nix evaluator category:       Nix, CI, Testing, DevOps homepage:       https://docs.hercules-ci.com@@ -34,32 +34,42 @@   description: Build for Nix >=2.4pre*   default: True -flag nix-2_5+flag nix-2_15   description: Build for Nix >=2.5pre*   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++17     -Wall   extra-libraries: stdc++ -  if flag(nix-2_5)-    cxx-options:-      -DNIX_2_5-    cpp-options:-      -DNIX_2_5-   if os(darwin)     -- avoid https://gitlab.haskell.org/ghc/ghc/issues/11829     ld-options:  -Wl,-keep_dwarf_unwind    if impl(ghc >= 8.10)     ghc-options:-      -optcxx-std=c++17       -optcxx-Wall+    if flag(nix-2_15)+      ghc-options:+        -optcxx-std=c++2a+    else+      ghc-options:+        -optcxx-std=c++17   else+    -- Remove soon     ghc-options:       -optc-std=c++17       -optc-Wall@@ -113,8 +123,9 @@       include   install-includes:       hercules-ci-cnix/expr.hxx-  extra-libraries:-      boost_context+  if ! flag(ide)+    extra-libraries:+        boost_context   pkgconfig-depends:       nix-store >= 2.4     , nix-expr >= 2.4@@ -125,7 +136,7 @@       nix-cmd >= 2.8  -test-suite hercules-ci-cnix-expr-tests+test-suite hercules-ci-cnix-expr-unit-tests   type: exitcode-stdio-1.0   main-is: TestMain.hs   other-modules:
src/Hercules/CNix/Expr.hs view
@@ -8,6 +8,10 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-}++-- redundant-constraints: False positive in default signature for `toRawValue`+{-# OPTIONS_GHC -Wno-redundant-constraints #-}+ #ifdef __GHCIDE__ # define NIX_IS_AT_LEAST(mm,m,p) 1 #endif@@ -20,6 +24,8 @@     setOption,     setExtraStackOverflowHandlerToSleep,     initThread,+    allowThreads,+    runGcRegisteredThread,     logInfo,     withEvalState,     withEvalStateConduit,@@ -91,6 +97,8 @@  C.context (Hercules.CNix.Store.Context.context <> Hercules.CNix.Expr.Context.evalContext) +C.verbatim "#define GC_THREADS 1"+ C.include "<stdio.h>"  C.include "<cstring>"@@ -137,7 +145,10 @@     [C.throwBlock| void {       nix::initNix();       nix::initGC();-#ifdef NIX_2_5+#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@@ -145,8 +156,10 @@       features.push_back("flakes"); #endif       nix::settings.experimentalFeatures.assign(features);+#endif     } |] +-- | Initialize the current (main) thread for stack overflow detection. initThread :: IO () initThread =   void@@ -154,6 +167,47 @@       nix::detectStackOverflow();     }|] +-- | Configure the garbage collector to support threads.+--+-- This is not needed when all evaluation happens on the main thread.+allowThreads :: IO ()+allowThreads =+  void+    [C.block| void {+      GC_allow_register_threads();+    }|]++-- | Run in a thread from which GC may be triggered safely.+--+-- This also installs the stack overflow handler.+--+-- NOTE: Before using this, you must call 'allowThreads' once.+runGcRegisteredThread :: IO a -> IO a+runGcRegisteredThread io =+  runInBoundThread do+    bracket+      start+      (const end)+      (const io)+  where+    start =+      do+        initThread+        [C.block| void {+          struct GC_stack_base sb;+          int r = GC_get_stack_base(&sb);+          assert(r == GC_SUCCESS);+          GC_register_my_thread(&sb);+        }|]+        pass+    end =+      do+        [C.block| void {+          GC_unregister_my_thread();+        }|]+        pass++ {- | Configure the stack overflow handler to sleep before returning, allowing   other threads to continue for a bit. @@ -265,7 +319,13 @@   mkRawValue     =<< [C.throwBlock| Value* {       Value value;-      $(EvalState *evalState)->evalFile($(const char *filename'), value);+      auto cstr = $(const char *filename');+#if NIX_IS_AT_LEAST(2,16,0)+      SourcePath path = CanonPath(cstr);+#else+      std::string path = cstr;+#endif+      $(EvalState *evalState)->evalFile(path, value);       return new (NoGC) Value(value);     }|] @@ -462,7 +522,13 @@   mkRawValue     =<< [C.throwBlock| Value *{       EvalState &evalState = *$(EvalState *evalState);-      Expr *expr = evalState.parseExprFromString(std::string($bs-ptr:s, $bs-len:s), std::string($bs-ptr:basePath, $bs-len:basePath));+      std::string basePathStr = std::string($bs-ptr:basePath, $bs-len:basePath);+#if 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);       return r;@@ -628,10 +694,10 @@   toRawValue _ = pure  -- | Upcast-instance ToRawValue (Value a)+instance forall (a :: Type). ToRawValue (Value a)  -- | Identity-instance ToValue (Value a) where+instance forall (a :: Type). ToValue (Value a) where   type NixTypeFor (Value a) = a   toValue _ = pure 
src/Hercules/CNix/Expr/Schema.hs view
@@ -270,11 +270,11 @@ type MonadEval m = (MonadIO m, MonadReader (Ptr EvalState) m)  -- | A combination of '>>=' and '#.'.-(>>.) :: (KnownSymbol s, as . s ~ b, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (PSObject b)+(>>.) :: (KnownSymbol s, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (PSObject (as . s)) mas >>. p = mas >>= \as -> as #. p  -- | Attribute selector. @a #. #b@ is @a.b@ in Nix. Operates on attributes that are required (@_.@) in the schema, throwing an error if necessary.-(#.) :: (KnownSymbol s, as . s ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject b)+(#.) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject (as . s)) as #. p = do   evalState <- ask   let name = T.pack (symbolVal p)@@ -284,11 +284,11 @@     Just b -> pure PSObject {value = b, provenance = Attribute (provenance as) name}  -- | A combination of '>>=' and '#?'.-(>>?) :: (KnownSymbol s, as ? s ~ b, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (Maybe (PSObject b))+(>>?) :: (KnownSymbol s, MonadEval m) => m (PSObject (Attrs' as w)) -> AttrLabel s -> m (Maybe (PSObject (as ? s))) mas >>? p = mas >>= \as -> as #? p  -- | Attribute selector. @a #? #b@ is @a.b@ in Nix, but handles the missing case without exception. Operates on attributes that are optional (@_?@) in the schema, throwing an error if necessary.-(#?) :: (KnownSymbol s, as ? s ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (Maybe (PSObject b))+(#?) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (Maybe (PSObject (as ? s))) as #? p = do   evalState <- ask   let name = T.pack (symbolVal p)@@ -306,7 +306,7 @@ -- -- It provides a decent error message with attrset provenance, but can't provide -- extra context like you can when manually handling the @a '#?' b@ 'Nothing' case.-(#?!) :: (KnownSymbol s, as ? s ~ b, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject b)+(#?!) :: (KnownSymbol s, MonadEval m) => PSObject (Attrs' as w) -> AttrLabel s -> m (PSObject (as ? s)) as #?! p = do   as #? p >>= \case     Nothing -> throwIO $ MissingAttribute (provenance as) (T.pack (symbolVal p))@@ -392,7 +392,6 @@ (|!) ::   forall a b c m.   ( CheckType (NixTypeForSchema a),-    MonadIO m,     MonadEval m,     PossibleTypesForSchema a,     PossibleTypesForSchema b@@ -421,12 +420,12 @@ englishOr (a : as) = a <> ", " <> englishOr as  -- | Optional application.-($?) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => PSObject (a ->? b) -> PSObject a -> m (PSObject b)+($?) :: (MonadEval m, PossibleTypesForSchema b) => PSObject (a ->? b) -> PSObject a -> m (PSObject b) x $? a =   pure x >>$? pure a  -- | Optional application. Like '$?' but takes care of monadic binding as a convenience.-(>>$?) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => m (PSObject (a ->? b)) -> m (PSObject a) -> m (PSObject b)+(>>$?) :: (MonadEval m, PossibleTypesForSchema b) => m (PSObject (a ->? b)) -> m (PSObject a) -> m (PSObject b) x >>$? a =   ( (\f -> a >>= (f .$))       |! pure@@ -434,7 +433,7 @@     =<< x  -- | Application. Like '$.' but takes care of monadic binding as a convenience.-(>>$.) :: (MonadEval m, PossibleTypesForSchema a, PossibleTypesForSchema b) => m (PSObject (a ->. b)) -> m (PSObject a) -> m (PSObject b)+(>>$.) :: (MonadEval m) => m (PSObject (a ->. b)) -> m (PSObject a) -> m (PSObject b) f >>$. a = do   f' <- f   a' <- a
test/Hercules/CNix/Expr/SchemaSpec.hs view
@@ -8,7 +8,6 @@ import qualified Hercules.CNix.Expr as Expr import Hercules.CNix.Expr.Raw (RawValueType (Attrs, Bool, Lambda, Null, String)) import Hercules.CNix.Expr.Schema-import Hercules.CNix.Expr.Schema (FromPSObject (fromPSObject)) import Protolude hiding (TypeError, check, evalState) import SingleState (evalState) import Test.Hspec
test/Hercules/CNix/ExprSpec.hs view
@@ -136,7 +136,8 @@                 ExitSuccess -> pass             readProc exe args = do               -- putErrText $ "Reading " <> show exe <> " " <> show args-              (t, r) <- System.Process.withCreateProcess ((System.Process.proc exe args) {System.Process.cwd = Just dir, System.Process.std_out = System.Process.CreatePipe}) \_ (Just stdo) _ p -> do+              (t, r) <- System.Process.withCreateProcess ((System.Process.proc exe args) {System.Process.cwd = Just dir, System.Process.std_out = System.Process.CreatePipe}) \_ stdom _ p -> do+                stdo <- maybe (panic "no stdout") pure stdom                 t <- T.hGetContents stdo                 (t,) <$> waitForProcess p               case r of