commit 5a70590eeec64f62a5c213ef62e30c8948681fca Author: grimhilt Date: Sat Aug 31 17:29:09 2024 +0200 feat(init): init command diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68402c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +* +!/**/ +!*.rs +!.gitignore +!README.md +!LICENSE + +target +tests/nextcloud-docker-dev +tests/data + diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..43763f1 --- /dev/null +++ b/src/commands.rs @@ -0,0 +1 @@ +pub mod init; diff --git a/src/commands/init.rs b/src/commands/init.rs new file mode 100644 index 0000000..6c9c00a --- /dev/null +++ b/src/commands/init.rs @@ -0,0 +1,48 @@ +use crate::config::config::Config; +use std::fs::{create_dir_all, DirBuilder, File}; +use std::path::PathBuf; + +pub struct InitArgs {} + +/// Creates the necessary files and directories for a nextsync repository. +/// +/// The following files and directories are created: +/// - `.nextsync/objects` +/// - `.nextsync/refs` +/// - `.nextsync/index` +/// - `.nextsync/HEAD` +/// +/// If the `execution_path` specified in the `config` does not exist, it will be created. +/// +/// # Panics +/// +/// This function will panic if it cannot create the mentioned files or directories. +pub fn exec(_: InitArgs, config: Config) { + let mut path: PathBuf = config.execution_path.clone(); + path.push(".nextsync"); + + if config.execution_path.exists() { + // Check the dir is not already a nextsync dir + if path.exists() { + panic!( + "{} is already a nextsync directory, cannot overwrite it!", + config.execution_path.display() + ); + } + } + + let mut binding = DirBuilder::new(); + let mut builder = binding.recursive(true); + + for dir in &["objects", "refs"] { + path.push(dir); + builder.create(&path).unwrap(); + path.pop(); + } + + for file in &["HEAD", "index"] { + path.push(file); + File::create(&path).unwrap(); + path.pop(); + } +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..ef68c36 --- /dev/null +++ b/src/config.rs @@ -0,0 +1 @@ +pub mod config; diff --git a/src/config/config.rs b/src/config/config.rs new file mode 100644 index 0000000..b409c2b --- /dev/null +++ b/src/config/config.rs @@ -0,0 +1,20 @@ +use std::env; +use std::path::PathBuf; + +/// +/// # Parameters +/// * `execution_path`: path of the command (directory arg) or current path +pub struct Config { + pub execution_path: PathBuf, +} + +impl Config { + pub fn new(exec_path: Option<&String>) -> Self { + Config { + execution_path: match exec_path { + Some(path) => PathBuf::from(path), + None => PathBuf::from(env::current_dir().unwrap()), + }, + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4ebf403 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,22 @@ +use clap::Command; + +mod commands; +mod config; +mod subcommands; + +fn main() { + let app = Command::new("Nextsync") + .version("1.0") + .author("grimhilt") + .about("A git-line command line tool to interact with nextcloud") + .subcommands([subcommands::init::create()]); + // .setting(clap::AppSettings::SubcommandRequiredElseHelp); + + let matches = app.get_matches(); + + match matches.subcommand() { + Some(("init", args)) => subcommands::init::handler(args), + Some((_, _)) => {} + None => {} + }; +} diff --git a/src/subcommands.rs b/src/subcommands.rs new file mode 100644 index 0000000..43763f1 --- /dev/null +++ b/src/subcommands.rs @@ -0,0 +1 @@ +pub mod init; diff --git a/src/subcommands/init.rs b/src/subcommands/init.rs new file mode 100644 index 0000000..f3f4ac5 --- /dev/null +++ b/src/subcommands/init.rs @@ -0,0 +1,20 @@ +use clap::{Arg, ArgMatches, Command}; + +use crate::commands; +use crate::config::config::Config; + +pub fn create() -> Command { + Command::new("init") + .arg( + Arg::new("directory") + .required(false) + .num_args(1) + .value_name("DIRECTORY"), + ) + .about("Create an empty Nextsync repository") +} + +pub fn handler(args: &ArgMatches) { + let exec_dir = args.get_one::("directory"); + commands::init::exec(commands::init::InitArgs {}, Config::new(exec_dir)); +}