Validate project name on aiken new
This commit is contained in:
parent
2cac7963c3
commit
2736df5466
|
@ -64,6 +64,8 @@ dependencies = [
|
||||||
"pallas-crypto",
|
"pallas-crypto",
|
||||||
"pallas-primitives",
|
"pallas-primitives",
|
||||||
"pallas-traverse",
|
"pallas-traverse",
|
||||||
|
"regex",
|
||||||
|
"thiserror",
|
||||||
"uplc",
|
"uplc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -233,9 +235,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.2.22"
|
version = "3.2.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
|
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -245,7 +247,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap",
|
"textwrap 0.16.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -591,7 +593,7 @@ dependencies = [
|
||||||
"supports-hyperlinks",
|
"supports-hyperlinks",
|
||||||
"supports-unicode",
|
"supports-unicode",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
"textwrap",
|
"textwrap 0.15.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
@ -1214,15 +1216,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.15.1"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smawk",
|
"smawk",
|
||||||
"unicode-linebreak",
|
"unicode-linebreak",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
|
|
|
@ -20,6 +20,8 @@ pallas-codec = "0.14.0"
|
||||||
pallas-crypto = "0.14.0"
|
pallas-crypto = "0.14.0"
|
||||||
pallas-primitives = "0.14.0"
|
pallas-primitives = "0.14.0"
|
||||||
pallas-traverse = "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-lang = { path = "../lang", version = "0.0.24" }
|
||||||
aiken-lsp = { path = "../lsp", version = "0.0.0" }
|
aiken-lsp = { path = "../lsp", version = "0.0.0" }
|
||||||
|
|
|
@ -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 build;
|
||||||
pub mod check;
|
pub mod check;
|
||||||
|
pub mod error;
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
pub mod lsp;
|
pub mod lsp;
|
||||||
pub mod new;
|
pub mod new;
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::error::{Error, InvalidProjectNameReason};
|
||||||
|
|
||||||
#[derive(clap::Args)]
|
#[derive(clap::Args)]
|
||||||
/// Create a new Aiken project
|
/// Create a new Aiken project
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
|
@ -20,11 +22,11 @@ pub struct Creator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Creator {
|
impl Creator {
|
||||||
fn new(args: Args) -> Self {
|
fn new(args: Args, project_name: String) -> Self {
|
||||||
let root = args.name;
|
let root = args.name;
|
||||||
let src = root.join("src");
|
let src = root.join("src");
|
||||||
let scripts = src.join("scripts");
|
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);
|
let project = src.join(&project_name);
|
||||||
Self {
|
Self {
|
||||||
root,
|
root,
|
||||||
|
@ -111,9 +113,37 @@ fn write(path: PathBuf, contents: &str) -> miette::Result<()> {
|
||||||
Ok(())
|
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<()> {
|
pub fn exec(args: Args) -> miette::Result<()> {
|
||||||
if !args.name.exists() {
|
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()?;
|
creator.run()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue