use std::io::Result;
+use super::{
+ generate::Generate,
+ sync_down::SyncDown,
+ sync_up::SyncUp,
+ update::Update
+};
pub struct Add;
impl super::Command for Add {
fn before_dependencies(&self) -> Vec<Box<dyn super::Command>> {
- vec![]
+ vec![Box::new(SyncDown::new())]
}
fn execute(&self, input: Option<&String>) -> Result<()> {
}
fn after_dependencies(&self) -> Vec<Box<dyn super::Command>> {
- vec![]
+ vec![
+ Box::new(Update::new()),
+ Box::new(Generate::new()),
+ Box::new(SyncUp::new())
+ ]
}
fn command(&self) -> &'static str {
-use std::env::args;
use std::io::Result;
use super::available_commands;
}
fn execute(&self, _: Option<&String>) -> Result<()> {
- let arguments: Vec<String> = args().collect();
- let app_name = arguments.get(0).map_or("blog", |s| s.as_str());
let commands = available_commands();
println!("Usage:");
println!("");
for command in commands {
- print!("{} {} ", app_name, command.command());
+ print!("blog {} ", command.command());
println!("{}", command.help());
}
return Ok(())
pub mod remove_remote;
pub mod sync_up;
pub mod sync_down;
+pub mod status;
pub mod version;
pub mod help;
+
use std::io::Result;
use add::Add;
use sync_up::SyncUp;
use sync_down::SyncDown;
use version::Version;
+use status::Status;
use help::Help;
pub trait Command {
Box::new(RemoveRemote::new()),
Box::new(SyncUp::new()),
Box::new(SyncDown::new()),
+ Box::new(Status::new()),
Box::new(Version::new()),
Box::new(Help::new())
]
--- /dev/null
+use std::fs;
+use std::path::PathBuf;
+use crate::configuration::Configuration;
+
+pub fn status() -> String {
+ let configuration = Configuration::new();
+ let mut status_message = String::new();
+
+ status_message.push_str("# Configuration\n");
+ status_message.push_str("## Directories\n");
+
+ // Main Configuration Locations
+ status_message.push_str(&get_directory_stats("Configuration", configuration.config_directory));
+ status_message.push_str(&get_directory_stats("Data", configuration.data_directory));
+ status_message.push_str(&get_directory_stats("Output", configuration.output_directory));
+
+ status_message.push_str("## Blog Settings\n");
+ status_message.push_str(&format!("Number of posts to keep: {}\n", configuration.max_posts));
+ status_message
+}
+
+fn get_directory_stats(label: &str, directory: PathBuf) -> String {
+ let mut status_message = String::new();
+
+ status_message.push_str(&format!("{}: {}\n", label, directory.display()));
+ if directory.exists() {
+ status_message.push_str(&format!("{} directory exists.\n", label));
+ if fs::read_dir(&directory).is_ok() {
+ status_message.push_str(&format!("{} directory is readable.\n", label));
+ } else {
+ status_message.push_str(&format!("{} directory is not readable.\n", label));
+ }
+ } else {
+ status_message.push_str(&format!("{} directory does not exist.\n", label));
+ }
+
+ status_message
+}
--- /dev/null
+mod configuration_status;
+
+use std::io::Result;
+
+pub struct Status;
+
+impl Status {
+ pub fn new() -> Self {
+ Status
+ }
+}
+
+impl super::Command for Status {
+ fn before_dependencies(&self) -> Vec<Box<dyn super::Command>> {
+ vec![]
+ }
+
+ fn execute(&self, _: Option<&String>) -> Result<()> {
+ let status_providers = available_status_providers();
+ for status_provider in status_providers {
+ println!("{}", status_provider());
+ }
+ return Ok(())
+ }
+
+ fn after_dependencies(&self) -> Vec<Box<dyn super::Command>> {
+ vec![]
+ }
+
+ fn command(&self) -> &'static str {
+ "status"
+ }
+
+ fn help(&self) -> &'static str {
+ "\t\t\t\tPrints the status of your blog"
+ }
+}
+
+fn available_status_providers() -> Vec<fn() -> String> {
+ vec![
+ configuration_status::status,
+ ]
+}
use std::io::Result;
+use super::{sync_down::SyncDown, generate::Generate, sync_up::SyncUp};
pub struct Update;
impl super::Command for Update {
fn before_dependencies(&self) -> Vec<Box<dyn super::Command>> {
- vec![]
+ vec![Box::new(SyncDown::new())]
}
fn execute(&self, input: Option<&String>) -> Result<()> {
}
fn after_dependencies(&self) -> Vec<Box<dyn super::Command>> {
- vec![]
+ vec![
+ Box::new(Generate::new()),
+ Box::new(SyncUp::new())
+ ]
}
fn command(&self) -> &'static str {
vec![]
}
- fn execute(&self, input: Option<&String>) -> Result<()> {
- println!("Version: {:?}!", input);
+ fn execute(&self, _: Option<&String>) -> Result<()> {
+ let version = env!("CARGO_PKG_VERSION");
+ println!("{}", version);
return Ok(())
}
mod configuration;
mod command;
+use std::iter::once;
use std::env::args;
use std::io::Result;
-use configuration::Configuration;
use command::{available_commands, Command, help::Help};
fn main() -> Result<()> {
- let configuration = Configuration::new();
let commands = available_commands();
-
- println!("CONFIGURATION DIRECTORY: {}", configuration.config_directory.display());
- println!("DATA DIRECTORY: {}", configuration.data_directory.display());
- println!("OUTPUT DIRECTORY: {}", configuration.output_directory.display());
-
let arguments: Vec<String> = args().collect();
if let Some(command_name) = arguments.get(1) {
- if let Some(command) = commands.iter().find(|&c| c.command() == command_name) {
- return command.execute(arguments.get(2));
+ if let Some(main_command) = commands.into_iter().find(|c| c.command() == command_name) {
+ let before_commands = main_command.before_dependencies();
+ let after_commands = main_command.after_dependencies();
+
+ let command_chain: Vec<Box<dyn Command>> = before_commands
+ .into_iter()
+ .chain(once(main_command))
+ .chain(after_commands.into_iter())
+ .collect();
+
+ for command in command_chain {
+ let result = command.execute(arguments.get(2));
+ if let Err(_) = result {
+ return result;
+ }
+ }
+
+ return Ok(())
}
}