Preserve more information in __cur_file rather than __cwd

This commit is contained in:
John Wiegley 2018-04-02 19:57:05 -07:00
parent 56440490f6
commit c50bf1a9f6
4 changed files with 33 additions and 40 deletions

39
Nix.hs
View File

@ -28,35 +28,30 @@ import Nix.Utils
-- | Evaluate a nix expression in the default context -- | Evaluate a nix expression in the default context
evalTopLevelExpr :: MonadBuiltins e m evalTopLevelExpr :: MonadBuiltins e m
=> Maybe FilePath -> NExprLoc -> m (NValueNF m) => Maybe FilePath -> NExprLoc -> m (NValueNF m)
evalTopLevelExpr mdir expr = do evalTopLevelExpr mpath expr = do
base <- baseEnv base <- baseEnv
(normalForm =<<) $ pushScopes base $ case mdir of (normalForm =<<) $ pushScopes base $ case mpath of
Nothing -> framedEvalExpr eval expr Nothing -> framedEvalExpr eval expr
Just dir -> do Just path -> do
traceM $ "Setting __cwd = " ++ show dir traceM $ "Setting __cur_file = " ++ show path
ref <- valueThunk $ NVLiteralPath dir ref <- valueThunk $ NVLiteralPath path
pushScope (M.singleton "__cwd" ref) pushScope (M.singleton "__cur_file" ref)
(framedEvalExpr eval expr) (framedEvalExpr eval expr)
evalTopLevelExprIO :: Maybe FilePath -> NExprLoc -> IO (NValueNF (Lazy IO)) evalTopLevelExprIO :: Maybe FilePath -> NExprLoc -> IO (NValueNF (Lazy IO))
evalTopLevelExprIO mdir = runLazyIO . evalTopLevelExpr mdir evalTopLevelExprIO mpath = runLazyIO . evalTopLevelExpr mpath
-- informativeEvalTopLevelExprIO :: Maybe FilePath -> NExpr
-- -> IO (NValueNF (Lazy IO))
-- informativeEvalTopLevelExprIO mdir expr =
-- runReaderT (runLazy (evalTopLevelExpr mdir expr)) []
tracingEvalTopLevelExprIO :: Maybe FilePath -> NExprLoc tracingEvalTopLevelExprIO :: Maybe FilePath -> NExprLoc
-> IO (NValueNF (Lazy IO)) -> IO (NValueNF (Lazy IO))
tracingEvalTopLevelExprIO mdir expr = do tracingEvalTopLevelExprIO mpath expr = do
traced <- tracingEvalExpr eval expr traced <- tracingEvalExpr eval expr
case mdir of case mpath of
Nothing -> Nothing ->
runLazyIO (normalForm =<< (`pushScopes` traced) =<< baseEnv) runLazyIO (normalForm =<< (`pushScopes` traced) =<< baseEnv)
Just dir -> do Just path -> do
traceM $ "Setting __cwd = " ++ show dir traceM $ "Setting __cur_file = " ++ show path
ref <- runLazyIO (valueThunk $ NVLiteralPath dir) ref <- runLazyIO (valueThunk $ NVLiteralPath path)
let m = M.singleton "__cwd" ref let m = M.singleton "__cur_file" ref
runLazyIO (baseEnv >>= (`pushScopes` pushScope m traced) runLazyIO (baseEnv >>= (`pushScopes` pushScope m traced)
>>= normalForm) >>= normalForm)
@ -91,12 +86,12 @@ symbolicBaseEnv = return [Scope M.empty False]
lintExprIO :: NExprLoc -> IO (Symbolic (Lint IO)) lintExprIO :: NExprLoc -> IO (Symbolic (Lint IO))
lintExprIO expr = lintExprIO expr =
runLintIO (symbolicBaseEnv runLintIO $ symbolicBaseEnv
>>= (`pushScopes` lintExpr (stripAnnotation expr))) >>= (`pushScopes` lintExpr (stripAnnotation expr))
tracingLintExprIO :: NExprLoc -> IO (Symbolic (Lint IO)) tracingLintExprIO :: NExprLoc -> IO (Symbolic (Lint IO))
tracingLintExprIO expr = do tracingLintExprIO expr = do
traced <- tracingEvalExpr lint expr traced <- tracingEvalExpr lint expr
ref <- runLintIO $ sthunk $ mkSymbolic [TPath] ref <- runLintIO $ sthunk $ mkSymbolic [TPath]
let m = M.singleton "__cwd" ref let m = M.singleton "__cur_file" ref
runLintIO (symbolicBaseEnv >>= (`pushScopes` pushScope m traced)) runLintIO $ symbolicBaseEnv >>= (`pushScopes` pushScope m traced)

View File

@ -82,13 +82,13 @@ instance MonadNix (Lazy IO) where
makeAbsolutePath origPath = do makeAbsolutePath origPath = do
absPath <- if isAbsolute origPath then pure origPath else do absPath <- if isAbsolute origPath then pure origPath else do
cwd <- do cwd <- do
mres <- lookupVar @_ @(NThunk (Lazy IO)) "__cwd" mres <- lookupVar @_ @(NThunk (Lazy IO)) "__cur_file"
case mres of case mres of
Nothing -> liftIO getCurrentDirectory Nothing -> liftIO getCurrentDirectory
Just (NThunk v) -> forceThunk v >>= \case Just (NThunk v) -> forceThunk v >>= \case
NVLiteralPath s -> return s NVLiteralPath s -> return $ takeDirectory s
v -> throwError $ "when resolving relative path," v -> throwError $ "when resolving relative path,"
++ " __cwd is in scope," ++ " __cur_file is in scope,"
++ " but is not a path; it is: " ++ " but is not a path; it is: "
++ show (void v) ++ show (void v)
pure $ cwd </> origPath pure $ cwd </> origPath
@ -114,16 +114,16 @@ instance MonadNixEnv (Lazy IO) where
-- jww (2018-03-29): Cache which files have been read in. -- jww (2018-03-29): Cache which files have been read in.
importFile = forceThunk . getNThunk >=> \case importFile = forceThunk . getNThunk >=> \case
NVLiteralPath path -> do NVLiteralPath path -> do
mres <- lookupVar @(Context (NThunk (Lazy IO))) "__cwd" mres <- lookupVar @(Context (NThunk (Lazy IO))) "__cur_file"
path' <- case mres of path' <- case mres of
Nothing -> do Nothing -> do
traceM "No known current directory" traceM "No known current directory"
return path return path
Just (NThunk dir) -> forceThunk dir >>= normalForm >>= \case Just (NThunk p) -> forceThunk p >>= normalForm >>= \case
Fix (NVLiteralPath dir') -> do Fix (NVLiteralPath p') -> do
traceM $ "Current directory for import is: " traceM $ "Current file being evaluated is: "
++ show dir' ++ show p'
return $ dir' </> path return $ takeDirectory p' </> path
x -> error $ "How can the current directory be: " ++ show x x -> error $ "How can the current directory be: " ++ show x
traceM $ "Importing file " ++ path' traceM $ "Importing file " ++ path'
withStringContext ("While importing file " ++ show path') $ do withStringContext ("While importing file " ++ show path') $ do
@ -131,12 +131,11 @@ instance MonadNixEnv (Lazy IO) where
case eres of case eres of
Failure err -> error $ "Parse failed: " ++ show err Failure err -> error $ "Parse failed: " ++ show err
Success expr -> do Success expr -> do
ref <- fmap NThunk $ buildThunk $ return $ ref <- NThunk <$> valueRef (NVLiteralPath path')
NVLiteralPath $ takeDirectory path'
-- Use this cookie so that when we evaluate the next -- Use this cookie so that when we evaluate the next
-- import, we'll remember which directory its containing -- import, we'll remember which directory its containing
-- file was in. -- file was in.
pushScope (M.singleton "__cwd" ref) pushScope (M.singleton "__cur_file" ref)
(framedEvalExpr eval expr) (framedEvalExpr eval expr)
p -> error $ "Unexpected argument to import: " ++ show (void p) p -> error $ "Unexpected argument to import: " ++ show (void p)

View File

@ -10,7 +10,6 @@ import Nix.Lint
import Nix.Parser import Nix.Parser
import Nix.Pretty import Nix.Pretty
import Options.Applicative hiding (ParserResult(..)) import Options.Applicative hiding (ParserResult(..))
import System.FilePath
import System.IO import System.IO
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>)) import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
@ -51,12 +50,12 @@ mainOptions = Options
main :: IO () main :: IO ()
main = do main = do
opts <- execParser optsDef opts <- execParser optsDef
(eres, mdir) <- case expression opts of (eres, mpath) <- case expression opts of
Just s -> return (parseNixStringLoc s, Nothing) Just s -> return (parseNixStringLoc s, Nothing)
Nothing -> case filePath opts of Nothing -> case filePath opts of
Nothing -> (, Nothing) . parseNixStringLoc <$> getContents Nothing -> (, Nothing) . parseNixStringLoc <$> getContents
Just "-" -> (, Nothing) . parseNixStringLoc <$> getContents Just "-" -> (, Nothing) . parseNixStringLoc <$> getContents
Just path -> (, Just (takeDirectory path)) <$> parseNixFileLoc path Just path -> (, Just path) <$> parseNixFileLoc path
case eres of case eres of
Failure err -> hPutStrLn stderr $ "Parse failed: " ++ show err Failure err -> hPutStrLn stderr $ "Parse failed: " ++ show err
@ -65,9 +64,9 @@ main = do
sym <- lintExprIO expr sym <- lintExprIO expr
putStrLn =<< runLintIO (renderSymbolic sym) putStrLn =<< runLintIO (renderSymbolic sym)
if | evaluate opts, debug opts -> if | evaluate opts, debug opts ->
print =<< tracingEvalTopLevelExprIO mdir expr print =<< tracingEvalTopLevelExprIO mpath expr
| evaluate opts -> | evaluate opts ->
putStrLn . printNix =<< evalTopLevelExprIO mdir expr putStrLn . printNix =<< evalTopLevelExprIO mpath expr
| debug opts -> | debug opts ->
print expr print expr
| otherwise -> | otherwise ->

View File

@ -123,4 +123,4 @@ nixEvalFile file = do
error $ "Parsing failed for file `" ++ file ++ "`.\n" ++ show err error $ "Parsing failed for file `" ++ file ++ "`.\n" ++ show err
Success expression -> do Success expression -> do
setEnv "TEST_VAR" "foo" setEnv "TEST_VAR" "foo"
evalTopLevelExprIO (Just (takeDirectory file)) expression evalTopLevelExprIO (Just file) expression