128 lines
4.7 KiB
Nix
128 lines
4.7 KiB
Nix
{
|
||
description = "Reproducible Sphinx Documentation Build";
|
||
|
||
inputs = {
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||
flake-utils.url = "github:numtide/flake-utils";
|
||
};
|
||
|
||
outputs = { self, nixpkgs, flake-utils }:
|
||
flake-utils.lib.eachDefaultSystem (system:
|
||
let
|
||
pkgs = nixpkgs.legacyPackages.${system};
|
||
lib = pkgs.lib;
|
||
|
||
# ----------------------------------------------------------------
|
||
# 1. 定义精确的 Python 环境
|
||
# ----------------------------------------------------------------
|
||
# 这里显式列出依赖,确保无论在哪台机器,Sphinx 版本一致
|
||
pythonEnv = pkgs.python3.withPackages (ps: with ps; [
|
||
sphinx
|
||
sphinx-multiversion
|
||
sphinx-autobuild
|
||
# 在这里添加你的 theme 或 extension,例如:
|
||
sphinx-rtd-theme
|
||
myst-parser
|
||
sphinxcontrib-mermaid
|
||
linkify-it-py
|
||
]);
|
||
|
||
# ----------------------------------------------------------------
|
||
# 2. 从 Flake 输入中提取 Git 信息 (Pure 方式)
|
||
# ----------------------------------------------------------------
|
||
# Nix 在求值时知道当前的 revision,不需要在 build 时运行 git 命令
|
||
gitHash = if (self ? rev) then self.rev else "dirty-dev";
|
||
isDirty = if (self ? rev) then "0" else "1";
|
||
|
||
buildDir = "./_build";
|
||
port = 8000;
|
||
|
||
in
|
||
{
|
||
# ----------------------------------------------------------------
|
||
# Packages: 纯净构建 (nix build)
|
||
# ----------------------------------------------------------------
|
||
# 这种方式构建的是"当前代码的快照",完全不依赖 .git 目录
|
||
packages.default = pkgs.stdenv.mkDerivation {
|
||
name = "sphinx-docs";
|
||
src = ./.;
|
||
|
||
buildInputs = [ pythonEnv ];
|
||
|
||
# 将 Nix 提取的 Git 信息注入环境变量
|
||
# 这完全替代了 Makefile 中 $(shell git rev-parse) 的逻辑
|
||
env = {
|
||
LANGUAGE = "zh_CN";
|
||
CURRENT_GIT_COMMIT_HASH = gitHash;
|
||
CURRENT_GIT_COMMIT_DIRTY = isDirty;
|
||
SPHINXBUILD = "sphinx-build";
|
||
};
|
||
|
||
# 直接定义构建逻辑,不再依赖 Makefile
|
||
buildPhase = ''
|
||
echo "Building documentation for commit: $CURRENT_GIT_COMMIT_HASH"
|
||
|
||
# 使用 -W 将警告视为错误,确保构建质量
|
||
sphinx-build -M html . ${buildDir} \
|
||
-D language=$LANGUAGE \
|
||
-w _build/warnings.log
|
||
'';
|
||
|
||
installPhase = ''
|
||
mkdir -p $out
|
||
cp -r ${buildDir}/* $out/
|
||
'';
|
||
};
|
||
|
||
# ----------------------------------------------------------------
|
||
# Apps: 快速运行工具 (nix run)
|
||
# ----------------------------------------------------------------
|
||
# 提供一个脚本来预览构建结果
|
||
apps.release = flake-utils.lib.mkApp {
|
||
drv = let targetDir = self.packages.${system}.default;
|
||
in pkgs.writeShellApplication {
|
||
name = "preview-docs";
|
||
runtimeInputs = [ pythonEnv ];
|
||
text = ''
|
||
echo "Open at http://localhost:${toString port}/index.html"
|
||
python3 -m http.server --directory "${targetDir}/html" ${toString port}
|
||
'';
|
||
};
|
||
};
|
||
app.develop = flake-utils.lib.mkApp {
|
||
drv = pkgs.writeShellApplication {
|
||
name = "sphinx-autobuild";
|
||
runtimeInputs = [ pythonEnv ];
|
||
text = ''
|
||
sphinx-autobuild . ${buildDir} --host 0.0.0.0 --port ${toString port}
|
||
'';
|
||
};
|
||
};
|
||
# 设置默认 run 行为
|
||
apps.default = self.app.${system}.develop;
|
||
|
||
# ----------------------------------------------------------------
|
||
# DevShell: 开发环境 (nix develop)
|
||
# ----------------------------------------------------------------
|
||
# 用于开发和需要访问 .git 的操作(如 sphinx-multiversion)
|
||
devShells.default = pkgs.mkShell {
|
||
packages = [ pythonEnv pkgs.git pkgs.gnumake ];
|
||
|
||
shellHook = ''
|
||
export LANGUAGE="zh_CN"
|
||
export SPHINXBUILD="sphinx-build"
|
||
|
||
# 在开发环境中,我们可以动态获取 git 状态
|
||
export CURRENT_GIT_COMMIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||
|
||
echo "🚀 Sphinx Dev Environment Loaded"
|
||
echo "-----------------------------------"
|
||
echo "Run 'make html' for standard build"
|
||
echo "Run 'make html-multiversion' for versioned build (Requires .git)"
|
||
echo "Run 'nix build' for clean production build"
|
||
'';
|
||
};
|
||
}
|
||
);
|
||
}
|