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;
|
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 crate::config::config::Config;
|
||||||
use std::fs::{create_dir_all, DirBuilder, File};
|
use std::fs::{DirBuilder, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct InitArgs {}
|
pub struct InitArgs {}
|
||||||
@ -32,7 +32,7 @@ pub fn exec(_: InitArgs, config: Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut binding = DirBuilder::new();
|
let mut binding = DirBuilder::new();
|
||||||
let mut builder = binding.recursive(true);
|
let builder = binding.recursive(true);
|
||||||
|
|
||||||
for dir in &["objects", "refs"] {
|
for dir in &["objects", "refs"] {
|
||||||
path.push(dir);
|
path.push(dir);
|
||||||
|
@ -1,20 +1,58 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `execution_path`: path of the command (directory arg) or current path
|
/// * `execution_path`: path of the command (directory arg) or current path
|
||||||
|
/// * `root`: path of the repo
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub execution_path: PathBuf,
|
pub execution_path: PathBuf,
|
||||||
|
root: OnceLock<Option<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(exec_path: Option<&String>) -> Self {
|
pub fn new() -> Self {
|
||||||
Config {
|
Config {
|
||||||
execution_path: match exec_path {
|
execution_path: PathBuf::from(env::current_dir().unwrap()),
|
||||||
Some(path) => PathBuf::from(path),
|
root: OnceLock::new(),
|
||||||
None => PathBuf::from(env::current_dir().unwrap()),
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 commands;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod store;
|
||||||
mod subcommands;
|
mod subcommands;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -9,13 +10,14 @@ fn main() {
|
|||||||
.version("1.0")
|
.version("1.0")
|
||||||
.author("grimhilt")
|
.author("grimhilt")
|
||||||
.about("A git-line command line tool to interact with nextcloud")
|
.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);
|
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||||
|
|
||||||
let matches = app.get_matches();
|
let matches = app.get_matches();
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
Some(("init", args)) => subcommands::init::handler(args),
|
Some(("init", args)) => subcommands::init::handler(args),
|
||||||
|
Some(("add", args)) => subcommands::add::handler(args),
|
||||||
Some((_, _)) => {}
|
Some((_, _)) => {}
|
||||||
None => {}
|
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;
|
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) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
let exec_dir = args.get_one::<String>("directory");
|
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