3 个不稳定版本

0.2.1 2021年10月7日
0.2.0 2021年10月5日
0.1.0 2021年9月30日

#2170命令行实用工具

每月42次下载
用于 sauce

Apache-2.0

24KB
361

Corpus: 集中组织,相对路径唯一性策略

license Version info Build Status

简介

Corpus 实现了一种相对简单的策略,用于集中组织文件(通常是 XDG 配置/数据),相对于某个根位置(通常是家目录),需要唯一的路径(通常对应于当前目录)。

最简单的解释可能是通过激励性示例项目: Sauce。Sauce(类似于 direnv)记录特定目录的环境变量(以及其他内容),以便您进入该目录后能够激活。

direnv 不同,包含此数据的文件不在本地的 .envrc 文件中,而是在中心组织。例如,如果您在 ~/projects/sauce,相应的数据路径将是

~/.local/share/sauce/projects/sauce.toml
|             |     |             |     |
+------+------+--+--+------+------+--+--+
       |         |         |         |
  XDG_DATA_DIR   |    relative path  |
              project             extension

相比之下,~/projects/ 将产生 ~/.local/share/sauce/projects.toml,而 ~/projects/sauce/src 将产生 ~/.local/share/sauce/projects/sauce/src.toml。本质上,这个想法是复制相同的本地文件夹结构...但是在其他地方!

为什么?

为什么你可能想这样做?在许多场景中,否则你会在文件夹中乱扔一大堆多余的(可能很大的!)文件,这些文件与你的 实际 文件混杂在一起。

对于 sauce,只需复制根位置即可轻松地将数据从一个计算机复制到另一个计算机: ~/.local/share/sauce。对于 direnv(如果您这样配置),这意味着复制 ~/.local/share/direnv。在我看来,这比搜索可能放置了一些配置/机密信息的所有潜在位置要好。

这也意味着您不必污染版本控制(如果您正在使用),以忽略使用 to 忽略特定于您的数据/机密。

CLI

可以使用 corpus CLI 命令交互式确定路径。这通常可以用来适应(适当可配置)的工具,使它们自己使用这种策略!

$ # Get the "corpus" path for the current directory
$ corpus --ext toml --kind xdg-data --name sauce
~/.local/share/x/y/z.toml

$ # Get the "corpus" path for a specific directory
$ corpus --ext toml --kind xdg-data --path <path> -n sauce
~/.local/share/<path>.toml

$ # Get the nearest ancestor directory that actually exists
$ corpus --ext toml --kind xdg-data --nearest -n sauce
~/.local/share/x/y.toml

$ # Get corresponding real path, given a data path
$ corpus --kind xdg-data --source-path --path ~/.local/share/x/y
~/x/y

安装

使用 Cargo

cargo install corpus --features=binary

下载版本

示例

中心 venv

function venv() {
  VENV_DIR=$(corpus --kind xdg-data --name venv)
  if [ ! -d "$VENV_DIR" ]; then
    python -m venv "$VENV_DIR"
  fi
  source "$VENV_DIR/bin/activate"
}

# At ~/projects/foo
venv
# Creates ~/.local/share/venv/projects/foo

# At ~/projects/project/subproject
venv
# Creates ~/.local/share/venv/projects/project/subprocess

中心 git

Git 允许您设置两个环境变量:GIT_DIR.git 目录)和 GIT_WORK_TREE(仓库根目录的位置)。

因此,您可以通过一点创意的 bash 脚本来(相对简单地)将所有 .git/ 文件夹集中存储。

export GIT_DIR=$(corpus --nearest -n git -e git)
export GIT_WORK_TREE=$(corpus --nearest --source-path -n git -e git)
  • 对于 GIT_DIR,我们希望使用 --nearest,这样,如果您在子目录中执行 cd,它将选择
  • 与最近的现有 Git 仓库相对应的文件。
  • 对于 GIT_WORK_TREE,我们也使用 --source-path 来回溯仓库根位置,给定数据的位置

仅凭这些本身并不完全可靠,因为如果只是将此放入您的 bashrc/zshrc,那么 git initgit clone 将会表现出一些奇怪的行为,但一点创意的 shell 脚本(欢迎 PR!)或别名应该能完成这项工作!

它还可以用作库,在实现自己的工具时使用此策略。

use std::path::PathBuf;
use corpus::{builder, RootLocation};

let corpus = builder()
    .with_root("/home/.config")
    .relative_to("/home")
    .with_name("project")
    .with_extension("toml")
    .build()
    .unwrap();

let result = corpus.path("/home/foo/bar");
assert_eq!(result, PathBuf::from("/home/.config/project/foo/bar.toml"));

同样,Sauce 利用此模式(和库)来为其数据文件使用此策略!

依赖项

~0.4–1.4MB
~25K SLoC