Validate project name on aiken new
This commit is contained in:
@@ -20,6 +20,8 @@ pallas-codec = "0.14.0"
|
||||
pallas-crypto = "0.14.0"
|
||||
pallas-primitives = "0.14.0"
|
||||
pallas-traverse = "0.14.0"
|
||||
regex = "1.5.4"
|
||||
thiserror = "1.0.31"
|
||||
|
||||
aiken-lang = { path = "../lang", version = "0.0.24" }
|
||||
aiken-lsp = { path = "../lsp", version = "0.0.0" }
|
||||
|
||||
36
crates/cli/src/cmd/error.rs
Normal file
36
crates/cli/src/cmd/error.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use std::fmt;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("{} is not a valid project name. {}", name, reason.to_string())]
|
||||
InvalidProjectName {
|
||||
name: String,
|
||||
reason: InvalidProjectNameReason,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum InvalidProjectNameReason {
|
||||
AikenPrefix,
|
||||
AikenReservedModule,
|
||||
Format,
|
||||
}
|
||||
|
||||
impl fmt::Display for InvalidProjectNameReason {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InvalidProjectNameReason::AikenPrefix => write!(f, "It is a reserved word in Aiken."),
|
||||
InvalidProjectNameReason::AikenReservedModule => {
|
||||
write!(f, "It is a reserved module name in Aiken.")
|
||||
}
|
||||
InvalidProjectNameReason::Format => write!(
|
||||
f,
|
||||
"It does not have the correct format. Project names \
|
||||
must start with a lowercase letter and may only contain lowercase letters, \
|
||||
numbers and underscores."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod build;
|
||||
pub mod check;
|
||||
pub mod error;
|
||||
pub mod fmt;
|
||||
pub mod lsp;
|
||||
pub mod new;
|
||||
|
||||
@@ -4,6 +4,8 @@ use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::error::{Error, InvalidProjectNameReason};
|
||||
|
||||
#[derive(clap::Args)]
|
||||
/// Create a new Aiken project
|
||||
pub struct Args {
|
||||
@@ -20,11 +22,11 @@ pub struct Creator {
|
||||
}
|
||||
|
||||
impl Creator {
|
||||
fn new(args: Args) -> Self {
|
||||
fn new(args: Args, project_name: String) -> Self {
|
||||
let root = args.name;
|
||||
let src = root.join("src");
|
||||
let scripts = src.join("scripts");
|
||||
let project_name = root.clone().into_os_string().into_string().unwrap();
|
||||
let project_name = project_name;
|
||||
let project = src.join(&project_name);
|
||||
Self {
|
||||
root,
|
||||
@@ -111,9 +113,37 @@ fn write(path: PathBuf, contents: &str) -> miette::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_name(name: &str) -> Result<(), Error> {
|
||||
if name.starts_with("aiken_") {
|
||||
Err(Error::InvalidProjectName {
|
||||
name: name.to_string(),
|
||||
reason: InvalidProjectNameReason::AikenPrefix,
|
||||
})
|
||||
} else if name == "aiken" {
|
||||
Err(Error::InvalidProjectName {
|
||||
name: name.to_string(),
|
||||
reason: InvalidProjectNameReason::AikenReservedModule,
|
||||
})
|
||||
} else if !regex::Regex::new("^[a-z][a-z0-9_]*$")
|
||||
.expect("new name regex could not be compiled")
|
||||
.is_match(name)
|
||||
{
|
||||
Err(Error::InvalidProjectName {
|
||||
name: name.to_string(),
|
||||
reason: InvalidProjectNameReason::Format,
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec(args: Args) -> miette::Result<()> {
|
||||
if !args.name.exists() {
|
||||
let creator = Creator::new(args);
|
||||
let project_name = args.name.clone().into_os_string().into_string().unwrap();
|
||||
|
||||
validate_name(&project_name).into_diagnostic()?;
|
||||
|
||||
let creator = Creator::new(args, project_name);
|
||||
creator.run()?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user