From 5dc0e68836e586225f3f57be61d0cf8f85fb7e9a Mon Sep 17 00:00:00 2001 From: Ian Wijma Date: Fri, 5 Jan 2024 22:03:47 +1100 Subject: [PATCH] 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. --- Cargo.lock | 9 +++++++++ Cargo.toml | 1 + command_init/src/lib.rs | 12 +++++++----- command_name/Cargo.toml | 10 ++++++++++ command_name/src/lib.rs | 21 ++++++++++++++++++++ manifest/src/lib.rs | 36 ++++++++++++++++++++++++++++++++--- manifest/src/manifest_file.rs | 14 +++++++------- mccli/Cargo.toml | 3 ++- mccli/src/main.rs | 21 ++++++++++++++++++-- 9 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 command_name/Cargo.toml create mode 100644 command_name/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8fb9bc3..e2c3e40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,14 @@ dependencies = [ "manifest", ] +[[package]] +name = "command_name" +version = "0.1.0" +dependencies = [ + "clap", + "manifest", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -183,6 +191,7 @@ version = "0.1.0" dependencies = [ "clap", "command_init", + "command_name", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c839548..ff79a22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,5 @@ resolver = '2' members = [ 'mccli', 'command_init', + 'command_name', ] diff --git a/command_init/src/lib.rs b/command_init/src/lib.rs index 7d941fa..2190cc6 100644 --- a/command_init/src/lib.rs +++ b/command_init/src/lib.rs @@ -4,14 +4,16 @@ use manifest::Manifest; #[derive(Args, Debug)] pub struct Arguments { - #[arg(default_value = ".")] - directory: String + #[arg()] + directory: String, } -pub fn execute (_arguments: &Arguments) { - let directory: PathBuf = PathBuf::from(_arguments.directory.clone()); +pub fn execute (arguments: &Arguments) { + 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() { true => println!("Project initialized"), diff --git a/command_name/Cargo.toml b/command_name/Cargo.toml new file mode 100644 index 0000000..8b1b476 --- /dev/null +++ b/command_name/Cargo.toml @@ -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"] } diff --git a/command_name/src/lib.rs b/command_name/src/lib.rs new file mode 100644 index 0000000..fda6840 --- /dev/null +++ b/command_name/src/lib.rs @@ -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()); +} diff --git a/manifest/src/lib.rs b/manifest/src/lib.rs index d39d631..3f37ec9 100644 --- a/manifest/src/lib.rs +++ b/manifest/src/lib.rs @@ -42,15 +42,43 @@ impl Manifest { 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")); } - pub fn directory_path(&self) -> PathBuf { + fn directory_path(&self) -> PathBuf { return PathBuf::from(&self.directory); } - pub fn directory_name(&self) -> String { + fn directory_name(&self) -> String { let directory = self.directory_path(); return directory @@ -59,4 +87,6 @@ impl Manifest { .to_string_lossy() .to_string(); } + + } diff --git a/manifest/src/manifest_file.rs b/manifest/src/manifest_file.rs index 00553f8..c8b104c 100644 --- a/manifest/src/manifest_file.rs +++ b/manifest/src/manifest_file.rs @@ -3,22 +3,22 @@ use std::fs; use std::fs::File; use serde::{Serialize, Deserialize}; use std::path::PathBuf; -use serde::de::DeserializeOwned; -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Debug)] pub struct ManifestFile { - name: String, + pub version: u8, + pub name: String, } impl ManifestFile { pub fn from(name: String) -> ManifestFile { - return ManifestFile { name } + return ManifestFile { version: 1, name } } - pub fn read(path: &PathBuf) -> Result> { + pub fn read(path: &PathBuf) -> Result> { let file = File::open(path)?; - let data: Content = serde_yaml::from_reader(file)?; + let data: ManifestFile = serde_yaml::from_reader(file)?; Ok(data) } @@ -34,4 +34,4 @@ impl ManifestFile { Ok(true) } -} \ No newline at end of file +} diff --git a/mccli/Cargo.toml b/mccli/Cargo.toml index 4a9b921..f987592 100644 --- a/mccli/Cargo.toml +++ b/mccli/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] clap = { version = "4.4.8", features = ["derive", "unicode", "wrap_help"] } -command_init = { path = '../command_init' } \ No newline at end of file +command_init = { path = '../command_init' } +command_name = { path = '../command_name' } \ No newline at end of file diff --git a/mccli/src/main.rs b/mccli/src/main.rs index e691daa..f13b475 100644 --- a/mccli/src/main.rs +++ b/mccli/src/main.rs @@ -1,3 +1,4 @@ +use std::panic; use clap::{Parser, Subcommand}; #[derive(Parser, Debug)] @@ -10,12 +11,28 @@ struct Arguments { #[derive(Subcommand, Debug)] enum Command { Init(command_init::Arguments), + Name(command_name::Arguments), } fn main() { let arguments = Arguments::parse(); - match &arguments.command { - Command::Init(arguments) => { command_init::execute(arguments) } + // TODO: Remove panics and use Results instead. + 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."); + } + } } }