feat(add): start add logic and ignorer
This commit is contained in:
parent
2364cadfd5
commit
fb57bd6565
@ -1 +1,2 @@
|
||||
pub mod add;
|
||||
pub mod init;
|
||||
|
59
src/commands/add.rs
Normal file
59
src/commands/add.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use crate::config::config::Config;
|
||||
use crate::store::ignorer::Ignorer;
|
||||
// use crate::store::object::object::{Obj, ObjMethods};
|
||||
// use crate::store::{self, object::Object};
|
||||
// use crate::utils::nextsyncignore::{self, ignore_file};
|
||||
// use crate::utils::path::{normalize_relative, path_buf_to_string, repo_root};
|
||||
// use crate::utils::{self, path};
|
||||
// use glob::glob;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct AddArgs {
|
||||
/// List of files/dirs to add
|
||||
pub files: Vec<String>,
|
||||
/// Allow ignored files
|
||||
pub force: bool,
|
||||
/// Select all files
|
||||
pub all: bool,
|
||||
}
|
||||
|
||||
pub fn exec(args: AddArgs, config: Config) {
|
||||
// Init ignorer
|
||||
let mut ignorer = Ignorer::new(config.get_root_unsafe());
|
||||
ignorer.active_nsignore(!args.force);
|
||||
|
||||
if args.all {
|
||||
return add_dir(config.get_root_unsafe(), &mut ignorer);
|
||||
}
|
||||
|
||||
/*
|
||||
for all files
|
||||
if globbing
|
||||
take all match glob nextsyncignore
|
||||
else
|
||||
if dir
|
||||
add dir
|
||||
add all childs with nextsyncignore
|
||||
else
|
||||
add files
|
||||
*/
|
||||
}
|
||||
|
||||
/// Add all files in a directory
|
||||
///
|
||||
/// # Parameters
|
||||
/// * `dir`: the directory to add from
|
||||
/// * `force`: true if we should apply the nextsyncignore's rules
|
||||
fn add_dir(dir: &PathBuf, ignorer: &mut Ignorer) {
|
||||
/*
|
||||
for elements present in dir {
|
||||
if !force && should_ignore() {
|
||||
continue;
|
||||
}
|
||||
if is dir
|
||||
add_dir(new_dir, force)
|
||||
else
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::config::config::Config;
|
||||
use std::fs::{create_dir_all, DirBuilder, File};
|
||||
use std::fs::{DirBuilder, File};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct InitArgs {}
|
||||
@ -32,7 +32,7 @@ pub fn exec(_: InitArgs, config: Config) {
|
||||
}
|
||||
|
||||
let mut binding = DirBuilder::new();
|
||||
let mut builder = binding.recursive(true);
|
||||
let builder = binding.recursive(true);
|
||||
|
||||
for dir in &["objects", "refs"] {
|
||||
path.push(dir);
|
||||
|
@ -1,20 +1,58 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
///
|
||||
/// # Parameters
|
||||
/// * `execution_path`: path of the command (directory arg) or current path
|
||||
/// * `root`: path of the repo
|
||||
pub struct Config {
|
||||
pub execution_path: PathBuf,
|
||||
root: OnceLock<Option<PathBuf>>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(exec_path: Option<&String>) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Config {
|
||||
execution_path: match exec_path {
|
||||
Some(path) => PathBuf::from(path),
|
||||
None => PathBuf::from(env::current_dir().unwrap()),
|
||||
execution_path: PathBuf::from(env::current_dir().unwrap()),
|
||||
root: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(exec_path: Option<&String>) -> Self {
|
||||
match exec_path {
|
||||
Some(path) => Config {
|
||||
execution_path: PathBuf::from(path),
|
||||
root: OnceLock::new(),
|
||||
},
|
||||
None => Config::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_root(&self) -> &Option<PathBuf> {
|
||||
self.root.get_or_init(|| {
|
||||
let mut path = self.execution_path.clone();
|
||||
|
||||
let root = loop {
|
||||
path.push(".nextsync");
|
||||
if path.exists() {
|
||||
path.pop();
|
||||
break Some(path);
|
||||
}
|
||||
path.pop();
|
||||
path.pop();
|
||||
if path == Path::new("/") {
|
||||
break None;
|
||||
}
|
||||
};
|
||||
root
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_root_unsafe(&self) -> &PathBuf {
|
||||
match self.get_root() {
|
||||
Some(path) => path,
|
||||
None => panic!("fatal: not a nextsync repository (or any parent up to mount point /)"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use clap::Command;
|
||||
|
||||
mod commands;
|
||||
mod config;
|
||||
mod store;
|
||||
mod subcommands;
|
||||
|
||||
fn main() {
|
||||
@ -9,13 +10,14 @@ fn main() {
|
||||
.version("1.0")
|
||||
.author("grimhilt")
|
||||
.about("A git-line command line tool to interact with nextcloud")
|
||||
.subcommands([subcommands::init::create()]);
|
||||
.subcommands([subcommands::init::create(), subcommands::add::create()]);
|
||||
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||
|
||||
let matches = app.get_matches();
|
||||
|
||||
match matches.subcommand() {
|
||||
Some(("init", args)) => subcommands::init::handler(args),
|
||||
Some(("add", args)) => subcommands::add::handler(args),
|
||||
Some((_, _)) => {}
|
||||
None => {}
|
||||
};
|
||||
|
2
src/store.rs
Normal file
2
src/store.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod ignorer;
|
||||
pub mod nsignore;
|
53
src/store/ignorer.rs
Normal file
53
src/store/ignorer.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use crate::store::nsignore::{get_nsignore_file, get_nsignore_rules, is_file_ignored};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
pub struct Ignorer {
|
||||
/// Path of this level
|
||||
path: PathBuf,
|
||||
/// Should it use the nextsyncignore file
|
||||
use_nsignore: bool,
|
||||
/// Nsignore's rules
|
||||
rules: OnceLock<Vec<String>>,
|
||||
childs: Option<Vec<Box<Ignorer>>>,
|
||||
}
|
||||
|
||||
impl Ignorer {
|
||||
pub fn new(path: &PathBuf) -> Self {
|
||||
Ignorer {
|
||||
path: path.to_path_buf(),
|
||||
use_nsignore: true,
|
||||
rules: OnceLock::new(),
|
||||
childs: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn active_nsignore(&mut self, active: bool) {
|
||||
self.use_nsignore = active;
|
||||
}
|
||||
|
||||
fn get_rules(&mut self) -> &Vec<String> {
|
||||
self.rules
|
||||
.get_or_init(|| match get_nsignore_file(&self.path) {
|
||||
Some(nsignore_path) => get_nsignore_rules(&nsignore_path),
|
||||
None => Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns whether a file/dir is ignored or not
|
||||
///
|
||||
/// * `path`:
|
||||
fn is_ignored(&mut self, path: PathBuf) -> bool {
|
||||
is_file_ignored(path.to_str().unwrap(), self.get_rules())
|
||||
}
|
||||
|
||||
/// Returns whether a file/dir should be ignored by the program or not
|
||||
///
|
||||
/// This takes advantage of the `use_nsignore` variable set by
|
||||
/// `active_nsignore`.
|
||||
///
|
||||
/// * `path`:
|
||||
pub fn should_ignore(&mut self, path: PathBuf) -> bool {
|
||||
self.use_nsignore && self.is_ignored(path)
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod add;
|
||||
pub mod init;
|
||||
|
46
src/subcommands/add.rs
Normal file
46
src/subcommands/add.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
|
||||
use crate::commands;
|
||||
use crate::commands::add::AddArgs;
|
||||
use crate::config::config::Config;
|
||||
|
||||
pub fn create() -> Command {
|
||||
Command::new("add")
|
||||
.arg(
|
||||
Arg::new("files")
|
||||
.required_unless_present("all")
|
||||
.conflicts_with("all")
|
||||
.num_args(1..)
|
||||
.value_name("FILE")
|
||||
.help("Files to add"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("force")
|
||||
.short('f')
|
||||
.long("force")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Allow adding otherwise ignored files."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("all")
|
||||
.short('A')
|
||||
.long("all")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("This adds, modifies, and removes index entries to match the working tree"),
|
||||
)
|
||||
.about("Add changes to the index")
|
||||
}
|
||||
|
||||
pub fn handler(args: &ArgMatches) {
|
||||
commands::add::exec(
|
||||
AddArgs {
|
||||
files: match args.get_many::<String>("files") {
|
||||
None => vec![],
|
||||
Some(vals) => vals.map(|s| s.to_string()).collect(),
|
||||
},
|
||||
force: *args.get_one::<bool>("force").unwrap(),
|
||||
all: *args.get_one::<bool>("all").unwrap(),
|
||||
},
|
||||
Config::new(),
|
||||
);
|
||||
}
|
@ -16,5 +16,5 @@ pub fn create() -> Command {
|
||||
|
||||
pub fn handler(args: &ArgMatches) {
|
||||
let exec_dir = args.get_one::<String>("directory");
|
||||
commands::init::exec(commands::init::InitArgs {}, Config::new(exec_dir));
|
||||
commands::init::exec(commands::init::InitArgs {}, Config::from(exec_dir));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user