1# @Language: Markdown
2# @Software: VS Code
3# @Author  : Di Wang
4# @Email   : [email protected]

dotfiles管理

什么是dotfiles? 参见https://wiki.archlinux.org/title/Dotfiles. 很多配置文件会以dot开头, 这些文件被称为dotfile. 如果我们经常在多台机器上工作, 这些机器往往有不同的硬件和操作系统, 我们会希望在不同的机器上使用同样的配置, 例如使用同样的shell快捷键, terminal有同样的UI, 因此如何在不同的机器之间同步与安装dotfiles的需求就应运而生.

常用的dotfiles

  • shell, .zshrc, .tcshrc, .bashrc
  • Editor, .vimrc
  • WM/DE, i3, sway, awesome
  • Multipler, .tmux.conf or .screenrc
  • Terminal, alacritty.toml or kitty
  • git, .gitconfig

dotfiles需要放到指定的位置才会生效, 最常用的是${HOME}目录, 但如果软件依据XDG标准来读取自己的配置文件, 也可以放到XDG_CONFIG_HOME目录, 默认为$HOME/.config目录.

需求

  • 可以选择某个机器安装哪些dotfiles. 例如一些机器上只需要安装.zshrc, 而有些只能使用tcshbash.
  • 安装完dotfile后可以执行脚本, 比如安装完.zshrc会自动安装zsh插件和theme
  • 一些环境需要设置proxy server
  • 一些配置依赖于软件版本, 比如tmux旧版本不支持一些配置, git新版本引入了某配置, 需要根据安装机器的软件环境来自动决定
  • 可以自动判断操作系统的架构(例如darwin-x64, linux-arm), 然后设置对应的EPICS_HOST_ARCH

dotdrop

前段中的arch wiki页面中列出了一些dotfiles管理软件, 我个人使用dotdrop. 官方文档地址dotdrop.readthedocs.io dotdrop使用python编写, 目前版本也支持使用apt brew 和pip直接安装. 但我依然沿用早期的git submodule方式使用. 下面的例子摘自官方文档, 我个人的使用方式参见my dotfiles, 因为不希望自动更新submodule, 所以我对启动程序做了一些微小修改.

安装

 1## create the repository
 2$ mkdir dotfiles; cd dotfiles
 3$ git init
 4
 5## install dotdrop as a submodule
 6$ git submodule add https://github.com/deadc0de6/dotdrop.git
 7$ pip3 install --user -r dotdrop/requirements.txt
 8$ ./dotdrop/bootstrap.sh
 9
10## use dotdrop
11$ ./dotdrop.sh --help

基础使用

dotdrop使用config.yaml作为默认配置文件, 不过鉴于YAML的劣势, 将来应该会顺应潮流升级为TOML格式.

dotdrop的基本理念把dotfiles放到git repo中进行统一管理, 在config.yaml文件中指定dotfiles的git repo内的路径和系统安装路径, 其中src, 就是git repo中的路径(可以在config.yaml修改), 然后dst是dotfiles的安装路径. 运行dotdrop时, 就会读取git repo中的dotfiles, 然后做一些修改, 之后安装到系统某个路径. 安装路径应该依据软件来选择, 例如vim配置文件需要放到~/.vimrc.

 1config:
 2  backup: true
 3  banner: true
 4  create: true
 5  dotpath: dotfiles
 6dotfiles:
 7  d_polybar:
 8    dst: ~/.config/polybar
 9    src: config/polybar
10  f_vimrc:
11    dst: ~/.vimrc
12    src: vimrc
13  f_xinitrc:
14    dst: ~/.xinitrc
15    src: xinitrc
16profiles:
17  home:
18    dotfiles:
19    - f_vimrc
20    - f_xinitrc
21    - d_polybar

另一个概念是profile, 每一个profile中包含了多个dotfiles, 基本来说是以host来区分, 即某个host上使用的bash和vim, 那这个profile就需要包含bash和vim这两个dotfiles. 当然也可以不以hostname来区分, 如果多个host可共用一套配置, 那就可以用别的命名, 比如vps等.

1$ dotdrop profiles #列出配置文件中定义的profiles, 比如profileA profileB
2$ dotdrop install -p profileA # 安装指定的profile
3$ dotdrop compare -p profileA # 对比profileA和已安装的dotfiles
4$ dotdrop files -p profileA # 列出profileA中的dotfiles

它也支持直接导入dotfile, 可以使用dotdrop import命令, 但我不使用.

还有一些概念包括variables和actions. variables就是一些变量, 在config.yaml中设置之后, 可以在各个dotfile中使用, 会被profile中的局部同名variable覆盖. actions就是一段shell程序, 会被Python调用执行, 比如可以安装某些依赖. actions可以设置执行的时机(安装dotfiles之前或之后). 可以设置某些actions为default_actions, 这样每安装一个dotfile就会执行一次(用于log). 不过更常用的是在某个dotfile中使用某个action, 比如安装.vimrc时, 执行action安装Vim插件.

配置文件

dotdrop的config.yaml文件有多个层级(官方称为block), 每个层级都有自己的配置项.

  • config, 一些全局配置项, 比如git repo中的dotfiles路径, 在安装时是否创建backup文件等
  • dotfiles, 核心, 定义dotfiles, 设置安装后的文件权限等
  • profiles, 可以include其他profile, 可以设定局部variables, 设定要执行的actions
  • actions, 定义action, 执行一段程序. 通常是单行命令, 也可以调用某个shell脚本文件.
  • variables, 定义variable
  • dynvariables, 也是定义variable, 不过它的值来源于一段shell程序的输出结果, 方便我们动态判断运行环境, 比如确定git的版本.
  • uservariables, 也是定义variable, 不过会在要求用户输入来确定值. 方便处理一些敏感信息
  • transformations, 官方给的用例有两种, 一种是处理需要压缩和解压缩的文件, 另一种是用pgp加密和解密文件. 这样就可以把.ssh之类的敏感文件加密后管理起来.

具体使用参考官方文档.

高级用法

高级用法依赖于jinja2, 可以在dotfiles中使用template, 由dotdrop进行替换, template中可以使用variable, 也可以使用一些条件逻辑. 常用使用方式如下. 一看就会.

example1

判断profile的名字, 如果是wsl, 那就把~/.local/bin加入到PATH

1{%@@ if profile == "wsl" @@%}
2export  PATH="{{@@ HOME @@}}/.local/bin:${PATH}"
3{%@@ endif @@%}

example2

config.yaml中有两个variable: USE_PROXYPROXY, 首先判断 USE_PROXY 的值, 如果为YES, 那就添加两个alias, 可以设置proxy server, proxy server的IP也是通过template解析出来的. 一般是首先全局定义USE_PROXYNO, 然后在某个profile中覆盖为YES.

1{%@@ if USE_PROXY == "YES" @@%}
2alias setproxy="export http_proxy=http://{{@@ PROXY @@}}; export https_proxy=https://{{@@ PROXY @@}}"
3alias noproxy="unset http_proxy; unset https_proxy"
4{%@@ endif @@%}

example3

判断git的版本, 如果大于2.13, 就在.gitconfig中添加一项配置. 这样的话在一些git版本为1.8的旧机器上, 这个额外的配置就不会产生.

1{%@@ if GIT_VERSION >= "2.13" @@%}
2# The contents of this file are included only for GitLab.com URLs
3[includeIf "hasconfig:remote.*.url:git@**gitlab**:**/**"]
4        # Edit this line to point to your alternative configuration file
5        path = ~/.gitconfig-gitlab
6{%@@ endif @@%}

其中GIT_VERSION是一个dynvariable, 在config.yaml中定义:

1dynvariables:
2  GIT_VERSION: git --version | cut -f 3 -d " "