feat: NixOS 声明式配置(从 Arch + decman 迁移)
- flake.nix: NixOS + home-manager + nixos-wsl 三输入 - hosts/wsl + hosts/bare: WSL 与裸机共享模块,分主机配置 - modules/: base(CLI 工具) + dev(工具链+LSP) + docker + locale + shell - home/: zsh(oh-my-zsh+插件+别名) + git(delta) + starship + 工具集成 - scripts/install.sh: 一键安装脚本(WSL/裸机通用) - 原 bun/go 全局包 hack 改为 nixpkgs 声明式管理
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
# ── 核心工具 ──
|
||||
curl
|
||||
git
|
||||
micro
|
||||
vim
|
||||
wget
|
||||
|
||||
# ── 现代 CLI 替代 ──
|
||||
bat # cat
|
||||
btop # top
|
||||
duf # df
|
||||
dust # du
|
||||
eza # ls
|
||||
fd # find
|
||||
jq # JSON
|
||||
procs # ps
|
||||
ripgrep # grep
|
||||
sd # sed
|
||||
xh # curl/httpie
|
||||
yq # YAML
|
||||
|
||||
# ── 文件管理 ──
|
||||
trash-cli
|
||||
yazi
|
||||
|
||||
# ── 系统信息 ──
|
||||
fastfetch
|
||||
tealdeer # tldr
|
||||
];
|
||||
|
||||
# ── Nix 设置 ──
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
# 国内镜像(按需取消注释)
|
||||
# substituters = [
|
||||
# "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"
|
||||
# "https://cache.nixos.org"
|
||||
# ];
|
||||
};
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
from decman import File, Module
|
||||
from decman.plugins.aur import packages as aur_packages
|
||||
from decman.plugins.pacman import packages as pacman_packages
|
||||
|
||||
|
||||
class BaseModule(Module):
|
||||
def __init__(self, user: str):
|
||||
super().__init__("base")
|
||||
self.user = user
|
||||
|
||||
def files(self):
|
||||
return {
|
||||
"/etc/pacman.conf": File(
|
||||
source_file="./system/etc/pacman.conf",
|
||||
),
|
||||
"/etc/pacman.d/mirrorlist": File(
|
||||
source_file="./system/etc/pacman.d/mirrorlist",
|
||||
),
|
||||
"/etc/sudoers.d/10-wheel": File(
|
||||
source_file="./system/etc/sudoers.d/10-wheel",
|
||||
permissions=0o440,
|
||||
),
|
||||
f"/home/{self.user}/.config/git/config": File(
|
||||
source_file="./home/.config/git/config",
|
||||
owner=self.user,
|
||||
),
|
||||
f"/home/{self.user}/.config/starship.toml": File(
|
||||
source_file="./home/.config/starship.toml",
|
||||
owner=self.user,
|
||||
),
|
||||
}
|
||||
|
||||
@pacman_packages
|
||||
def pacman_packages(self) -> set[str]:
|
||||
return {
|
||||
"atuin",
|
||||
"base-devel",
|
||||
"base",
|
||||
"bat",
|
||||
"btop",
|
||||
"curl",
|
||||
"direnv",
|
||||
"duf",
|
||||
"dust",
|
||||
"eza",
|
||||
"fastfetch",
|
||||
"fd",
|
||||
"git-delta",
|
||||
"git",
|
||||
"jq",
|
||||
"micro",
|
||||
"procs",
|
||||
"ripgrep",
|
||||
"sd",
|
||||
"starship",
|
||||
"sudo",
|
||||
"tealdeer",
|
||||
"trash-cli",
|
||||
"vim",
|
||||
"wget",
|
||||
"xh",
|
||||
"yazi",
|
||||
"yq",
|
||||
"zoxide",
|
||||
}
|
||||
|
||||
@aur_packages
|
||||
def aur_packages(self) -> set[str]:
|
||||
return {
|
||||
"decman",
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
# ── 语言运行时 ──
|
||||
bun
|
||||
go
|
||||
nodejs
|
||||
|
||||
# ── 包管理 / 版本管理 ──
|
||||
mise
|
||||
uv
|
||||
|
||||
# ── 编辑器 ──
|
||||
neovim
|
||||
|
||||
# ── 终端复用 ──
|
||||
tmux
|
||||
zellij
|
||||
|
||||
# ── Git 增强 ──
|
||||
delta # Arch 包名: git-delta
|
||||
gh # Arch 包名: github-cli
|
||||
lazygit
|
||||
|
||||
# ── Linter / Formatter ──
|
||||
biome
|
||||
ruff
|
||||
shellcheck
|
||||
shfmt
|
||||
|
||||
# ── LSP 服务器 ──
|
||||
ast-grep
|
||||
bash-language-server
|
||||
gopls
|
||||
typescript-language-server # 若报错尝试 nodePackages.typescript-language-server
|
||||
yaml-language-server # 若报错尝试 nodePackages.yaml-language-server
|
||||
vue-language-server # 替代原 bun -g @vue/language-server
|
||||
dockerfile-language-server-nodejs # 替代原 bun -g dockerfile-language-server
|
||||
|
||||
# ── 原 bun/go 全局安装的工具 ──
|
||||
# 以下工具如果在 nixpkgs 中不存在,需要自定义打包:
|
||||
#
|
||||
# opencode-ai:
|
||||
# buildNpmPackage { pname = "opencode-ai"; ... }
|
||||
#
|
||||
# go-claude-code-comment-checker:
|
||||
# buildGoModule {
|
||||
# pname = "comment-checker";
|
||||
# src = fetchFromGitHub { owner = "code-yeongyu"; repo = "..."; ... };
|
||||
# vendorHash = "sha256-...";
|
||||
# }
|
||||
];
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
import decman
|
||||
from decman import File, Module
|
||||
from decman.plugins.pacman import packages as pacman_packages
|
||||
|
||||
BUN_GLOBAL_PACKAGES = [
|
||||
"@vue/language-server",
|
||||
"dockerfile-language-server", # TODO: 等 extra-testing -> extra 后改用 pacman
|
||||
"opencode-ai",
|
||||
]
|
||||
|
||||
GO_INSTALL_PACKAGES = [
|
||||
"github.com/code-yeongyu/go-claude-code-comment-checker/cmd/comment-checker@latest",
|
||||
]
|
||||
|
||||
|
||||
class DevModule(Module):
|
||||
def __init__(self, user: str):
|
||||
super().__init__("dev")
|
||||
self.user = user
|
||||
|
||||
def files(self):
|
||||
return {
|
||||
f"/home/{self.user}/.config/mise/config.toml": File(
|
||||
source_file="./home/.config/mise/config.toml",
|
||||
owner=self.user,
|
||||
),
|
||||
}
|
||||
|
||||
@pacman_packages
|
||||
def pacman_packages(self) -> set[str]:
|
||||
return {
|
||||
"ast-grep",
|
||||
"bash-language-server",
|
||||
"biome",
|
||||
"bun",
|
||||
"github-cli",
|
||||
"go",
|
||||
"gopls",
|
||||
"lazygit",
|
||||
"mise",
|
||||
"neovim",
|
||||
"nodejs",
|
||||
"ruff",
|
||||
"shellcheck",
|
||||
"shfmt",
|
||||
"tmux",
|
||||
"typescript-language-server",
|
||||
"uv",
|
||||
"yaml-language-server",
|
||||
"zellij",
|
||||
}
|
||||
|
||||
def after_update(self, store):
|
||||
failures: list[str] = []
|
||||
for pkg in BUN_GLOBAL_PACKAGES:
|
||||
try:
|
||||
decman.prg(["bun", "add", "-g", pkg], user=self.user, mimic_login=True)
|
||||
except Exception as e:
|
||||
failures.append(f"bun: {pkg} ({e})")
|
||||
for pkg in GO_INSTALL_PACKAGES:
|
||||
try:
|
||||
decman.prg(["go", "install", pkg], user=self.user, mimic_login=True)
|
||||
except Exception as e:
|
||||
failures.append(f"go: {pkg} ({e})")
|
||||
if failures:
|
||||
print(f"\n⚠ {len(failures)} 个全局包安装失败:")
|
||||
for f in failures:
|
||||
print(f" - {f}")
|
||||
print()
|
||||
@@ -0,0 +1,17 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker-compose
|
||||
];
|
||||
|
||||
# 注:用户 docker 组权限在 hosts/*/default.nix 中配置
|
||||
#
|
||||
# WSL 环境下如使用 Docker Desktop,可改为:
|
||||
# wsl.docker-desktop.enable = true;
|
||||
# 并将上面的 virtualisation.docker.enable 设为 false
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
import decman
|
||||
from decman import Module
|
||||
from decman.plugins.pacman import packages as pacman_packages
|
||||
from decman.plugins.systemd import units
|
||||
|
||||
|
||||
class DockerModule(Module):
|
||||
def __init__(self, user: str):
|
||||
super().__init__("docker")
|
||||
self.user = user
|
||||
|
||||
@pacman_packages
|
||||
def pacman_packages(self) -> set[str]:
|
||||
return {"docker", "docker-compose"}
|
||||
|
||||
@units
|
||||
def units(self) -> set[str]:
|
||||
return {"docker.socket"}
|
||||
|
||||
def after_update(self, store):
|
||||
result = subprocess.run(
|
||||
["id", "-nG", self.user], capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
return
|
||||
if "docker" not in result.stdout.split():
|
||||
decman.prg(["gpasswd", "-a", self.user, "docker"])
|
||||
@@ -0,0 +1,8 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
i18n = {
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
supportedLocales = [ "en_US.UTF-8/UTF-8" ];
|
||||
};
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import decman
|
||||
from decman import File, Module
|
||||
|
||||
|
||||
class LocaleModule(Module):
|
||||
def __init__(self):
|
||||
super().__init__("locale")
|
||||
|
||||
def files(self):
|
||||
return {
|
||||
"/etc/locale.conf": File(content="LANG=en_US.UTF-8\n"),
|
||||
"/etc/locale.gen": File(content="en_US.UTF-8 UTF-8\n"),
|
||||
}
|
||||
|
||||
def on_change(self, store):
|
||||
decman.prg(["locale-gen"])
|
||||
@@ -0,0 +1,6 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
# 系统级启用 Zsh(用户级配置在 home/shell.nix)
|
||||
programs.zsh.enable = true;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
import decman
|
||||
from decman import File, Module
|
||||
from decman.plugins.aur import packages as aur_packages
|
||||
from decman.plugins.pacman import packages as pacman_packages
|
||||
|
||||
|
||||
class ZshModule(Module):
|
||||
def __init__(self, user: str):
|
||||
super().__init__("zsh")
|
||||
self.user = user
|
||||
|
||||
def files(self):
|
||||
return {
|
||||
f"/home/{self.user}/.zshrc": File(
|
||||
source_file="./home/.zshrc",
|
||||
owner=self.user,
|
||||
),
|
||||
}
|
||||
|
||||
@pacman_packages
|
||||
def pacman_packages(self) -> set[str]:
|
||||
return {
|
||||
"fzf",
|
||||
"zsh",
|
||||
"zsh-autosuggestions",
|
||||
"zsh-completions",
|
||||
"zsh-syntax-highlighting",
|
||||
}
|
||||
|
||||
@aur_packages
|
||||
def aur_packages(self) -> set[str]:
|
||||
return {
|
||||
"fzf-tab-git",
|
||||
"oh-my-zsh-git",
|
||||
}
|
||||
|
||||
def after_update(self, store):
|
||||
result = subprocess.run(
|
||||
["getent", "passwd", self.user], capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
return
|
||||
# passwd 格式: name:x:uid:gid:gecos:home:shell
|
||||
shell = result.stdout.strip().split(":")[-1]
|
||||
if shell != "/usr/bin/zsh":
|
||||
decman.prg(["chsh", "-s", "/usr/bin/zsh", self.user])
|
||||
Reference in New Issue
Block a user