From 77eedfdd5e341f96aa34a60f3725431d6bc5da02 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Fri, 10 May 2024 14:22:08 -0500 Subject: [PATCH] Wire it up to eval and export --- cli/src/error.rs | 11 +++++++++++ cli/src/input.rs | 16 ++++++++++++++++ core/src/error/mod.rs | 11 ++++++++++- package/src/lib.rs | 12 ++++++++++++ package/src/lock.rs | 4 +++- 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/cli/src/error.rs b/cli/src/error.rs index 887a95f623..5efac067e1 100644 --- a/cli/src/error.rs +++ b/cli/src/error.rs @@ -54,6 +54,10 @@ pub enum Error { error: CliUsageError, }, NoManifest, + /// The provided manifest path doesn't have a parent directory. + NoPackageRoot { + manifest_path: std::path::PathBuf, + }, Package { error: nickel_lang_package::Error, }, @@ -290,6 +294,13 @@ impl Error { report_standalone("failed to read manifest file", Some(error.to_string())) } } + Error::NoPackageRoot { manifest_path } => report_standalone( + &format!( + "invalid manifest path `{}` has no parent", + manifest_path.display() + ), + None, + ), } } } diff --git a/cli/src/input.rs b/cli/src/input.rs index 502d275a1f..476690d42f 100644 --- a/cli/src/input.rs +++ b/cli/src/input.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use nickel_lang_core::{eval::cache::lazy::CBNCache, program::Program}; +use nickel_lang_package::ManifestFile; use crate::{cli::GlobalOptions, customize::Customize, error::CliResult}; @@ -23,6 +24,9 @@ pub struct InputOptions { #[arg(long, short = 'I', global = true)] pub import_path: Vec, + #[arg(long, global = true)] + pub manifest_path: Option, + #[command(flatten)] pub customize_mode: Customize, } @@ -47,6 +51,18 @@ impl Prepare for InputOptions { program.add_import_paths(nickel_path.split(':')); } + if let Some(manifest_path) = self.manifest_path.as_ref() { + let root_path = + manifest_path + .parent() + .ok_or_else(|| crate::error::Error::NoPackageRoot { + manifest_path: manifest_path.clone(), + })?; + let lock_file = ManifestFile::from_path(manifest_path)?.lock()?; + let package_map = lock_file.resolve_package_map(root_path.to_owned())?; + program.set_package_map(package_map); + } + #[cfg(debug_assertions)] if self.nostdlib { program.set_skip_stdlib(); diff --git a/core/src/error/mod.rs b/core/src/error/mod.rs index 8165786669..3e557cb749 100644 --- a/core/src/error/mod.rs +++ b/core/src/error/mod.rs @@ -2598,7 +2598,16 @@ impl IntoDiagnostics for ImportError { vec![Diagnostic::error().with_message(msg).with_labels(labels)] } - ImportError::NoPackageMap { pos } => todo!(), + ImportError::NoPackageMap { pos } => { + let labels = pos + .as_opt_ref() + .map(|span| vec![primary(span).with_message("imported here")]) + .unwrap_or_default(); + vec![Diagnostic::error() + .with_message("tried to import from a package, but no package manifest found") + .with_labels(labels) + .with_notes(vec!["did you forget a --manifest-path argument?".to_owned()])] + } } } } diff --git a/package/src/lib.rs b/package/src/lib.rs index c01bbb0c02..978de01d07 100644 --- a/package/src/lib.rs +++ b/package/src/lib.rs @@ -14,6 +14,9 @@ pub use manifest::ManifestFile; // TODO: enrich all these errors with the location of the upstream manifest file pub enum Error { + Io { + error: std::io::Error, + }, ManifestEval { package: Option, program: Program, @@ -32,6 +35,9 @@ pub enum Error { impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Error::Io { error } => { + write!(f, "I/O error: {error}") + } Error::ManifestEval { .. } => todo!(), Error::InvalidPathImport { spec } => { write!(f, "invalid import path: {spec:?}") @@ -44,6 +50,12 @@ impl std::fmt::Display for Error { } } +impl From for Error { + fn from(error: std::io::Error) -> Self { + Self::Io { error } + } +} + /// A source includes the place to fetch a package from (e.g. git or a registry), /// along with possibly some narrowing-down of the allowed versions (e.g. a range /// of versions, or a git commit id). diff --git a/package/src/lock.rs b/package/src/lock.rs index 5537b8be90..1fe8961ee1 100644 --- a/package/src/lock.rs +++ b/package/src/lock.rs @@ -7,7 +7,7 @@ use std::{ use directories::ProjectDirs; use nickel_lang_core::{ - cache::normalize_abs_path, + cache::{normalize_abs_path, normalize_path}, package::{Name, ObjectId, PackageMap}, }; use serde::{Deserialize, Serialize}; @@ -149,6 +149,8 @@ impl LockFile { // been re-written to git dependencies; and there are no path dependencies of path dependencies // because those haven't been expanded yet. + let root_path = normalize_path(root_path)?; + let mut ret = PackageMap { // Make all path dependencies of the root absolute. top_level: self