From 49bce28c9c07bd359fc5ba047c5cd6f3f17e3f5a Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 18 Jan 2022 00:28:15 +0200 Subject: [PATCH 1/3] Builtins: add unsafeDiscardOutputDependency Courtesy of `layus`, ported from implementation in https://github.com/haskell-nix/hnix/pull/755. --- src/Nix/Builtins.hs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs index efca92473..7a707ef1b 100644 --- a/src/Nix/Builtins.hs +++ b/src/Nix/Builtins.hs @@ -46,6 +46,7 @@ import Data.Char ( isDigit ) import Data.Foldable ( foldrM ) import Data.Fix ( foldFix ) import Data.List ( partition ) +import qualified Data.HashSet as HS import qualified Data.HashMap.Lazy as M import Data.Scientific import qualified Data.Set as S @@ -471,6 +472,20 @@ getAttrNix x y = attrsetGet key aset +unsafeDiscardOutputDependencyNix + :: forall e t f m + . MonadNix e t f m + => NValue t f m + -> m (NValue t f m) +unsafeDiscardOutputDependencyNix nv = + do + (nc, ns) <- (getStringContext &&& ignoreContext) <$> fromValue nv + toValue $ mkNixString (HS.map discard nc) ns + where + discard :: StringContext -> StringContext + discard (StringContext AllOutputs a) = StringContext DirectPath a + discard x = x + unsafeGetAttrPosNix :: forall e t f m . MonadNix e t f m @@ -1906,7 +1921,7 @@ builtinsList = , add0 Normal "true" (pure $ mkNVBool True) , add Normal "tryEval" tryEvalNix , add Normal "typeOf" typeOfNix - --, add0 Normal "unsafeDiscardOutputDependency" unsafeDiscardOutputDependency + , add Normal "unsafeDiscardOutputDependency" unsafeDiscardOutputDependencyNix , add Normal "unsafeDiscardStringContext" unsafeDiscardStringContextNix , add2 Normal "unsafeGetAttrPos" unsafeGetAttrPosNix , add Normal "valueSize" getRecursiveSizeNix From f52c486569f5b6fa66abf52cee6c1baa95769708 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 18 Jan 2022 01:46:10 +0200 Subject: [PATCH 2/3] Builtins: add path Courtesy of `layus`, ported from implementation in https://github.com/haskell-nix/hnix/pull/755. --- src/Nix/Builtins.hs | 46 ++++++++++++++++++++++++++++++++++++++- tests/NixLanguageTests.hs | 5 ++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs index 7a707ef1b..25745852b 100644 --- a/src/Nix/Builtins.hs +++ b/src/Nix/Builtins.hs @@ -885,6 +885,50 @@ builtinsBuiltinNix => m (NValue t f m) builtinsBuiltinNix = throwError $ ErrorCall "HNix does not provide builtins.builtins at the moment. Using builtins directly should be preferred" +attrGetOr' + :: forall e t f m v a + . (MonadNix e t f m, FromValue v m (NValue t f m)) + => AttrSet (NValue t f m) + -> VarName + -> m a + -> (v -> m a) + -> m a +attrGetOr' attrs n d f = + maybe + d + (f <=< fromValue) + (M.lookup n attrs) + +attrGetOr + :: forall e t f m v a + . (MonadNix e t f m, FromValue v m (NValue t f m)) + => AttrSet (NValue t f m) + -> VarName + -> a + -> (v -> m a) + -> m a +attrGetOr attrs name fallback = attrGetOr' attrs name (pure fallback) + +-- NOTE: It is a part of the implementation taken from: +-- https://github.com/haskell-nix/hnix/pull/755 +-- look there for `sha256` and/or `filterSource` +pathNix :: forall e t f m. MonadNix e t f m => NValue t f m -> m (NValue t f m) +pathNix arg = + do + attrs <- fromValue @(AttrSet (NValue t f m)) arg + path <- fmap (coerce . toString) $ fromStringNoContext =<< coerceToPath =<< attrsetGet "path" attrs + + -- TODO: Fail on extra args + -- XXX: This is a very common pattern, we could factor it out + name <- toText <$> attrGetOr attrs "name" (takeFileName path) (fmap (coerce . toString) . fromStringNoContext) + recursive <- attrGetOr attrs "recursive" True pure + + Right (coerce . toText . coerce @StorePath @String -> s) <- addToStore name path recursive False + -- TODO: Ensure that s matches sha256 when not empty + pure $ mkNVStr $ mkNixStringWithSingletonContext (StringContext DirectPath s) s + where + coerceToPath = coerceToString callFunc DontCopyToStore CoerceAny + dirOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m) dirOfNix nvdir = do @@ -1899,7 +1943,7 @@ builtinsList = , add0 Normal "null" (pure nvNull) , add Normal "parseDrvName" parseDrvNameNix , add2 Normal "partition" partitionNix - --, add Normal "path" path + , add Normal "path" pathNix , add Normal "pathExists" pathExistsNix , add Normal "readDir" readDirNix , add Normal "readFile" readFileNix diff --git a/tests/NixLanguageTests.hs b/tests/NixLanguageTests.hs index 6890dc3ed..6295317e3 100644 --- a/tests/NixLanguageTests.hs +++ b/tests/NixLanguageTests.hs @@ -56,8 +56,7 @@ groupBy key = Map.fromListWith (<>) . fmap (key &&& pure) -- previously passed. newFailingTests :: Set String newFailingTests = Set.fromList - [ "eval-okay-path" -- #128 - , "eval-okay-fromTOML" + [ "eval-okay-fromTOML" , "eval-okay-zipAttrsWith" , "eval-okay-tojson" , "eval-okay-search-path" @@ -75,7 +74,7 @@ deprecatedRareNixQuirkTests :: Set String deprecatedRareNixQuirkTests = Set.fromList [ -- A rare quirk of Nix that is proper to fix&enforce then to support (see git commit history) "eval-okay-strings-as-attrs-names" - -- Nix upstream removed this test alltogather + -- Nix upstream removed this test altogether , "eval-okay-hash" ] From cce482febe03aaba13852e3ff4b6a8fab0cc0f4c Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 18 Jan 2022 02:17:35 +0200 Subject: [PATCH 3/3] Builtins: refactor attrGetOr --- src/Nix/Builtins.hs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs index 25745852b..dc86ab9e0 100644 --- a/src/Nix/Builtins.hs +++ b/src/Nix/Builtins.hs @@ -885,29 +885,21 @@ builtinsBuiltinNix => m (NValue t f m) builtinsBuiltinNix = throwError $ ErrorCall "HNix does not provide builtins.builtins at the moment. Using builtins directly should be preferred" -attrGetOr' +-- a safer version of `attrsetGet` +attrGetOr :: forall e t f m v a . (MonadNix e t f m, FromValue v m (NValue t f m)) - => AttrSet (NValue t f m) - -> VarName - -> m a + => a -> (v -> m a) + -> VarName + -> AttrSet (NValue t f m) -> m a -attrGetOr' attrs n d f = +attrGetOr fallback fun name attrs = maybe - d - (f <=< fromValue) - (M.lookup n attrs) + (pure fallback) + (fun <=< fromValue) + (M.lookup name attrs) -attrGetOr - :: forall e t f m v a - . (MonadNix e t f m, FromValue v m (NValue t f m)) - => AttrSet (NValue t f m) - -> VarName - -> a - -> (v -> m a) - -> m a -attrGetOr attrs name fallback = attrGetOr' attrs name (pure fallback) -- NOTE: It is a part of the implementation taken from: -- https://github.com/haskell-nix/hnix/pull/755 @@ -920,8 +912,8 @@ pathNix arg = -- TODO: Fail on extra args -- XXX: This is a very common pattern, we could factor it out - name <- toText <$> attrGetOr attrs "name" (takeFileName path) (fmap (coerce . toString) . fromStringNoContext) - recursive <- attrGetOr attrs "recursive" True pure + name <- toText <$> attrGetOr (takeFileName path) (fmap (coerce . toString) . fromStringNoContext) "name" attrs + recursive <- attrGetOr True pure "recursive" attrs Right (coerce . toText . coerce @StorePath @String -> s) <- addToStore name path recursive False -- TODO: Ensure that s matches sha256 when not empty