3个不稳定版本
0.2.0 | 2024年6月8日 |
---|---|
0.1.1 | 2024年5月11日 |
0.1.0 | 2024年5月10日 |
#119 in 配置
24KB
208 行
Allenap的Unison配置生成器
这帮助我生成我的Unison配置文件。
背景
Unison执行双向文件同步。我编写一个配置文件,运行unison name-of-config-file
,然后Unison在这里和那里之间同步文件。那里可以是另一个目录,也可以是通过SSH可访问的另一个机器。这通常是它的用途。
我有几台机器需要同步。我没有作为真相来源的中央服务器,所以我通常从几台不同的机器来回同步。有一天,我会在机器A上运行unison
以同步到机器B,另一天我会进行反向操作,然后也同步到机器C,以及这些的组合。因此,我想要每台机器上都有相同的配置——所以我使用Unison本身来同步这些配置文件。
我还想同步不同的集合的文件。我想将dotfiles同步到我的云服务器上,但不是我的财务记录。我想将我的编码项目在我的笔记本电脑和我的桌子下的Linux机器之间同步,但不是我的照片。
操作原理
此脚本接受一个配置文件——从stdin读取——描述我拥有的所有主机。例如
# schemes.yaml
hosts:
alice:
hostname: alice.example.com
home: /home/gavin
sets:
- common
- financial
- github
bob:
hostname: bob.example.org
home: /Users/gavin
sets:
- common
- github
- photos
carol:
hostname: carol.example.net
home: /home/gavin
sets:
- common
- financial
- photos
此配置文件描述了三个主机——alice、bob和carol——以及每个主机同步的文件集合。
当我将unison-confgen < schemes.yaml
在alice上运行时,将生成两个配置文件
alice-bob.prf
alice-carol.prf
这些包含标准Unison配置指令,以在主机之间同步具有共同文件的集合。
现在我可以输入unison alice-bob
或unison alice-carol
来
- 在alice和bob之间同步
common
和github
集合 - 同步 Alice 和 Carol 之间的
common
和financial
集合。
同样,Bob 将拥有 bob-alice.prf
和 bob-carol.prf
,而 Carol 将拥有 carol-alice.prf
和 carol-bob.prf
。
集合里有什么内容?
集合文件位于 sets
子目录中。它的名字与集合名完全相同,没有文件扩展名。它包含 Unison 配置指令。它不必描述一组文件,但通常可能看起来像
# sets/github
path = GitHub
ignore = Regex GitHub/.*/target
ignore = Name .overmind.sock
路径,如上例中的 GitHub
,是相对于 schemes.yaml
中的 home
设置解析的。
这些集合文件在生成的配置文件中以原始形式包含,但增加了一项:可以使用 include
指令来包含另一个集合文件
# sets/all-code
include github
include gitlab
include projects
用法
我将 unison-confgen
二进制文件放在 PATH
上——通常是因为我已使用 cargo install
来安装它,Cargo 的 bin
目录已经在我的 PATH
上。
然后,在 ~/.unison
中,我有 etc/schemes.yaml
配置文件,一个 sets
子目录和一个 Makefile
来驱动它
.PHONY: all
all: clean gen
.PHONY: gen
gen:
@type unison-confgen >/dev/null || cargo install allenap-unison-confgen
unison-confgen < etc/schemes.yaml
.PHONY: clean
clean:
@$(RM) $(wildcard *.prf)
.PHONY: complete
complete: clean gen
@echo $(basename $(wildcard *.prf))
运行 make -C ~/.unison
会清除所有 .prf
文件并重新生成它们。
complete
目标对于 shell 完成非常有用。我在 ~/.bashrc
中的 Bash 中使用了以下代码
# Unison stuff
# shellcheck disable=SC2317
_unison() {
local cur words
# The current word due for completion.
cur=${COMP_WORDS[COMP_CWORD]}
# Non-local array storing the possible completions.
COMPREPLY=()
case "${cur}" in
-*)
words="$(unison -help | awk '/^ -/ { print $1 }')"
;;
*)
words="$(make -sC ~/.unison complete)"
;;
esac
mapfile -t COMPREPLY < <(compgen -W "${words}" -- "${cur}")
return 0
}
for _unison in $(compgen -c unison)
do
complete -F _unison "$_unison"
done
unset _unison
# Override local hostname. Useful when WiFi publishes a different
# local domain (<cough>FritzBox</cough>), for example.
if [ -f ~/.unison/hostname ]
then
read -r UNISONLOCALHOSTNAME < ~/.unison/hostname &&
export UNISONLOCALHOSTNAME
fi
这就全部了。它简单但有效;我已经使用它好几年了。最近我用 Rust(从 Python)重写了它,这是第一次发布。由于它满足了我的所有需求,我可能不会在上面做太多工作。好吧,也许在雨天我
- 添加一个合适的命令行解析器;
- 将 shell 完成代码移入 Rust 二进制文件;
- 消除对那个
Makefile
的需要。
但我不会抱太大的希望。
祝您玩得开心!
许可证
GNU 通用公共许可证 3.0(或更高版本)。请参阅 LICENSE。
依赖项
~2–26MB
~381K SLoC