feat(init): init command

This commit is contained in:
grimhilt 2024-08-31 17:29:09 +02:00
commit 5a70590eee
8 changed files with 124 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
*
!/**/
!*.rs
!.gitignore
!README.md
!LICENSE
target
tests/nextcloud-docker-dev
tests/data

1
src/commands.rs Normal file
View File

@ -0,0 +1 @@
pub mod init;

48
src/commands/init.rs Normal file
View File

@ -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();
}
}

1
src/config.rs Normal file
View File

@ -0,0 +1 @@
pub mod config;

20
src/config/config.rs Normal file
View File

@ -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()),
},
}
}
}

22
src/main.rs Normal file
View File

@ -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 => {}
};
}

1
src/subcommands.rs Normal file
View File

@ -0,0 +1 @@
pub mod init;

20
src/subcommands/init.rs Normal file
View File

@ -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::<String>("directory");
commands::init::exec(commands::init::InitArgs {}, Config::new(exec_dir));
}