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 {
Lib,
Validator,
Env,
}
impl ModuleKind {
@ -38,6 +39,10 @@ impl ModuleKind {
pub fn is_lib(&self) -> bool {
matches!(self, ModuleKind::Lib)
}
pub fn is_env(&self) -> bool {
matches!(self, ModuleKind::Env)
}
}
#[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()
&& (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 {
location: *location,

View File

@ -127,6 +127,9 @@ pub enum Error {
#[error("I couldn't find any exportable function named '{name}' in module '{module}'.")]
ExportNotFound { module: String, name: String },
#[error("I located conditional modules under 'env', but no default one!")]
NoDefaultEnvironment,
}
impl Error {
@ -195,6 +198,7 @@ impl ExtraData for Error {
| Error::NoValidatorNotFound { .. }
| Error::MoreThanOneValidatorFound { .. }
| Error::Module { .. }
| Error::NoDefaultEnvironment { .. }
| Error::ExportNotFound { .. } => None,
Error::Type { error, .. } => error.extra_data(),
}
@ -224,6 +228,7 @@ impl GetSource for Error {
| Error::NoValidatorNotFound { .. }
| Error::MoreThanOneValidatorFound { .. }
| Error::ExportNotFound { .. }
| Error::NoDefaultEnvironment { .. }
| Error::Module { .. } => None,
Error::DuplicateModule { second: path, .. }
| Error::MissingManifest { path }
@ -252,6 +257,7 @@ impl GetSource for Error {
| Error::Json { .. }
| Error::MalformedStakeAddress { .. }
| Error::NoValidatorNotFound { .. }
| Error::NoDefaultEnvironment { .. }
| Error::MoreThanOneValidatorFound { .. }
| Error::ExportNotFound { .. }
| Error::Module { .. } => None,
@ -307,6 +313,7 @@ impl Diagnostic for Error {
Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None,
Error::ExportNotFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.code().map(boxed),
}
}
@ -330,6 +337,9 @@ impl Diagnostic for Error {
Error::MissingManifest { .. } => Some(Box::new(
"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::Format { .. } => None,
Error::TestFailure { .. } => None,
@ -408,6 +418,7 @@ impl Diagnostic for Error {
Error::MalformedStakeAddress { .. } => None,
Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.labels(),
}
}
@ -419,6 +430,7 @@ impl Diagnostic for Error {
Error::ImportCycle { .. } => None,
Error::ExportNotFound { .. } => None,
Error::Blueprint(e) => e.source_code(),
Error::NoDefaultEnvironment { .. } => None,
Error::Parse { named, .. } => Some(named),
Error::Type { named, .. } => Some(named),
Error::StandardIo(_) => None,
@ -462,6 +474,7 @@ impl Diagnostic for Error {
Error::MalformedStakeAddress { .. } => None,
Error::NoValidatorNotFound { .. } => None,
Error::MoreThanOneValidatorFound { .. } => None,
Error::NoDefaultEnvironment { .. } => None,
Error::Module(e) => e.url(),
}
}
@ -476,6 +489,7 @@ impl Diagnostic for Error {
Error::Parse { .. } => None,
Error::Type { error, .. } => error.related(),
Error::StandardIo(_) => None,
Error::NoDefaultEnvironment { .. } => None,
Error::MissingManifest { .. } => None,
Error::TomlLoading { .. } => None,
Error::Format { .. } => None,

View File

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