Introduced a new command: command_name

Implemented a new command "command_name" in the CLi with its associated functionalities in the relevant modules. The new command allows the user to set the name field in the manifest file. Main.rs was updated to handle this new command and exhaustive error handling was added to the main function. Also, improved the manifest module for better error handling and added functionalities for getting and setting manifest's name.
This commit is contained in:
Ian Wijma 2024-01-05 22:03:47 +11:00
parent 63d01ea03c
commit 5dc0e68836
9 changed files with 109 additions and 18 deletions

9
Cargo.lock generated
View File

@ -113,6 +113,14 @@ dependencies = [
"manifest", "manifest",
] ]
[[package]]
name = "command_name"
version = "0.1.0"
dependencies = [
"clap",
"manifest",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -183,6 +191,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"command_init", "command_init",
"command_name",
] ]
[[package]] [[package]]

View File

@ -3,4 +3,5 @@ resolver = '2'
members = [ members = [
'mccli', 'mccli',
'command_init', 'command_init',
'command_name',
] ]

View File

@ -4,14 +4,16 @@ use manifest::Manifest;
#[derive(Args, Debug)] #[derive(Args, Debug)]
pub struct Arguments { pub struct Arguments {
#[arg(default_value = ".")] #[arg()]
directory: String directory: String,
} }
pub fn execute (_arguments: &Arguments) { pub fn execute (arguments: &Arguments) {
let directory: PathBuf = PathBuf::from(_arguments.directory.clone()); let Arguments { directory } = arguments;
let manifest = Manifest::from(&directory); let directory_path: PathBuf = PathBuf::from(directory);
let manifest = Manifest::from(&directory_path);
match manifest.init() { match manifest.init() {
true => println!("Project initialized"), true => println!("Project initialized"),

10
command_name/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "command_name"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
manifest = {path = "../manifest"}
clap = { version = "4.4.8", features = ["derive", "unicode", "wrap_help"] }

21
command_name/src/lib.rs Normal file
View File

@ -0,0 +1,21 @@
use std::path::PathBuf;
use clap::{Args};
use manifest::Manifest;
#[derive(Args, Debug)]
pub struct Arguments {
#[arg()]
directory: String,
#[arg(default_value = "")]
name: String,
}
pub fn execute (arguments: &Arguments) {
let Arguments {name, directory} = arguments;
let directory_path: PathBuf = PathBuf::from(directory);
let manifest = Manifest::from(&directory_path);
manifest.set_name(name.into());
}

View File

@ -42,15 +42,43 @@ impl Manifest {
false false
} }
pub fn file_path(&self) -> PathBuf { pub fn get_name(&self) -> String {
let ManifestFile { name, .. } = self.get_manifest_file();
return name;
}
pub fn set_name(&self, name: String) {
let file = self.file_path();
let mut manifest_file = self.get_manifest_file();
manifest_file.name = name;
match manifest_file.write(&file) {
Ok(_) => println!("Name updated"),
Err(_) => panic!("Unable to update the name")
}
}
fn get_manifest_file(&self) -> ManifestFile {
let file = self.file_path();
match ManifestFile::read(&file) {
Ok(manifest_file) => manifest_file,
Err(_) => panic!("Unable to read file: {:?}", file)
}
}
fn file_path(&self) -> PathBuf {
return PathBuf::from(format!("{}/{}", self.directory.to_string_lossy(), "mccli.yaml")); return PathBuf::from(format!("{}/{}", self.directory.to_string_lossy(), "mccli.yaml"));
} }
pub fn directory_path(&self) -> PathBuf { fn directory_path(&self) -> PathBuf {
return PathBuf::from(&self.directory); return PathBuf::from(&self.directory);
} }
pub fn directory_name(&self) -> String { fn directory_name(&self) -> String {
let directory = self.directory_path(); let directory = self.directory_path();
return directory return directory
@ -59,4 +87,6 @@ impl Manifest {
.to_string_lossy() .to_string_lossy()
.to_string(); .to_string();
} }
} }

View File

@ -3,22 +3,22 @@ use std::fs;
use std::fs::File; use std::fs::File;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::path::PathBuf; use std::path::PathBuf;
use serde::de::DeserializeOwned;
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug)]
pub struct ManifestFile { pub struct ManifestFile {
name: String, pub version: u8,
pub name: String,
} }
impl ManifestFile { impl ManifestFile {
pub fn from(name: String) -> ManifestFile { pub fn from(name: String) -> ManifestFile {
return ManifestFile { name } return ManifestFile { version: 1, name }
} }
pub fn read<Content: DeserializeOwned>(path: &PathBuf) -> Result<Content, Box<dyn Error>> { pub fn read(path: &PathBuf) -> Result<ManifestFile, Box<dyn Error>> {
let file = File::open(path)?; let file = File::open(path)?;
let data: Content = serde_yaml::from_reader(file)?; let data: ManifestFile = serde_yaml::from_reader(file)?;
Ok(data) Ok(data)
} }
@ -34,4 +34,4 @@ impl ManifestFile {
Ok(true) Ok(true)
} }
} }

View File

@ -7,4 +7,5 @@ edition = "2021"
[dependencies] [dependencies]
clap = { version = "4.4.8", features = ["derive", "unicode", "wrap_help"] } clap = { version = "4.4.8", features = ["derive", "unicode", "wrap_help"] }
command_init = { path = '../command_init' } command_init = { path = '../command_init' }
command_name = { path = '../command_name' }

View File

@ -1,3 +1,4 @@
use std::panic;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -10,12 +11,28 @@ struct Arguments {
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
enum Command { enum Command {
Init(command_init::Arguments), Init(command_init::Arguments),
Name(command_name::Arguments),
} }
fn main() { fn main() {
let arguments = Arguments::parse(); let arguments = Arguments::parse();
match &arguments.command { // TODO: Remove panics and use Results instead.
Command::Init(arguments) => { command_init::execute(arguments) } let result = panic::catch_unwind(|| {
match &arguments.command {
Command::Init(arguments) => { command_init::execute(arguments) },
Command::Name(arguments) => { command_name::execute(arguments) },
}
});
match result {
Ok(_) => {}
Err(err) => {
if let Some(s) = err.downcast_ref::<&str>() {
println!("Panic occurred with message: {}", s);
} else {
println!("Panic occurred with unknown payload.");
}
}
} }
} }