{-# language CPP #-}
module Nix.Effects.Basic where
import Nix.Prelude hiding ( head
)
import Relude.Unsafe ( head )
import GHC.Exception ( ErrorCall(ErrorCall) )
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 Nix.Convert
import Nix.Effects
import Nix.Exec ( MonadNix
, evalExprLoc
, nixInstantiateExpr
)
import Nix.Expr.Types
import Nix.Expr.Types.Annotated
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
defaultToAbsolutePath :: forall e t f m . MonadNix e t f m => Path -> m Path
defaultToAbsolutePath :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Path -> m Path
defaultToAbsolutePath Path
origPath =
do
Path
origPathExpanded <- forall (m :: * -> *). MonadFile m => Path -> m Path
expandHomePath Path
origPath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
Path -> Path
removeDotDotIndirections
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadFile m => Path -> m Path
canonicalizePath
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. a -> a -> Bool -> a
bool
(forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(Path -> Path -> Path
<///> Path
origPathExpanded)
forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe
forall (m :: * -> *). MonadFile m => m Path
getCurrentDirectory
( (\case
NVPath Path
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path -> Path
takeDirectory Path
s
Free (NValue' t f m) t
val -> forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"when resolving relative path, __cur_file is in scope, but is not a path; it is: " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show Free (NValue' t f m) t
val
) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall v (m :: * -> *). MonadValue v m => v -> m v
demand
)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a (m :: * -> *). Scoped a m => VarName -> m (Maybe a)
lookupVar VarName
"__cur_file"
)
(forall (f :: * -> *) a. Applicative f => a -> f a
pure Path
origPathExpanded)
(Path -> Bool
isAbsolute Path
origPathExpanded)
expandHomePath :: MonadFile m => Path -> m Path
expandHomePath :: forall (m :: * -> *). MonadFile m => Path -> m Path
expandHomePath (coerce :: forall a b. Coercible a b => a -> b
coerce -> (Char
'~' : [Char]
xs)) = (forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce [Char]
xs) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadFile m => m Path
getHomeDirectory
expandHomePath Path
p = forall (f :: * -> *) a. Applicative f => a -> f a
pure Path
p
removeDotDotIndirections :: Path -> Path
removeDotDotIndirections :: Path -> Path
removeDotDotIndirections = coerce :: forall a b. Coercible a b => a -> b
coerce forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"/" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. (Eq a, IsString a) => [a] -> [a] -> [a]
go forall a. Monoid a => a
mempty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a] -> [[a]]
splitOn [Char]
"/" forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce
where
go :: [a] -> [a] -> [a]
go [a]
s [] = 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 forall a. a -> [a] -> [a]
: [a]
s) [a]
rest
infixr 9 <///>
(<///>) :: Path -> Path -> Path
Path
x <///> :: Path -> Path -> Path
<///> Path
y
| Path -> Bool
isAbsolute Path
y Bool -> Bool -> Bool
|| [Char]
"." forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` coerce :: forall a b. Coercible a b => a -> b
coerce Path
y = Path
x Path -> Path -> Path
</> Path
y
| Bool
otherwise = Path -> Path -> Path
joinByLargestOverlap Path
x Path
y
where
joinByLargestOverlap :: Path -> Path -> Path
joinByLargestOverlap :: Path -> Path -> Path
joinByLargestOverlap (Path -> [Path]
splitDirectories -> [Path]
xs) (Path -> [Path]
splitDirectories -> [Path]
ys) =
[Path] -> Path
joinPath forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head
[ [Path]
xs forall a. Semigroup a => a -> a -> a
<> forall a. Int -> [a] -> [a]
drop (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Path]
tx) [Path]
ys | [Path]
tx <- forall a. [a] -> [[a]]
tails [Path]
xs, [Path]
tx forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` forall a. [a] -> [[a]]
inits [Path]
ys ]
defaultFindEnvPath :: MonadNix e t f m => String -> m Path
defaultFindEnvPath :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
[Char] -> m Path
defaultFindEnvPath = forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Path -> m Path
findEnvPathM forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce
findEnvPathM :: forall e t f m . MonadNix e t f m => Path -> m Path
findEnvPathM :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Path -> m Path
findEnvPathM Path
name =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"impossible")
(\ NValue t f m
v ->
do
[NValue t f m]
l <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @[NValue t f m] forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
v
forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
(Path -> m (Maybe Path)) -> [NValue t f m] -> Path -> m Path
findPathBy MonadEffects t f m => Path -> m (Maybe Path)
nixFilePath [NValue t f m]
l Path
name
)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a (m :: * -> *). Scoped a m => VarName -> m (Maybe a)
lookupVar VarName
"__nixPath"
where
nixFilePath :: MonadEffects t f m => Path -> m (Maybe Path)
nixFilePath :: MonadEffects t f m => Path -> m (Maybe Path)
nixFilePath Path
path =
do
Path
absPath <- forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
Path -> m Path
toAbsolutePath @t @f Path
path
Bool
isDir <- forall (m :: * -> *). MonadFile m => Path -> m Bool
doesDirectoryExist Path
absPath
Path
absFile <-
forall a. a -> a -> Bool -> a
bool
(forall (f :: * -> *) a. Applicative f => a -> f a
pure Path
absPath)
(forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
Path -> m Path
toAbsolutePath @t @f forall a b. (a -> b) -> a -> b
$ Path
absPath Path -> Path -> Path
</> Path
"default.nix")
Bool
isDir
(forall (f :: * -> *) a. Applicative f => a -> f a
pure Path
absFile forall a. Monoid a => a -> Bool -> a
`whenTrue`) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadFile m => Path -> m Bool
doesFileExist Path
absFile
findPathBy
:: forall e t f m
. MonadNix e t f m
=> (Path -> m (Maybe Path))
-> [NValue t f m]
-> Path
-> m Path
findPathBy :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
(Path -> m (Maybe Path)) -> [NValue t f m] -> Path -> m Path
findPathBy Path -> m (Maybe Path)
finder [NValue t f m]
ls Path
name =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"file ''" forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce Path
name forall a. Semigroup a => a -> a -> a
<> [Char]
"'' was not found in the Nix search path (add it's using $NIX_PATH or -I)")
forall (f :: * -> *) a. Applicative f => a -> f a
pure
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM MonadNix e t f m => Maybe Path -> NValue t f m -> m (Maybe Path)
fun forall a. Monoid a => a
mempty [NValue t f m]
ls
where
fun
:: MonadNix e t f m
=> Maybe Path
-> NValue t f m
-> m (Maybe Path)
fun :: MonadNix e t f m => Maybe Path -> NValue t f m -> m (Maybe Path)
fun =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(\ NValue t f m
nv ->
do
(HashMap VarName (NValue t f m)
s :: HashMap VarName (NValue t f m)) <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv
NValue t f m
p <- HashMap VarName (NValue t f m) -> m (NValue t f m)
resolvePath HashMap VarName (NValue t f m)
s
Path
path <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
p
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(Path -> Maybe Path -> m (Maybe Path)
tryPath Path
path forall a. Monoid a => a
mempty)
(\ NValue t f m
nv' ->
do
Maybe NixString
mns <- forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay @NixString forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
nv'
Path -> Maybe Path -> m (Maybe Path)
tryPath Path
path forall a b. (a -> b) -> a -> b
$
forall b a. Monoid b => (a -> b) -> Maybe a -> b
whenJust
(\ NixString
nsPfx ->
let pfx :: Text
pfx = NixString -> Text
ignoreContext NixString
nsPfx in
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ forall a. ToString a => a -> [Char]
toString Text
pfx forall a. Monoid a => a -> Bool -> a
`whenFalse` Text -> Bool
Text.null Text
pfx
)
Maybe NixString
mns
)
(forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
"prefix" HashMap VarName (NValue t f m)
s)
)
(forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure)
tryPath :: Path -> Maybe Path -> m (Maybe Path)
tryPath :: Path -> Maybe Path -> m (Maybe Path)
tryPath Path
p (Just Path
n) | Path
n' : [Path]
ns <- Path -> [Path]
splitDirectories Path
name, Path
n forall a. Eq a => a -> a -> Bool
== Path
n' =
Path -> m (Maybe Path)
finder forall a b. (a -> b) -> a -> b
$ Path
p Path -> Path -> Path
<///> [Path] -> Path
joinPath [Path]
ns
tryPath Path
p Maybe Path
_ = Path -> m (Maybe Path)
finder forall a b. (a -> b) -> a -> b
$ Path
p Path -> Path -> Path
<///> Path
name
resolvePath :: HashMap VarName (NValue t f m) -> m (NValue t f m)
resolvePath :: HashMap VarName (NValue t f m) -> m (NValue t f m)
resolvePath HashMap VarName (NValue t f m)
s =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"__nixPath must be a list of attr sets with 'path' elements, but received: " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show HashMap VarName (NValue t f m)
s)
(forall v (m :: * -> *). MonadValue v m => m v -> m v
defer forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m (NValue t f m)
fetchTarball)
(forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
"uri" HashMap VarName (NValue t f m)
s)
)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
"path" HashMap VarName (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 :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NValue t f m -> m (NValue t f m)
fetchTarball =
\case
NVSet PositionSet
_ AttrSet (NValue t f m)
s ->
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall [Char]
"builtins.fetchTarball: Missing url attribute")
(Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
fetchFromString (forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
"sha256" AttrSet (NValue t f m)
s) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
(forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
"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)
fetchFromString forall a. Maybe a
Nothing NValue t f m
v
NValue t f m
v -> forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"builtins.fetchTarball: Expected URI or set, got " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show NValue t f m
v
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall v (m :: * -> *). MonadValue v m => v -> m v
demand
where
fetchFromString
:: Maybe (NValue t f m)
-> NValue t f m
-> m (NValue t f m)
fetchFromString :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
fetchFromString Maybe (NValue t f m)
msha =
\case
NVStr NixString
ns -> Text -> Maybe (NValue t f m) -> m (NValue t f m)
fetch (NixString -> Text
ignoreContext NixString
ns) Maybe (NValue t f m)
msha
NValue t f m
v -> forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"builtins.fetchTarball: Expected URI or string, got " forall a. Semigroup a => a -> a -> a
<> 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 =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, MonadInstantiate m) =>
Text -> m (NValue t f m)
nixInstantiateExpr forall a b. (a -> b) -> a -> b
$
Text
"builtins.fetchTarball \"" forall a. Semigroup a => a -> a -> a
<> Text
uri forall a. Semigroup a => a -> a -> a
<> Text
"\""
)
(\ NValue t f m
v ->
do
NixString
nsSha <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand NValue t f m
v
let sha :: Text
sha = NixString -> Text
ignoreContext NixString
nsSha
forall e t (f :: * -> *) (m :: * -> *).
(MonadNix e t f m, MonadInstantiate m) =>
Text -> m (NValue t f m)
nixInstantiateExpr forall a b. (a -> b) -> a -> b
$
Text
"builtins.fetchTarball { " forall a. Semigroup a => a -> a -> a
<> Text
"url = \"" forall a. Semigroup a => a -> a -> a
<> Text
uri forall a. Semigroup a => a -> a -> a
<> Text
"\"; " forall a. Semigroup a => a -> a -> a
<> Text
"sha256 = \"" forall a. Semigroup a => a -> a -> a
<> Text
sha forall a. Semigroup a => a -> a -> a
<> Text
"\"; }"
)
defaultFindPath :: MonadNix e t f m => [NValue t f m] -> Path -> m Path
defaultFindPath :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
[NValue t f m] -> Path -> m Path
defaultFindPath = forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
[NValue t f m] -> Path -> m Path
findPathM
findPathM
:: forall e t f m
. MonadNix e t f m
=> [NValue t f m]
-> Path
-> m Path
findPathM :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
[NValue t f m] -> Path -> m Path
findPathM = forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
(Path -> m (Maybe Path)) -> [NValue t f m] -> Path -> m Path
findPathBy MonadEffects t f m => Path -> m (Maybe Path)
existingPath
where
existingPath :: MonadEffects t f m => Path -> m (Maybe Path)
existingPath :: MonadEffects t f m => Path -> m (Maybe Path)
existingPath Path
path =
do
Path
apath <- forall t (f :: * -> *) (m :: * -> *).
MonadEffects t f m =>
Path -> m Path
toAbsolutePath @t @f Path
path
Bool
doesExist <- forall (m :: * -> *). MonadFile m => Path -> m Bool
doesPathExist Path
apath
pure $ forall (f :: * -> *) a. Applicative f => a -> f a
pure Path
apath forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
doesExist
defaultImportPath
:: (MonadNix e t f m, MonadState (HashMap Path NExprLoc, b) m)
=> Path
-> m (NValue t f m)
defaultImportPath :: forall e t (f :: * -> *) (m :: * -> *) b.
(MonadNix e t f m, MonadState (HashMap Path NExprLoc, b) m) =>
Path -> m (NValue t f m)
defaultImportPath Path
path =
do
forall (m :: * -> *). Monad m => [Char] -> m ()
traceM forall a b. (a -> b) -> a -> b
$ [Char]
"Importing file " forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce Path
path
forall s e (m :: * -> *) a.
(Framed e m, Exception s) =>
NixLevel -> s -> m a -> m a
withFrame
NixLevel
Info
([Char] -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ [Char]
"While importing file " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show Path
path)
forall a b. (a -> b) -> a -> b
$ forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
NExprLoc -> m (NValue t f m)
evalExprLoc forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
(forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(\ Doc Void
err -> forall s e (m :: * -> *) a.
(Framed e m, Exception s, MonadThrow m) =>
s -> m a
throwError forall a b. (a -> b) -> a -> b
$ [Char] -> ErrorCall
ErrorCall forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (Show a, IsString b) => a -> b
show forall a b. (a -> b) -> a -> b
$ forall ann. [Doc ann] -> Doc ann
fillSep [Doc Void
"Parse during import failed:", Doc Void
err])
(\ NExprLoc
expr ->
do
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall a b. (a -> b) -> a -> b
$ forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert Path
path NExprLoc
expr
pure NExprLoc
expr
)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadFile m => Path -> m (Result NExprLoc)
parseNixFileLoc Path
path
)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Path
path
) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall a b. (a, b) -> a
fst
defaultPathToDefaultNix :: MonadNix e t f m => Path -> m Path
defaultPathToDefaultNix :: forall e t (f :: * -> *) (m :: * -> *).
MonadNix e t f m =>
Path -> m Path
defaultPathToDefaultNix = forall (m :: * -> *). MonadFile m => Path -> m Path
pathToDefaultNixFile
pathToDefaultNixFile :: MonadFile m => Path -> m Path
pathToDefaultNixFile :: forall (m :: * -> *). MonadFile m => Path -> m Path
pathToDefaultNixFile Path
p =
do
Bool
isDir <- forall (m :: * -> *). MonadFile m => Path -> m Bool
doesDirectoryExist Path
p
pure $ Path
p Path -> Path -> Path
</> Path
"default.nix" forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
isDir
defaultTraceEffect :: MonadPutStr m => String -> m ()
defaultTraceEffect :: forall (m :: * -> *). MonadPutStr m => [Char] -> m ()
defaultTraceEffect = forall (m :: * -> *). MonadPutStr m => [Char] -> m ()
Nix.Effects.putStrLn