diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-12T15·28+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-28T11·02+0000 |
commit | 6fe5e2d75257504f0321e2e98b6fb675b716fe25 (patch) | |
tree | bf0549b862e8bdf25dda9e9b3aa05c16889b0ba5 /tvix/eval/src/compiler.rs | |
parent | 1f8aad0ab41eec3db2e892bf80b6b76d54d36bbc (diff) |
feat(tvix/eval): resolve relative path literals r/4519
Resolves relative paths (e.g. `./foo`) either relative to the location of the Nix file, or relative to the working directory if none is supplied. Change-Id: I70ec574657b221b458015117a004b6e4a9c25a30 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6185 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index c5ec664dc2cf..63a02f68c013 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -13,7 +13,7 @@ //! the code in this module, `debug_assert!` has been used to catch //! mistakes early during development. -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::chunk::Chunk; use crate::errors::{Error, EvalResult}; @@ -35,6 +35,7 @@ pub struct CompilationResult { struct Compiler { chunk: Chunk, warnings: Vec<EvalWarning>, + root_dir: PathBuf, } impl Compiler { @@ -175,7 +176,11 @@ impl Compiler { buf } - rnix::value::Anchor::Relative => todo!("resolve relative to file location"), + rnix::value::Anchor::Relative => { + let mut buf = self.root_dir.clone(); + buf.push(path); + buf + } // This confusingly named variant is actually // angle-bracket lookups, which in C++ Nix desugar @@ -624,8 +629,23 @@ impl Compiler { } } -pub fn compile(ast: rnix::AST) -> EvalResult<CompilationResult> { +pub fn compile(ast: rnix::AST, location: Option<PathBuf>) -> EvalResult<CompilationResult> { + let mut root_dir = match location { + Some(dir) => Ok(dir), + None => std::env::current_dir().map_err(|e| { + Error::PathResolution(format!("could not determine current directory: {}", e)) + }), + }?; + + // If the path passed from the caller points to a file, the + // filename itself needs to be truncated as this must point to a + // directory. + if root_dir.is_file() { + root_dir.pop(); + } + let mut c = Compiler { + root_dir, chunk: Chunk::default(), warnings: vec![], }; |