Add new 'deps add' command
This makes it easier to add new dependencies, without having to manually edit the `aiken.toml` file. The command is accessible via two different paths: - aiken deps add or simply - aiken add for this is quite common to find at the top-level of the command-line, and, we still want to keep commands for managing dependencies grouped under a command sub-group and not all at the top-level. So we're merely promoting that one for visibility.
This commit is contained in:
@@ -2,17 +2,13 @@ use crate::{package_name::PackageName, Error};
|
||||
use aiken_lang::ast::Span;
|
||||
use miette::NamedSource;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::Display,
|
||||
fs, io,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::{fmt::Display, fs, io, path::Path};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub name: PackageName,
|
||||
pub version: String,
|
||||
pub license: String,
|
||||
pub license: Option<String>,
|
||||
#[serde(default)]
|
||||
pub description: String,
|
||||
pub repository: Option<Repository>,
|
||||
@@ -57,7 +53,7 @@ impl Config {
|
||||
Config {
|
||||
name: name.clone(),
|
||||
version: "0.0.0".to_string(),
|
||||
license: "Apache-2.0".to_string(),
|
||||
license: Some("Apache-2.0".to_string()),
|
||||
description: format!("Aiken contracts for project '{name}'"),
|
||||
repository: Some(Repository {
|
||||
user: name.owner.clone(),
|
||||
@@ -81,10 +77,11 @@ impl Config {
|
||||
fs::write(aiken_toml_path, aiken_toml)
|
||||
}
|
||||
|
||||
pub fn load(dir: PathBuf) -> Result<Config, Error> {
|
||||
pub fn load(dir: &Path) -> Result<Config, Error> {
|
||||
let config_path = dir.join("aiken.toml");
|
||||
let raw_config = fs::read_to_string(&config_path)
|
||||
.map_err(|_| Error::MissingManifest { path: dir.clone() })?;
|
||||
let raw_config = fs::read_to_string(&config_path).map_err(|_| Error::MissingManifest {
|
||||
path: dir.to_path_buf(),
|
||||
})?;
|
||||
|
||||
let result: Self = toml::from_str(&raw_config).map_err(|e| Error::TomlLoading {
|
||||
path: config_path.clone(),
|
||||
@@ -100,4 +97,19 @@ impl Config {
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn insert(mut self, dependency: &Dependency, and_replace: bool) -> Option<Self> {
|
||||
for mut existing in self.dependencies.iter_mut() {
|
||||
if existing.name == dependency.name {
|
||||
return if and_replace {
|
||||
existing.version = dependency.version.clone();
|
||||
Some(self)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
}
|
||||
self.dependencies.push(dependency.clone());
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{deps::manifest::Package, pretty, script::EvalHint};
|
||||
use crate::{deps::manifest::Package, package_name::PackageName, pretty, script::EvalHint};
|
||||
use aiken_lang::{
|
||||
ast::{BinOp, Span},
|
||||
parser::error::ParseError,
|
||||
@@ -418,6 +418,8 @@ pub enum Warning {
|
||||
#[source]
|
||||
warning: tipo::error::Warning,
|
||||
},
|
||||
#[error("{name} is already a dependency.")]
|
||||
DependencyAlreadyExists { name: PackageName },
|
||||
}
|
||||
|
||||
impl Diagnostic for Warning {
|
||||
@@ -429,6 +431,7 @@ impl Diagnostic for Warning {
|
||||
match self {
|
||||
Warning::Type { named, .. } => Some(named),
|
||||
Warning::NoValidators => None,
|
||||
Warning::DependencyAlreadyExists { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +439,7 @@ impl Diagnostic for Warning {
|
||||
match self {
|
||||
Warning::Type { warning, .. } => warning.labels(),
|
||||
Warning::NoValidators => None,
|
||||
Warning::DependencyAlreadyExists { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,6 +447,19 @@ impl Diagnostic for Warning {
|
||||
match self {
|
||||
Warning::Type { .. } => Some(Box::new("aiken::check")),
|
||||
Warning::NoValidators => Some(Box::new("aiken::check")),
|
||||
Warning::DependencyAlreadyExists { .. } => {
|
||||
Some(Box::new("aiken::deps::already_exists"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||
match self {
|
||||
Warning::Type { .. } => None,
|
||||
Warning::NoValidators => None,
|
||||
Warning::DependencyAlreadyExists { .. } => Some(Box::new(
|
||||
"If you need to change the version, try 'aiken packages upgrade' instead.",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ where
|
||||
module_types.insert("aiken".to_string(), builtins::prelude(&id_gen));
|
||||
module_types.insert("aiken/builtin".to_string(), builtins::plutus(&id_gen));
|
||||
|
||||
let config = Config::load(root.clone())?;
|
||||
let config = Config::load(&root)?;
|
||||
|
||||
Ok(Project {
|
||||
config,
|
||||
|
||||
@@ -13,22 +13,24 @@ pub struct PackageName {
|
||||
}
|
||||
|
||||
impl PackageName {
|
||||
fn validate(&self) -> Result<(), Error> {
|
||||
let name = format!("{}/{}", self.owner, self.repo);
|
||||
|
||||
pub fn restrict(&self) -> Result<(), Error> {
|
||||
if self.owner.starts_with("aiken") {
|
||||
return Err(Error::InvalidProjectName {
|
||||
reason: InvalidProjectNameReason::Reserved,
|
||||
name,
|
||||
name: self.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), Error> {
|
||||
let r = regex::Regex::new("^[a-z0-9_-]+$").expect("regex could not be compiled");
|
||||
|
||||
if !(r.is_match(&self.owner) && r.is_match(&self.repo)) {
|
||||
return Err(Error::InvalidProjectName {
|
||||
reason: InvalidProjectNameReason::Format,
|
||||
name,
|
||||
name: self.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user