about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-12T15·04+0300
committertazjin <tazjin@tvl.su>2022-08-28T11·02+0000
commite68b6d33b074efa8c745b4ee7c92518cf6dcc1ca (patch)
tree4ac76e1612c0a3c286d5b9e7ad716fc4e35e2edc
parentbf10c352012b3a12d5560890c12c2376ad00a92a (diff)
feat(tvix/eval): support absolute and home-anchored paths r/4517
These two paths are the easiest to handle, as they are simply built up
from the components supplied in the text node and then normalised.

Note that the normalisation of fs::canonicalize includes symlink
resolution, which Nix does not actually do. We will need to fix that
at some point.

Change-Id: I54158f0684f197dd2a2583f7d0982d54c7619993
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6183
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
-rw-r--r--tvix/eval/src/compiler.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 3ec7f673eb..c56951e464 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -13,6 +13,8 @@
 //! the code in this module, `debug_assert!` has been used to catch
 //! mistakes early during development.
 
+use std::path::Path;
+
 use crate::chunk::Chunk;
 use crate::errors::EvalResult;
 use crate::opcode::{CodeIdx, OpCode};
@@ -154,10 +156,39 @@ impl Compiler {
                 Ok(())
             }
 
-            rnix::NixValue::Path(_, _) => todo!(),
+            rnix::NixValue::Path(anchor, path) => self.compile_path(anchor, path),
         }
     }
 
+    fn compile_path(&mut self, anchor: rnix::value::Anchor, path: String) -> EvalResult<()> {
+        // TODO(tazjin): C++ Nix does not resolve symlinks, but `fs::canonicalize` does.
+
+        let path = match anchor {
+            rnix::value::Anchor::Absolute => Path::new(&path)
+                .canonicalize()
+                .expect("TODO: error variant"),
+
+            rnix::value::Anchor::Home => {
+                let mut buf = dirs::home_dir().expect("TODO: error variant");
+                buf.push(&path);
+                buf.canonicalize().expect("TODO: error variant")
+            }
+
+            rnix::value::Anchor::Relative => todo!("resolve relative to file location"),
+
+            // This confusingly named variant is actually
+            // angle-bracket lookups, which in C++ Nix desugar
+            // to calls to `__findFile` (implicitly in the
+            // current scope).
+            rnix::value::Anchor::Store => todo!("resolve <...> lookups at runtime"),
+        };
+
+        let idx = self.chunk.push_constant(Value::Path(path));
+        self.chunk.push_op(OpCode::OpConstant(idx));
+
+        Ok(())
+    }
+
     fn compile_string(&mut self, string: rnix::types::Str) -> EvalResult<()> {
         let mut count = 0;