ReBackup program

ReBackup is a simple backup program that doesn't actually create backups but instead creates a list of files to backup from a source directory.

It uses a walker to traverse filesystem items, which can be customized through rules (see [WalkerRule]).

Its main features are:

ReBackup can be used either:

Library usage

ReBackup only exports one single function which is the Walker: walk.

It can be used like this:

```rust use std::path::PathBuf; use rebackup::{fail, walk, WalkerConfig};

let source = std::env::args().nth(1) .unwraporelse(|| fail!(exit 1, "Please provide a source directory"));

// NOTE: This can be shortened to WalkerConfig::new(vec![]) // (expanded here for explanations purpose) let config = WalkerConfig { rules: vec![], followsymlinks: false, dropempty_dirs: false, };

let fileslist = walk(&PathBuf::from(source), &config) .unwrapor_else(|err| fail!(exit 2, "Failed to build the files list: {}", err));

let filesliststr: Vec<_> = fileslist .iter() .map(|item| item.tostring_lossy()) .collect();

println!("{}", filesliststr.join("\n")); ```

Rules

You can use powerful rules to configure how the walker behaves.

A rule is defined using [WalkerRule], and uses two callbacks:

Here is a basic rule excluding all directories containing .nomedia files:

```rust use rebackup::config::*;

let rule = WalkerRule { // Name of the rule name: "nomedia",

// Optional description of the rule
description: None,

// The type of items the rule applies to (`None` for all)
only_for: Some(WalkerItemType::Directory),

// Check if the rule would match a specific item
matches: Box::new(|path, _, _| path.join(".nomedia").is_file()),

// Apply the rule to determine what to do
action: Box::new(|_, _, _| Ok(WalkerRuleResult::ExcludeItem)),

}; ```

You can also build more powerful rules, like excluding files ignored by Git:

```rust use std::env; use std::process::Command; use rebackup::config::*;

let rule = WalkerRule { name: "gitignore", description: None, onlyfor: None, matches: Box::new(|path, _, _| path.ancestors().any(|path| path.join(".git").isdir())), action: Box::new(|dir, , _| { let cwd = env::currentdir()?;

    if dir.is_dir() {
        env::set_current_dir(dir)?;
    } else if let Some(parent) = dir.parent() {
        env::set_current_dir(parent)?;
    }

    let is_excluded = Command::new("git")
        .arg("check-ignore")
        .arg(dir.to_string_lossy().to_string())
        .output();

    // Restore the current directory before returning eventual error from the command
    env::set_current_dir(cwd)?;

    if is_excluded?.status.success() {
        Ok(WalkerRuleResult::ExcludeItem)
    } else {
        Ok(WalkerRuleResult::IncludeItem)
    }
}),

}; ```

You can check more examples of rules in examples/rules.rs.

Command-line usage

```shell

Build the list of files to backup, and pipe it to 'tar'

to create a compressed archive

Be aware of not creating the archive inside the directory to backup, or the archive

will be listed as well (you can still exclude it from the results afterwards)

rebackup pathtobackup/ | tar -czf output.tgz -T -

If you are in another directory, ask for absolute paths instead

Please note that the archive's content will have absolute paths as well

rebackup pathtobackup/ -a | tar -czf output.tgz -T -

Using filters to exclude items based on patterns

Here we're excluding all items ignored by the '.gitignore' file in Git repositories

rebackup pathtobackup/ -f '! git check-ignore "$REBACKUP_ITEM"'

To also exclude the ".git" folder (using glob pattern):

rebackup pathtobackup/ -f '! git check-ignore "$REBACKUP_ITEM"' -e '**/.git'

Use an alternate shell:

rebackup pathtobackup/ -f '! git check-ignore "$REBACKUP_ITEM"' --shell zsh --shell-head-args=-c

To list all available arguments:

rebackup --help ```

License

This project is released under the Apache-2.0 license terms.