183 lines
5.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# symlink.nu -- 软链接管理
#
# Copyright (C) 2022-2023 KAAAsS
use ../log.nu
use ../interactive.nu [confirm]
use global_conf.nu
use module.nu [filtered_modules]
# 获得链接的目标目录或目标文件的父目录
def get_base_dir [local: path, dest: path] {
let type = ($local | path type)
if ($type == dir) {
$dest
} else {
$dest | path dirname
}
}
# 声明文件及其目标路径
export def --env declare [
module: string, # 模块名称
local: any, # 本地路径,以项目根目录为起点的相对路径
dest: string, # 目标路径,以用户家目录为起点的相对路径
--local-only, # 是否是本地特有的文件。若文件不存在则会自动从 example 创建本地文件
] {
let type = ($local | describe)
let locals = if ($type == "list<string>") {
$local
} else {
[$local]
}
# 遍历 local 路径,获得映射
mut new_maps = []
for $local in $locals {
# 解析原文件路径为绝对路径
let local = ($local | path expand -n)
let dest = if ($type == "list<string>") {
# 对于文件列表(如 glob把文件名追加在最后
$dest | path join ($local | path basename)
} else {
$dest
}
log debug $"声明文件: ($module) : ($local) --> ($dest)"
$new_maps = ($new_maps | append [ { local: $local, dest: $dest } ])
# 若本地文件不存在,则根据模板创建本地文件
if ($local_only and (not ($local | path exists))) {
let template = $"($local).example"
if ($template | path exists) {
log debug $"创建本地文件: ($local)"
mkdir ($local | path dirname)
cp $template $local
} else {
error make {
msg: $"本地文件 ($local) 的模板不存在!配置有误!",
}
}
}
}
# 合并新映射并设置
let old_map = (global_conf get_config $module "file_map" null)
global_conf set_config $module "file_map" (
$old_map | append $new_maps
)
}
# 列出模块的文件信息
export def list_files [
modules?: list
] {
# 获取模块列表
let modules = (filtered_modules $modules)
# 增加文件信息
$modules | each { |$module|
let file_map = (global_conf get_config $module "file_map")
if ($file_map != null) {
# dest 相对路径转为绝对
let file_map = (
$file_map | each { |$it|
{
local: $it.local,
dest: ($env.HOME_DIR | path join $it.dest),
}
}
)
# 增加模块名列
[ [ module, v ]; [ $module, $file_map ] ]
}
} | flatten | flatten --all
}
# 进行模块文件的符号链接
export def do_link [
modules?: list
] {
let module_files = (
list_files $modules | group-by module | transpose module files
)
# 遍历模块
for $it in $module_files {
let module = $it.module
let files = $it.files
log status $"链接模块 ($module)..."
# 遍历文件映射,执行软链接
for $it in $files {
let local = $it.local
let dest = $it.dest
let type = ($dest | path type)
if ($type == symlink) {
log info $"($dest) 已链接,跳过"
} else {
let link = if ($type != "") {
# 文件存在时进行询问
let agree = (confirm $"- 文件 ($dest) 已存在,是否强制覆盖?" "n")
if ($agree) {
log debug $"删除 ($dest)"
rm -rf $dest
true
} else { false }
} else {
# 不存在则直接链接
true
}
# 进行符号链接
if ($link) {
log info $"链接 ($local) --> ($dest)"
mkdir (get_base_dir $local $dest)
ln -s $local $dest
}
}
}
log info ""
}
}
# 删除模块文件的符号链接
export def do_unlink [
modules?: list
] {
let module_files = (
list_files $modules | group-by module | transpose module files
)
# 遍历模块
for $it in $module_files {
let module = $it.module
let files = $it.files
log status $"清理模块 ($module)..."
# 遍历文件映射,删除软链接
for $it in $files {
let dest = $it.dest
let type = ($dest | path type)
if ($type == symlink) {
log info $"清理 ($dest)"
rm -rf $dest
} else if ($type != "") {
log warn $"- ($dest) 非符号链接,跳过"
}
null
}
log info ""
}
}