Compare commits

...

3 Commits

Author SHA1 Message Date
imbytecat 9befd389af docs: 修正 AGENTS.md 与重构后代码不符的描述
- zsh 模块描述: oh-my-zsh → 插件 + 自动 chsh(实际无 oh-my-zsh)
- source.py 分区描述: 删除已不存在的"系统文件→用户配置→pacman→AUR"分区
- source.py 结构: 同步删除"校验插件存在性"(对应 source.py 死代码清理)
- 模块组织原则: 删除矛盾的"直接在 source.py 用 File()"路径
- Pacman vs AUR 路径: decman.pacman.packages → @pacman_packages 装饰器
- 常见任务: 添加包/文件/dotfile 步骤更新到模块路径
2026-04-08 12:37:57 +08:00
imbytecat f626c12e49 fix(dev): hook 失败改为 raise SourceError 而非静默警告
全局包安装失败原本只 print 警告,decman 退出码仍为 0,违反声明式语义。
改为汇总后 raise decman.SourceError,符合官方 docstring 推荐(失败应被感知,
下次 sync 会重试)。保留"尝试所有包"逻辑,一次性看到全部失败。
2026-04-08 12:37:49 +08:00
imbytecat 04d517a2c2 refactor: 清理 source.py 死代码与空 __init__.py
- source.py: 删除插件存在性检查,modules import 阶段已会 ImportError
- modules/__init__.py: 删除空文件,PEP 420 namespace package 不需要
2026-04-08 12:37:41 +08:00
4 changed files with 13 additions and 19 deletions
+9 -12
View File
@@ -18,7 +18,7 @@
│ ├── dev.py # 开发模块(语言运行时 + 编辑器 + 工具链) │ ├── dev.py # 开发模块(语言运行时 + 编辑器 + 工具链)
│ ├── docker.py # Docker 模块(packages + systemd units │ ├── docker.py # Docker 模块(packages + systemd units
│ ├── locale.py # locale 模块(files + on_change hook │ ├── locale.py # locale 模块(files + on_change hook
│ └── zsh.py # Zsh 模块(shell + oh-my-zsh + 插件) │ └── zsh.py # Zsh 模块(shell + 插件 + 自动 chsh
├── system/etc/ # 系统配置文件源 → 部署到 /etc/ ├── system/etc/ # 系统配置文件源 → 部署到 /etc/
├── home/ # 用户配置文件源 → 部署到 ~/ ├── home/ # 用户配置文件源 → 部署到 ~/
├── scripts/ ├── scripts/
@@ -70,15 +70,15 @@ uv sync
files → pacman → aur → systemd files → pacman → aur → systemd
``` ```
`source.py` 中的声明分区按此排列:系统文件 → 用户配置 → modules pacman 包 → AUR 包 `source.py` 是纯模块注册入口,所有 files / packages / units 声明都在各 Module 内部实现
## 代码风格 ## 代码风格
### Pythonsource.py 及模块) ### Pythonsource.py 及模块)
**source.py 结构** **source.py 结构**
- 纯模块注册不直接声明文件或包 - 纯模块注册入口,不直接声明文件或包
- 校验 `SUDO_USER` 和必要插件存在性 - 校验 `SUDO_USER`(插件缺失时 `import modules.*` 阶段会直接 ImportError,无需运行时检查)
- 通过 `decman.modules += [...]` 注册所有模块 - 通过 `decman.modules += [...]` 注册所有模块
**模块模式**(适用于需要 hook 或跨步骤声明的场景): **模块模式**(适用于需要 hook 或跨步骤声明的场景):
@@ -101,10 +101,7 @@ class DockerModule(Module):
return {"docker.socket"} return {"docker.socket"}
``` ```
**何时用模块 vs 直接声明** **模块组织原则**:所有 files / packages / units 声明都通过 Module 封装,按领域拆分(base / dev / docker / locale / zsh)。新增功能优先加到对应现有模块;跨领域、需要 lifecycle hook(`on_change` / `after_update`)或需要绑定 packages + systemd units 时再新建模块。
- 需要 `on_change` hook(如 `locale-gen`)→ Module
- 需要绑定 packages + systemd units → Module`@packages` + `@units` 装饰器)
- 纯静态文件、无副作用 → 直接在 `source.py``File()`
### Shell 脚本 ### Shell 脚本
@@ -128,7 +125,7 @@ class DockerModule(Module):
1. **decman 是唯一真相**:不要手动装包,加到 `source.py` 或模块里,跑 `sudo decman` 1. **decman 是唯一真相**:不要手动装包,加到 `source.py` 或模块里,跑 `sudo decman`
2. **Pacman vs AUR**:用 `pacman -Ss` 确认包在官方仓库还是 AUR分别加到 `decman.pacman.packages``decman.aur.packages` 2. **Pacman vs AUR**:用 `pacman -Ss` 确认包在官方仓库还是 AUR,分别加到对应模块的 `@pacman_packages``@aur_packages` 装饰器方法返回集合
3. **系统文件**:源文件放 `system/`,目录结构对应目标路径(`system/etc/foo.conf``/etc/foo.conf`)。decman 复制(非 symlink)到目标位置。 3. **系统文件**:源文件放 `system/`,目录结构对应目标路径(`system/etc/foo.conf``/etc/foo.conf`)。decman 复制(非 symlink)到目标位置。
@@ -144,11 +141,11 @@ class DockerModule(Module):
## 常见任务 ## 常见任务
**添加包**确认 pacman/AUR → 加到 `source.py` 对应集合 → `sudo decman` **添加包**:确认 pacman/AUR → 加到对应模块的 `@pacman_packages` / `@aur_packages` 方法返回集合 → `sudo decman`
**添加系统文件**`system/` → 在 `source.py``File(source_file=...)``sudo decman` **添加系统文件**:`system/` → 在对应模块的 `files()` 方法`File(source_file=...)``sudo decman`
**添加 dotfile**`home/` → 在 `source.py``File(source_file=..., owner=USERNAME)``sudo decman` **添加 dotfile**:`home/` → 在对应模块的 `files()` 方法`File(source_file=..., owner=self.user)``sudo decman`
**添加需要 systemd 服务的软件**:创建 Module 文件,用 `@packages` + `@units` 装饰器 → 在 `source.py` 注册 → `sudo decman` **添加需要 systemd 服务的软件**:创建 Module 文件,用 `@packages` + `@units` 装饰器 → 在 `source.py` 注册 → `sudo decman`
View File
+4 -4
View File
@@ -78,7 +78,7 @@ class DevModule(Module):
except Exception as e: except Exception as e:
failures.append(f"go: {pkg} ({e})") failures.append(f"go: {pkg} ({e})")
if failures: if failures:
print(f"\n{len(failures)} 个全局包安装失败:") raise decman.SourceError(
for f in failures: f"{len(failures)} 个全局包安装失败:\n"
print(f" - {f}") + "\n".join(f" - {f}" for f in failures)
print() )
-3
View File
@@ -8,9 +8,6 @@ import modules.docker
import modules.locale import modules.locale
import modules.zsh import modules.zsh
if decman.pacman is None or decman.aur is None or decman.systemd is None:
raise decman.SourceError("缺少必要插件,请检查 decman 安装")
USERNAME = os.environ.get("SUDO_USER") USERNAME = os.environ.get("SUDO_USER")
if not USERNAME: if not USERNAME:
raise decman.SourceError("请使用 sudo 运行") raise decman.SourceError("请使用 sudo 运行")