feat: always resolve path at runtime
This commit is contained in:
@@ -43,7 +43,7 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
|
||||
Ir::Null(_) => "null".to_string(),
|
||||
Ir::Str(s) => s.val.escape_quote(),
|
||||
Ir::Path(p) => {
|
||||
// Path needs runtime resolution for interpolated paths
|
||||
// Path needs runtime resolution
|
||||
let path_expr = ctx.get_ir(p.expr).compile(ctx);
|
||||
format!("Nix.resolvePath({})", path_expr)
|
||||
}
|
||||
|
||||
@@ -231,10 +231,6 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
||||
f(guard.as_ctx())
|
||||
}
|
||||
|
||||
fn get_current_dir(&self) -> std::path::PathBuf {
|
||||
self.ctx.get_current_dir()
|
||||
}
|
||||
|
||||
fn push_dep_tracker(&mut self, slots: &[ExprId]) {
|
||||
let mut graph = Graph::new();
|
||||
let mut expr_to_node = HashMap::new();
|
||||
|
||||
@@ -38,8 +38,6 @@ pub trait DowngradeContext {
|
||||
where
|
||||
F: FnOnce(&mut Self) -> R;
|
||||
|
||||
fn get_current_dir(&self) -> std::path::PathBuf;
|
||||
|
||||
fn push_dep_tracker(&mut self, slots: &[ExprId]);
|
||||
fn push_dep_tracker_with_owner(&mut self, slots: &[ExprId], owner: ExprId);
|
||||
fn get_current_binding(&self) -> Option<ExprId>;
|
||||
|
||||
@@ -2,28 +2,10 @@
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
use rnix::ast::{self, Expr, HasEntry};
|
||||
use std::path::{Component, Path as StdPath, PathBuf};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
use super::*;
|
||||
|
||||
fn normalize_path(path: &StdPath) -> String {
|
||||
let mut normalized = PathBuf::new();
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::Prefix(p) => normalized.push(p.as_os_str()),
|
||||
Component::RootDir => normalized.push("/"),
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
normalized.pop();
|
||||
}
|
||||
Component::Normal(c) => normalized.push(c),
|
||||
}
|
||||
}
|
||||
normalized.to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
pub trait Downgrade<Ctx: DowngradeContext> {
|
||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId>;
|
||||
}
|
||||
@@ -75,33 +57,8 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::IfElse {
|
||||
|
||||
impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Path {
|
||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
||||
let parts_ast: Vec<_> = self.parts().collect();
|
||||
let has_interpolation = parts_ast
|
||||
.iter()
|
||||
.any(|part| matches!(part, ast::InterpolPart::Interpolation(_)));
|
||||
|
||||
let parts = if !has_interpolation {
|
||||
// Resolve at compile time
|
||||
let path_str: String = parts_ast
|
||||
.into_iter()
|
||||
.filter_map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Some(lit.to_string()),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let resolved_path = if path_str.starts_with('/') {
|
||||
normalize_path(&std::path::PathBuf::from(&path_str))
|
||||
} else {
|
||||
let current_dir = ctx.get_current_dir();
|
||||
normalize_path(¤t_dir.join(&path_str))
|
||||
};
|
||||
|
||||
vec![ctx.new_expr(Str { val: resolved_path }.to_ir())]
|
||||
} else {
|
||||
// Resolve at runtime
|
||||
parts_ast
|
||||
.into_iter()
|
||||
let parts = self
|
||||
.parts()
|
||||
.map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(
|
||||
Str {
|
||||
@@ -113,8 +70,7 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Path {
|
||||
interpol.expr().unwrap().downgrade(ctx)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
};
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let expr = if parts.len() == 1 {
|
||||
parts.into_iter().next().unwrap()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::DerefMut;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Component, PathBuf};
|
||||
use std::sync::Once;
|
||||
|
||||
use deno_core::{Extension, ExtensionFileSource, JsRuntime, OpState, RuntimeOptions, v8};
|
||||
@@ -125,13 +125,20 @@ fn op_resolve_path<Ctx: RuntimeCtx>(
|
||||
}
|
||||
|
||||
// Resolve relative path against current file directory (or CWD)
|
||||
let current_dir = ctx.get_current_dir();
|
||||
|
||||
Ok(current_dir
|
||||
.join(&path)
|
||||
.canonicalize()
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
.map_err(|e| format!("Failed to resolve path {}: {}", path, e))?)
|
||||
let current_dir = ctx.get_current_dir().join(&path);
|
||||
let mut normalized = PathBuf::new();
|
||||
for component in current_dir.components() {
|
||||
match component {
|
||||
Component::Prefix(p) => normalized.push(p.as_os_str()),
|
||||
Component::RootDir => normalized.push("/"),
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
normalized.pop();
|
||||
}
|
||||
Component::Normal(c) => normalized.push(c),
|
||||
}
|
||||
}
|
||||
Ok(normalized.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
#[deno_core::op2]
|
||||
|
||||
Reference in New Issue
Block a user