#backup #filter #rule #list #system #directory #walker

bin+lib rebackup

一个只使用强大规则系统构建备份文件列表的备份软件

3个稳定版本

1.0.2 2021年3月8日

#13#walker

Apache-2.0

40KB
525

ReBackup程序

ReBackup是一个简单的备份程序,它实际上并不创建备份,而是从源目录创建要备份的文件列表。

它使用walker来遍历文件系统项,可以通过规则进行自定义(见 WalkerRule)。

其主要功能包括:

  • 快速递归目录遍历
  • 强大的规则系统以包含、排除或重映射项
  • 处理符号链接(需要启用walker的选项)
  • 检测已访问的路径
  • 命令行界面

ReBackup可以使用以下方式之一使用:

  • 作为库(见 walk
  • 作为具有cli功能的独立二进制文件

库使用

ReBackup只导出一个函数,即Walker: walk

它可以使用如下方式:

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

let source = std::env::args().nth(1)
    .unwrap_or_else(|| 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![],
    follow_symlinks: false,
    drop_empty_dirs: false,
};

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

let files_list_str: Vec<_> = files_list
    .iter()
    .map(|item| item.to_string_lossy())
    .collect();

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

规则

您可以使用强大的规则来配置walker的行为。

规则使用 WalkerRule 定义,并使用两个回调

  • 一个用于确定规则是否适用于特定项
  • 一个用于运行规则本身

以下是一个基本的规则,排除包含 .nomedia 文件的目录

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)),
};

您也可以构建更强大的规则,如排除Git忽略的文件

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

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

        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)
        }
    }),
};

您可以在 examples/rules.rs 中查看更多规则的示例。

命令行使用

# 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 path_to_backup/ | 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 path_to_backup/ -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 path_to_backup/ -f '! git check-ignore "$REBACKUP_ITEM"'

# To also exclude the ".git" folder (using glob pattern):
rebackup path_to_backup/ -f '! git check-ignore "$REBACKUP_ITEM"' -e '**/.git'

# Use an alternate shell:
rebackup path_to_backup/ -f '! git check-ignore "$REBACKUP_ITEM"' --shell zsh --shell-head-args=-c

# To list all available arguments:
rebackup --help

许可证

本项目根据 Apache-2.0 许可协议发布。

依赖

~0.3–1MB
~22K SLoC