diff --git a/Cargo.lock b/Cargo.lock index a0402e5..8c07757 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,3 +3,57 @@ [[package]] name = "aur-helper" version = "0.1.0" +dependencies = [ + "rustc-serialize", + "toml-config", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +dependencies = [ + "log 0.4.11", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + +[[package]] +name = "toml" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796" +dependencies = [ + "rustc-serialize", +] + +[[package]] +name = "toml-config" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3de5e51a3b687866a2af93d043ff056f797b8c49e2d9d93376eeeaaf66682871" +dependencies = [ + "log 0.3.9", + "rustc-serialize", + "toml", +] diff --git a/Cargo.toml b/Cargo.toml index 2bd831c..3476044 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +toml-config = "0.4.0" +rustc-serialize = "0.3.24" \ No newline at end of file diff --git a/src/argument_parser.rs b/src/argument_parser.rs new file mode 100644 index 0000000..eb267eb --- /dev/null +++ b/src/argument_parser.rs @@ -0,0 +1,14 @@ +use std::env; + +pub struct Args { + pub(crate) operation: Option, + pub(crate) argument: Option +} + +pub fn get_argument_settings() -> Args { + let args: Vec = env::args().collect(); + Args { + operation: args.get(1).cloned(), + argument: args.get(2).cloned() + } +} \ No newline at end of file diff --git a/src/config_file_actions.rs b/src/config_file_actions.rs new file mode 100644 index 0000000..203d3e5 --- /dev/null +++ b/src/config_file_actions.rs @@ -0,0 +1,80 @@ +extern crate rustc_serialize; +extern crate toml_config; + +use std::path::Path; +use toml_config::ConfigFactory; +use std::fs::{create_dir_all, OpenOptions}; +use std::{env, io}; +use std::io::{ErrorKind, Write}; + +#[derive(RustcEncodable, RustcDecodable)] +pub struct Config { + pub nested: NestedConfig +} + +// Defaults will be used for missing/invalid configurations in the TOML config file +impl Default for Config { + fn default() -> Config { + Config { + nested: NestedConfig::default() + } + } +} + +impl Config { + const PATH: &'static str = "config.toml"; + + fn serialize(&self) -> String { + format!("[nested]\ninstall_directory = \"{}\"\ninstalled_packages = [\"{}\"]", self.nested.install_directory, self.nested.installed_packages.to_owned().join("\",\"")) + } + + pub fn write(&self) -> Result<(), io::Error> { + let path_string = Config::PATH; + let path = Path::new(path_string); + if path.exists() && !path.is_file() { + Err(io::Error::new(ErrorKind::InvalidInput, format!("The given path is not a file: {}", path_string).as_str())) + } else { + let dir = path.parent().expect(format!("Config path does not have a parent directory: {}", path_string).as_str()); + + create_dir_all(dir).expect(format!("Could not create directory {}", dir.display()).as_str()); + + let mut config_buffer = OpenOptions::new() + .write(true) + .truncate(true) + .open(path) + .unwrap(); + + config_buffer.write_all(self.serialize().as_bytes()).expect(format!("Could not write to config file {}", path_string).as_str()); + Ok(()) + } + } +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct NestedConfig { + pub install_directory: String, + pub installed_packages: Vec +} + +impl Default for NestedConfig { + fn default() -> NestedConfig { + NestedConfig { + install_directory: "~/.cache/aur-helper/packages".to_owned(), + installed_packages: Vec::new() + } + } +} + +pub fn load_config() -> Config { + let cfg: Config = ConfigFactory::load(Path::new(Config::PATH)); + let home_env = env::var("HOME").expect("Could not find HOME environment variable."); + let relative_home_dir = home_env.as_str(); + let absolute_home_dir = cfg.nested.install_directory.replace("~", relative_home_dir); + let package_path = Path::new(absolute_home_dir.as_str()); + + create_dir_all(package_path).expect(format!("Could not create package directory {}", package_path.display()).as_str()); + + cfg.write().expect("Cannot write configuration to file"); + + cfg +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e7a11a9..ce14aa8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,47 @@ +use crate::argument_parser::get_argument_settings; +use crate::config_file_actions::Config; + +mod config_file_actions; +mod argument_parser; +mod ops; + fn main() { - println!("Hello, world!"); + let args = get_argument_settings(); + + let mut cfg: Config = config_file_actions::load_config(); + println!("{}", cfg.nested.install_directory); + println!("{:?}", cfg.nested.installed_packages); + + if let Some(operation) = args.operation { + let argument = args.argument; + + match operation.to_lowercase().as_str() { + "install" => { + require_argument(&argument); + ops::install(argument.unwrap()); + }, + "list" => { + ops::list_installed(); + }, + "update" => { + require_argument(&argument); + ops::update(argument.unwrap()); + }, + "remove" => { + require_argument(&argument); + ops::remove(argument.unwrap()); + } + _ => { + ops::help(); + } + } + } else { + ops::help(); + } } + +fn require_argument(argument: &Option) { + if argument.is_none() { + panic!("This option requires an additional argument."); + } +} \ No newline at end of file diff --git a/src/ops.rs b/src/ops.rs new file mode 100644 index 0000000..94a5d5c --- /dev/null +++ b/src/ops.rs @@ -0,0 +1,19 @@ +pub fn install(argument: String) { + println!("Argument: {}", argument); +} + +pub fn list_installed() { + println!("Here's packages!"); +} + +pub fn update(argument: String) { + println!("Argument: {}", argument); +} + +pub fn remove(argument: String) { + println!("Argument: {}", argument); +} + +pub fn help() { + println!("Help!"); +} \ No newline at end of file