{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
module Nix.Effects.Basic where
import Prelude hiding ( traceM
, head
)
import Relude.Unsafe ( head )
import Nix.Utils
import Control.Monad ( foldM )
import qualified Data.HashMap.Lazy as M
import Data.List.Split ( splitOn )
import qualified Data.Text as Text
import Prettyprinter ( fillSep )
import System.FilePath
import Nix.Convert
import Nix.Effects
import Nix.Exec ( MonadNix
, evalExprLoc
, nixInstantiateExpr
)
import Nix.Expr
import Nix.Frames
import Nix.Parser
import Nix.Render
import Nix.Scope
import Nix.String
import Nix.Value
import Nix.Value.Monad
#ifdef MIN_VERSION_ghc_datasize
import GHC.DataSize
#endif
defaultMakeAbsolutePath :: MonadNix e t f m => FilePath -> m FilePath
defaultMakeAbsolutePath :: FilePath -> m FilePath
defaultMakeAbsolutePath FilePath
origPath = do
FilePath
origPathExpanded <- FilePath -> m FilePath
forall (m :: * -> *). MonadFile m => FilePath -> m FilePath
expandHomePath FilePath
origPath
FilePath
absPath <-
m FilePath -> m FilePath -> Bool -> m FilePath
forall a. a -> a -> Bool -> a
bool
(do
FilePath
cwd <- do
Maybe (Free (NValue' t f m) t)
mres <- Text -> m (Maybe (Free (NValue' t f m) t))
forall a (m :: * -> *). Scoped a m => Text -> m (Maybe a)
lookupVar Text
"__cur_file"
m FilePath
-> (Free (NValue' t f m) t -> m FilePath)
-> Maybe (Free (NValue' t f m) t)
-> m FilePath
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
m FilePath
forall (m :: * -> *). MonadFile m => m FilePath
getCurrentDirectory
(
(\case
NVPath FilePath
s -> FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> m FilePath) -> FilePath -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
takeDirectory FilePath
s
Free (NValue' t f m) t
val -> ErrorCall -> m FilePath
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m FilePath) -> ErrorCall -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"when resolving relative path, __cur_file is in scope, but is not a path; it is: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> Free (NValue' t f m) t -> FilePath
forall b a. (Show a, IsString b) => a -> b
show Free (NValue' t f m) t
val
) (Free (NValue' t f m) t -> m FilePath)
-> (Free (NValue' t f m) t -> m (Free (NValue' t f m) t))
-> Free (NValue' t f m) t
-> m FilePath
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Free (NValue' t f m) t -> m (Free (NValue' t f m) t)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand
)
Maybe (Free (NValue' t f m) t)
mres
pure $ FilePath
cwd FilePath -> FilePath -> FilePath
<///> FilePath
origPathExpanded
)
(FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
origPathExpanded)
(FilePath -> Bool
isAbsolute FilePath
origPathExpanded)
FilePath -> FilePath
removeDotDotIndirections (FilePath -> FilePath) -> m FilePath -> m FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> m FilePath
forall (m :: * -> *). MonadFile m => FilePath -> m FilePath
canonicalizePath FilePath
absPath
expandHomePath :: MonadFile m => FilePath -> m FilePath
expandHomePath :: FilePath -> m FilePath
expandHomePath (Char
'~' : FilePath
xs) = (FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
xs) (FilePath -> FilePath) -> m FilePath -> m FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m FilePath
forall (m :: * -> *). MonadFile m => m FilePath
getHomeDirectory
expandHomePath FilePath
p = FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
p
removeDotDotIndirections :: FilePath -> FilePath
removeDotDotIndirections :: FilePath -> FilePath
removeDotDotIndirections = FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
"/" ([FilePath] -> FilePath)
-> (FilePath -> [FilePath]) -> FilePath -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [FilePath] -> [FilePath] -> [FilePath]
forall a. (Eq a, IsString a) => [a] -> [a] -> [a]
go [FilePath]
forall a. Monoid a => a
mempty ([FilePath] -> [FilePath])
-> (FilePath -> [FilePath]) -> FilePath -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
"/"
where
go :: [a] -> [a] -> [a]
go [a]
s [] = [a] -> [a]
forall a. [a] -> [a]
reverse [a]
s
go (a
_ : [a]
s) (a
".." : [a]
rest) = [a] -> [a] -> [a]
go [a]
s [a]
rest
go [a]
s (a
this : [a]
rest) = [a] -> [a] -> [a]
go (a
this a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
s) [a]
rest
infixr 9 <///>
(<///>) :: FilePath -> FilePath -> FilePath
FilePath
x <///> :: FilePath -> FilePath -> FilePath
<///> FilePath
y | FilePath -> Bool
isAbsolute FilePath
y Bool -> Bool -> Bool
|| FilePath
"." FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` FilePath
y = FilePath
x FilePath -> FilePath -> FilePath
</> FilePath
y
| Bool
otherwise = FilePath -> FilePath -> FilePath
joinByLargestOverlap FilePath
x FilePath
y
where
joinByLargestOverlap :: FilePath -> FilePath -> FilePath
joinByLargestOverlap (FilePath -> [FilePath]
splitDirectories -> [FilePath]
xs) (FilePath -> [FilePath]
splitDirectories -> [FilePath]
ys) =
[FilePath] -> FilePath
joinPath ([FilePath] -> FilePath) -> [FilePath] -> FilePath
forall a b. (a -> b) -> a -> b
$ [[FilePath]] -> [FilePath]
forall a. [a] -> a
head
[ [FilePath]
xs [FilePath] -> [FilePath] -> [FilePath]
forall a. Semigroup a => a -> a -> a
<> Int -> [FilePath] -> [FilePath]
forall a. Int -> [a] -> [a]
drop ([FilePath] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [FilePath]
tx) [FilePath]
ys | [FilePath]
tx <- [FilePath] -> [[FilePath]]
forall a. [a] -> [[a]]
tails [FilePath]
xs, [FilePath]
tx [FilePath] -> [[FilePath]] -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` [FilePath] -> [[FilePath]]
forall a. [a] -> [[a]]
inits [FilePath]
ys ]
defaultFindEnvPath :: MonadNix e t f m => String -> m FilePath
defaultFindEnvPath :: FilePath -> m FilePath
defaultFindEnvPath = FilePath -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
FilePath -> m FilePath
findEnvPathM
findEnvPathM :: forall e t f m . MonadNix e t f m => FilePath -> m FilePath
findEnvPathM :: FilePath -> m FilePath
findEnvPathM FilePath
name = do
Maybe (NValue t f m)
mres <- Text -> m (Maybe (NValue t f m))
forall a (m :: * -> *). Scoped a m => Text -> m (Maybe a)
lookupVar Text
"__nixPath"
m FilePath
-> (NValue t f m -> m FilePath)
-> Maybe (NValue t f m)
-> m FilePath
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(FilePath -> m FilePath
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail FilePath
"impossible")
(
(\ NValue t f m
nv ->
do
([NValue t f m]
l :: [NValue t f m]) <- NValue t f m -> m [NValue t f m]
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
nv
(FilePath -> m (Maybe FilePath))
-> [NValue t f m] -> FilePath -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
(FilePath -> m (Maybe FilePath))
-> [NValue t f m] -> FilePath -> m FilePath
findPathBy FilePath -> m (Maybe FilePath)
MonadEffects t f m => FilePath -> m (Maybe FilePath)
nixFilePath [NValue t f m]
l FilePath
name
) (NValue t f m -> m FilePath)
-> (NValue t f m -> m (NValue t f m)) -> NValue t f m -> m FilePath
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand
)
Maybe (NValue t f m)
mres
where
nixFilePath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
nixFilePath :: FilePath -> m (Maybe FilePath)
nixFilePath FilePath
path = do
FilePath
absPath <- FilePath -> m FilePath
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m FilePath
makeAbsolutePath @t @f FilePath
path
Bool
isDir <- FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
doesDirectoryExist FilePath
absPath
FilePath
absFile <-
m FilePath -> m FilePath -> Bool -> m FilePath
forall a. a -> a -> Bool -> a
bool
(FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
absPath)
(forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m FilePath
forall (m :: * -> *). MonadEffects t f m => FilePath -> m FilePath
makeAbsolutePath @t @f (FilePath -> m FilePath) -> FilePath -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
absPath FilePath -> FilePath -> FilePath
</> FilePath
"default.nix")
Bool
isDir
Bool
exists <- FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
doesFileExist FilePath
absFile
pure $
Maybe FilePath -> Maybe FilePath -> Bool -> Maybe FilePath
forall a. a -> a -> Bool -> a
bool
Maybe FilePath
forall a. Monoid a => a
mempty
(FilePath -> Maybe FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
absFile)
Bool
exists
findPathBy
:: forall e t f m
. MonadNix e t f m
=> (FilePath -> m (Maybe FilePath))
-> [NValue t f m]
-> FilePath
-> m FilePath
findPathBy :: (FilePath -> m (Maybe FilePath))
-> [NValue t f m] -> FilePath -> m FilePath
findPathBy FilePath -> m (Maybe FilePath)
finder [NValue t f m]
ls FilePath
name = do
Maybe FilePath
mpath <- (Maybe FilePath -> NValue t f m -> m (Maybe FilePath))
-> Maybe FilePath -> [NValue t f m] -> m (Maybe FilePath)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Maybe FilePath -> NValue t f m -> m (Maybe FilePath)
go Maybe FilePath
forall a. Monoid a => a
mempty [NValue t f m]
ls
m FilePath
-> (FilePath -> m FilePath) -> Maybe FilePath -> m FilePath
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(ErrorCall -> m FilePath
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m FilePath) -> ErrorCall -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"file '" FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
name FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
"' was not found in the Nix search path (add it's using $NIX_PATH or -I)")
FilePath -> m FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Maybe FilePath
mpath
where
go :: Maybe FilePath -> NValue t f m -> m (Maybe FilePath)
go :: Maybe FilePath -> NValue t f m -> m (Maybe FilePath)
go Maybe FilePath
mp =
(NValue t f m -> m (Maybe FilePath))
-> (FilePath -> NValue t f m -> m (Maybe FilePath))
-> Maybe FilePath
-> NValue t f m
-> m (Maybe FilePath)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(\ NValue t f m
nv ->
do
(HashMap Text (NValue t f m)
s :: HashMap Text (NValue t f m)) <- NValue t f m -> m (HashMap Text (NValue t f m))
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue (NValue t f m -> m (HashMap Text (NValue t f m)))
-> m (NValue t f m) -> m (HashMap Text (NValue t f m))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv
NValue t f m
p <- HashMap Text (NValue t f m) -> m (NValue t f m)
forall e (m :: * -> *) t (f :: * -> *) k.
(MonadReader e m, Scoped (NValue t f m) m,
MonadValue (NValue t f m) m, Comonad f, Has e Frames,
Has e Options, Has e SrcSpan, MonadFix m, MonadCatch m,
Alternative m, MonadEffects t f m, MonadThunk t m (NValue t f m),
Traversable f, HasCitations m (NValue t f m) t,
HasCitations1 m (NValue t f m) f, Hashable k, IsString k,
Applicative f, Eq k, Show t, Show k, Typeable m, Typeable f,
Typeable t) =>
HashMap k (NValue t f m) -> m (NValue t f m)
resolvePath HashMap Text (NValue t f m)
s
NValue t f m
nvpath <- NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
p
(Path FilePath
path) <- NValue t f m -> m Path
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
nvpath
m (Maybe FilePath)
-> (NValue t f m -> m (Maybe FilePath))
-> Maybe (NValue t f m)
-> m (Maybe FilePath)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(FilePath -> Maybe FilePath -> m (Maybe FilePath)
tryPath FilePath
path Maybe FilePath
forall a. Monoid a => a
mempty)
(\ NValue t f m
nv' ->
do
Maybe NixString
mns <- NValue t f m -> m (Maybe NixString)
forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay (NValue t f m -> m (Maybe NixString))
-> m (NValue t f m) -> m (Maybe NixString)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv'
FilePath -> Maybe FilePath -> m (Maybe FilePath)
tryPath FilePath
path (Maybe FilePath -> m (Maybe FilePath))
-> Maybe FilePath -> m (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$
case Maybe NixString
mns of
Just (NixString
nsPfx :: NixString) ->
let pfx :: Text
pfx = NixString -> Text
stringIgnoreContext NixString
nsPfx in
Maybe FilePath -> Maybe FilePath -> Bool -> Maybe FilePath
forall a. a -> a -> Bool -> a
bool
Maybe FilePath
forall a. Monoid a => a
mempty
(FilePath -> Maybe FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
pfx))
(Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> Bool
Text.null Text
pfx)
Maybe NixString
_ -> Maybe FilePath
forall a. Monoid a => a
mempty
)
(Text -> HashMap Text (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"prefix" HashMap Text (NValue t f m)
s)
)
(m (Maybe FilePath) -> NValue t f m -> m (Maybe FilePath)
forall a b. a -> b -> a
const (m (Maybe FilePath) -> NValue t f m -> m (Maybe FilePath))
-> (FilePath -> m (Maybe FilePath))
-> FilePath
-> NValue t f m
-> m (Maybe FilePath)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe FilePath -> m (Maybe FilePath)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe FilePath -> m (Maybe FilePath))
-> (FilePath -> Maybe FilePath) -> FilePath -> m (Maybe FilePath)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Maybe FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
Maybe FilePath
mp
tryPath :: FilePath -> Maybe FilePath -> m (Maybe FilePath)
tryPath :: FilePath -> Maybe FilePath -> m (Maybe FilePath)
tryPath FilePath
p (Just FilePath
n) | FilePath
n' : [FilePath]
ns <- FilePath -> [FilePath]
splitDirectories FilePath
name, FilePath
n FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
n' =
FilePath -> m (Maybe FilePath)
finder (FilePath -> m (Maybe FilePath)) -> FilePath -> m (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath
p FilePath -> FilePath -> FilePath
<///> [FilePath] -> FilePath
joinPath [FilePath]
ns
tryPath FilePath
p Maybe FilePath
_ = FilePath -> m (Maybe FilePath)
finder (FilePath -> m (Maybe FilePath)) -> FilePath -> m (Maybe FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath
p FilePath -> FilePath -> FilePath
<///> FilePath
name
resolvePath :: HashMap k (NValue t f m) -> m (NValue t f m)
resolvePath HashMap k (NValue t f m)
s =
m (NValue t f m)
-> (NValue t f m -> m (NValue t f m))
-> Maybe (NValue t f m)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(m (NValue t f m)
-> (NValue t f m -> m (NValue t f m))
-> Maybe (NValue t f m)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"__nixPath must be a list of attr sets with 'path' elements, but received: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> HashMap k (NValue t f m) -> FilePath
forall b a. (Show a, IsString b) => a -> b
show HashMap k (NValue t f m)
s)
(m (NValue t f m) -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => m v -> m v
defer (m (NValue t f m) -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue t f m -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m (NValue t f m)
fetchTarball)
(k -> HashMap k (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup k
"uri" HashMap k (NValue t f m)
s)
)
NValue t f m -> m (NValue t f m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(k -> HashMap k (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup k
"path" HashMap k (NValue t f m)
s)
fetchTarball
:: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
fetchTarball :: NValue t f m -> m (NValue t f m)
fetchTarball =
\case
NVSet AttrSet (NValue t f m)
s AttrSet SourcePos
_ ->
m (NValue t f m)
-> (NValue t f m -> m (NValue t f m))
-> Maybe (NValue t f m)
-> m (NValue t f m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall FilePath
"builtins.fetchTarball: Missing url attribute")
(Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go (Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"sha256" AttrSet (NValue t f m)
s) (NValue t f m -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
(Text -> AttrSet (NValue t f m) -> Maybe (NValue t f m)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Text
"url" AttrSet (NValue t f m)
s)
v :: NValue t f m
v@NVStr{} -> Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go Maybe (NValue t f m)
forall a. Maybe a
Nothing NValue t f m
v
NValue t f m
v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.fetchTarball: Expected URI or set, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v
(NValue t f m -> m (NValue t f m))
-> (NValue t f m -> m (NValue t f m))
-> NValue t f m
-> m (NValue t f m)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand
where
go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
go Maybe (NValue t f m)
msha = \case
NVStr NixString
ns -> Text -> Maybe (NValue t f m) -> m (NValue t f m)
fetch (NixString -> Text
stringIgnoreContext NixString
ns) Maybe (NValue t f m)
msha
NValue t f m
v -> ErrorCall -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m (NValue t f m)) -> ErrorCall -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"builtins.fetchTarball: Expected URI or string, got " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> NValue t f m -> FilePath
forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v
fetch :: Text -> Maybe (NValue t f m) -> m (NValue t f m)
fetch :: Text -> Maybe (NValue t f m) -> m (NValue t f m)
fetch Text
uri Maybe (NValue t f m)
Nothing =
Text -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, MonadInstantiate m) =>
Text -> m (NValue t f m)
nixInstantiateExpr (Text -> m (NValue t f m)) -> Text -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text
"builtins.fetchTarball \"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
uri Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
fetch Text
url (Just NValue t f m
t) =
(\NValue t f m
nv -> do
NixString
nsSha <- NValue t f m -> m NixString
forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue NValue t f m
nv
let sha :: Text
sha = NixString -> Text
stringIgnoreContext NixString
nsSha
Text -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, MonadInstantiate m) =>
Text -> m (NValue t f m)
nixInstantiateExpr
(Text -> m (NValue t f m)) -> Text -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ Text
"builtins.fetchTarball { " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"url = \"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
url Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\"; " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"sha256 = \"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sha Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\"; }"
) (NValue t f m -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NValue t f m -> m (NValue t f m)
forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
t
defaultFindPath :: MonadNix e t f m => [NValue t f m] -> FilePath -> m FilePath
defaultFindPath :: [NValue t f m] -> FilePath -> m FilePath
defaultFindPath = [NValue t f m] -> FilePath -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
[NValue t f m] -> FilePath -> m FilePath
findPathM
findPathM
:: forall e t f m
. MonadNix e t f m
=> [NValue t f m]
-> FilePath
-> m FilePath
findPathM :: [NValue t f m] -> FilePath -> m FilePath
findPathM = (FilePath -> m (Maybe FilePath))
-> [NValue t f m] -> FilePath -> m FilePath
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
(FilePath -> m (Maybe FilePath))
-> [NValue t f m] -> FilePath -> m FilePath
findPathBy FilePath -> m (Maybe FilePath)
MonadEffects t f m => FilePath -> m (Maybe FilePath)
existingPath
where
existingPath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
existingPath :: FilePath -> m (Maybe FilePath)
existingPath FilePath
path =
do
FilePath
apath <- FilePath -> m FilePath
forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
FilePath -> m FilePath
makeAbsolutePath @t @f FilePath
path
Bool
doesExist <- FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
doesPathExist FilePath
apath
pure $ FilePath -> Maybe FilePath
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
apath Maybe FilePath -> Bool -> Maybe FilePath
forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
doesExist
defaultImportPath
:: (MonadNix e t f m, MonadState (HashMap FilePath NExprLoc, b) m)
=> FilePath
-> m (NValue t f m)
defaultImportPath :: FilePath -> m (NValue t f m)
defaultImportPath FilePath
path = do
FilePath -> m ()
forall (m :: * -> *). Monad m => FilePath -> m ()
traceM (FilePath -> m ()) -> FilePath -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Importing file " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
path
NixLevel -> ErrorCall -> m (NValue t f m) -> m (NValue t f m)
forall s e (m :: * -> *) a.
(Framed e m, Exception s) =>
NixLevel -> s -> m a -> m a
withFrame NixLevel
Info (FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall) -> FilePath -> ErrorCall
forall a b. (a -> b) -> a -> b
$ FilePath
"While importing file " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> FilePath
forall b a. (Show a, IsString b) => a -> b
show FilePath
path) (m (NValue t f m) -> m (NValue t f m))
-> m (NValue t f m) -> m (NValue t f m)
forall a b. (a -> b) -> a -> b
$ do
HashMap FilePath NExprLoc
imports <- ((HashMap FilePath NExprLoc, b) -> HashMap FilePath NExprLoc)
-> m (HashMap FilePath NExprLoc)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (HashMap FilePath NExprLoc, b) -> HashMap FilePath NExprLoc
forall a b. (a, b) -> a
fst
NExprLoc -> m (NValue t f m)
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NExprLoc -> m (NValue t f m)
evalExprLoc (NExprLoc -> m (NValue t f m)) -> m NExprLoc -> m (NValue t f m)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
m NExprLoc
-> (NExprLoc -> m NExprLoc) -> Maybe NExprLoc -> m NExprLoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(do
Result NExprLoc
eres <- FilePath -> m (Result NExprLoc)
forall (m :: * -> *).
MonadFile m =>
FilePath -> m (Result NExprLoc)
parseNixFileLoc FilePath
path
(Doc Void -> m NExprLoc)
-> (NExprLoc -> m NExprLoc) -> Result NExprLoc -> m NExprLoc
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(\ Doc Void
err -> ErrorCall -> m NExprLoc
forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError (ErrorCall -> m NExprLoc) -> ErrorCall -> m NExprLoc
forall a b. (a -> b) -> a -> b
$ FilePath -> ErrorCall
ErrorCall (FilePath -> ErrorCall)
-> (Doc Void -> FilePath) -> Doc Void -> ErrorCall
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Void -> FilePath
forall b a. (Show a, IsString b) => a -> b
show (Doc Void -> ErrorCall) -> Doc Void -> ErrorCall
forall a b. (a -> b) -> a -> b
$ [Doc Void] -> Doc Void
forall ann. [Doc ann] -> Doc ann
fillSep [Doc Void
"Parse during import failed:", Doc Void
err])
(\ NExprLoc
expr ->
do
((HashMap FilePath NExprLoc, b) -> (HashMap FilePath NExprLoc, b))
-> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HashMap FilePath NExprLoc -> HashMap FilePath NExprLoc)
-> (HashMap FilePath NExprLoc, b) -> (HashMap FilePath NExprLoc, b)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (FilePath
-> NExprLoc
-> HashMap FilePath NExprLoc
-> HashMap FilePath NExprLoc
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert FilePath
path NExprLoc
expr))
pure NExprLoc
expr
)
Result NExprLoc
eres
)
NExprLoc -> m NExprLoc
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(FilePath -> HashMap FilePath NExprLoc -> Maybe NExprLoc
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup FilePath
path HashMap FilePath NExprLoc
imports)
defaultPathToDefaultNix :: MonadNix e t f m => FilePath -> m FilePath
defaultPathToDefaultNix :: FilePath -> m FilePath
defaultPathToDefaultNix = FilePath -> m FilePath
forall (m :: * -> *). MonadFile m => FilePath -> m FilePath
pathToDefaultNixFile
pathToDefaultNixFile :: MonadFile m => FilePath -> m FilePath
pathToDefaultNixFile :: FilePath -> m FilePath
pathToDefaultNixFile FilePath
p = do
Bool
isDir <- FilePath -> m Bool
forall (m :: * -> *). MonadFile m => FilePath -> m Bool
doesDirectoryExist FilePath
p
pure $ FilePath
p FilePath -> FilePath -> FilePath
</> FilePath
"default.nix" FilePath -> Bool -> FilePath
forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
isDir
defaultTraceEffect :: MonadPutStr m => String -> m ()
defaultTraceEffect :: FilePath -> m ()
defaultTraceEffect = FilePath -> m ()
forall (m :: * -> *). MonadPutStr m => FilePath -> m ()
Nix.Effects.putStrLn