Parse sources of conditional env modules.

Do nothing about it yet, but trigger an error if env/default.ak is
  missing; but only if there's any module at all under env.
This commit is contained in:
KtorZ 2024-08-03 17:42:55 +02:00
parent 4645257e62
commit c9d0da0c22
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 42 additions and 2 deletions

View File

@ -28,6 +28,7 @@ pub type UntypedModule = Module<(), UntypedDefinition>;
pub enum ModuleKind { pub enum ModuleKind {
Lib, Lib,
Validator, Validator,
Env,
} }
impl ModuleKind { impl ModuleKind {
@ -38,6 +39,10 @@ impl ModuleKind {
pub fn is_lib(&self) -> bool { pub fn is_lib(&self) -> bool {
matches!(self, ModuleKind::Lib) matches!(self, ModuleKind::Lib)
} }
pub fn is_env(&self) -> bool {
matches!(self, ModuleKind::Env)
}
} }
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]

View File

@ -785,7 +785,9 @@ impl<'a> Environment<'a> {
})?; })?;
if module_info.kind.is_validator() if module_info.kind.is_validator()
&& (self.current_kind.is_lib() || !self.current_module.starts_with("tests")) && (self.current_kind.is_lib()
|| self.current_kind.is_env()
|| !self.current_module.starts_with("tests"))
{ {
return Err(Error::ValidatorImported { return Err(Error::ValidatorImported {
location: *location, location: *location,

View File

@ -127,6 +127,9 @@ pub enum Error {
#[error("I couldn't find any exportable function named '{name}' in module '{module}'.")] #[error("I couldn't find any exportable function named '{name}' in module '{module}'.")]
ExportNotFound { module: String, name: String }, ExportNotFound { module: String, name: String },
#[error("I located conditional modules under 'env', but no default one!")]
NoDefaultEnvironment,
} }
impl Error { impl Error {
@ -195,6 +198,7 @@ impl ExtraData for Error {
| Error::NoValidatorNotFound { .. } | Error::NoValidatorNotFound { .. }
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::Module { .. } | Error::Module { .. }
| Error::NoDefaultEnvironment { .. }
| Error::ExportNotFound { .. } => None, | Error::ExportNotFound { .. } => None,
Error::Type { error, .. } => error.extra_data(), Error::Type { error, .. } => error.extra_data(),
} }
@ -224,6 +228,7 @@ impl GetSource for Error {
| Error::NoValidatorNotFound { .. } | Error::NoValidatorNotFound { .. }
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::ExportNotFound { .. } | Error::ExportNotFound { .. }
| Error::NoDefaultEnvironment { .. }
| Error::Module { .. } => None, | Error::Module { .. } => None,
Error::DuplicateModule { second: path, .. } Error::DuplicateModule { second: path, .. }
| Error::MissingManifest { path } | Error::MissingManifest { path }
@ -252,6 +257,7 @@ impl GetSource for Error {
| Error::Json { .. } | Error::Json { .. }
| Error::MalformedStakeAddress { .. } | Error::MalformedStakeAddress { .. }
| Error::NoValidatorNotFound { .. } | Error::NoValidatorNotFound { .. }
| Error::NoDefaultEnvironment { .. }
| Error::MoreThanOneValidatorFound { .. } | Error::MoreThanOneValidatorFound { .. }
| Error::ExportNotFound { .. } | Error::ExportNotFound { .. }
| Error::Module { .. } => None, | Error::Module { .. } => None,
@ -307,6 +313,7 @@ impl Diagnostic for Error {
Error::NoValidatorNotFound { .. } => None, Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None, Error::MoreThanOneValidatorFound { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.code().map(boxed), Error::Module(e) => e.code().map(boxed),
} }
} }
@ -330,6 +337,9 @@ impl Diagnostic for Error {
Error::MissingManifest { .. } => Some(Box::new( Error::MissingManifest { .. } => Some(Box::new(
"Try running `aiken new <REPOSITORY/PROJECT>` to initialise a project with an example manifest.", "Try running `aiken new <REPOSITORY/PROJECT>` to initialise a project with an example manifest.",
)), )),
Error::NoDefaultEnvironment { .. } => Some(Box::new(
"Environment module names are free, but there must be at least one named 'default.ak'.",
)),
Error::TomlLoading { .. } => None, Error::TomlLoading { .. } => None,
Error::Format { .. } => None, Error::Format { .. } => None,
Error::TestFailure { .. } => None, Error::TestFailure { .. } => None,
@ -408,6 +418,7 @@ impl Diagnostic for Error {
Error::MalformedStakeAddress { .. } => None, Error::MalformedStakeAddress { .. } => None,
Error::NoValidatorNotFound { .. } => None, Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None, Error::MoreThanOneValidatorFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.labels(), Error::Module(e) => e.labels(),
} }
} }
@ -419,6 +430,7 @@ impl Diagnostic for Error {
Error::ImportCycle { .. } => None, Error::ImportCycle { .. } => None,
Error::ExportNotFound { .. } => None, Error::ExportNotFound { .. } => None,
Error::Blueprint(e) => e.source_code(), Error::Blueprint(e) => e.source_code(),
Error::NoDefaultEnvironment { .. } => None,
Error::Parse { named, .. } => Some(named), Error::Parse { named, .. } => Some(named),
Error::Type { named, .. } => Some(named), Error::Type { named, .. } => Some(named),
Error::StandardIo(_) => None, Error::StandardIo(_) => None,
@ -462,6 +474,7 @@ impl Diagnostic for Error {
Error::MalformedStakeAddress { .. } => None, Error::MalformedStakeAddress { .. } => None,
Error::NoValidatorNotFound { .. } => None, Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None, Error::MoreThanOneValidatorFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.url(), Error::Module(e) => e.url(),
} }
} }
@ -476,6 +489,7 @@ impl Diagnostic for Error {
Error::Parse { .. } => None, Error::Parse { .. } => None,
Error::Type { error, .. } => error.related(), Error::Type { error, .. } => error.related(),
Error::StandardIo(_) => None, Error::StandardIo(_) => None,
Error::NoDefaultEnvironment { .. } => None,
Error::MissingManifest { .. } => None, Error::MissingManifest { .. } => None,
Error::TomlLoading { .. } => None, Error::TomlLoading { .. } => None,
Error::Format { .. } => None, Error::Format { .. } => None,

View File

@ -65,6 +65,8 @@ use uplc::{
PlutusData, PlutusData,
}; };
const DEFAULT_ENV_MODULE: &str = "default";
#[derive(Debug)] #[derive(Debug)]
pub struct Source { pub struct Source {
pub path: PathBuf, pub path: PathBuf,
@ -611,11 +613,13 @@ where
} }
fn read_source_files(&mut self) -> Result<(), Error> { fn read_source_files(&mut self) -> Result<(), Error> {
let env = self.root.join("env");
let lib = self.root.join("lib"); let lib = self.root.join("lib");
let validators = self.root.join("validators"); let validators = self.root.join("validators");
self.aiken_files(&validators, ModuleKind::Validator)?; self.aiken_files(&validators, ModuleKind::Validator)?;
self.aiken_files(&lib, ModuleKind::Lib)?; self.aiken_files(&lib, ModuleKind::Lib)?;
self.aiken_files(&env, ModuleKind::Env)?;
Ok(()) Ok(())
} }
@ -879,12 +883,18 @@ where
} }
fn aiken_files(&mut self, dir: &Path, kind: ModuleKind) -> Result<(), Error> { fn aiken_files(&mut self, dir: &Path, kind: ModuleKind) -> Result<(), Error> {
let mut has_default = None;
walkdir::WalkDir::new(dir) walkdir::WalkDir::new(dir)
.follow_links(true) .follow_links(true)
.into_iter() .into_iter()
.filter_map(Result::ok) .filter_map(Result::ok)
.filter(|e| e.file_type().is_file()) .filter(|e| e.file_type().is_file())
.try_for_each(|d| { .try_for_each(|d| {
if has_default.is_none() {
has_default = Some(false);
}
let path = d.into_path(); let path = d.into_path();
let keep = is_aiken_path(&path, dir); let keep = is_aiken_path(&path, dir);
let ext = path.extension(); let ext = path.extension();
@ -895,11 +905,20 @@ where
} }
if keep { if keep {
if self.module_name(dir, &path).as_str() == DEFAULT_ENV_MODULE {
has_default = Some(true);
}
self.add_module(path, dir, kind) self.add_module(path, dir, kind)
} else { } else {
Ok(()) Ok(())
} }
}) })?;
if kind == ModuleKind::Env && has_default == Some(false) {
return Err(Error::NoDefaultEnvironment);
}
Ok(())
} }
fn add_module(&mut self, path: PathBuf, dir: &Path, kind: ModuleKind) -> Result<(), Error> { fn add_module(&mut self, path: PathBuf, dir: &Path, kind: ModuleKind) -> Result<(), Error> {