refactor: 合并 dev_scripts 入口为单一 harness.py (#23)
原有 4 个命令行入口(check_harness、sync_wiki_docs、new_task_archive、 export_task_archives)需要在多处文档分别描述,同步核心镜像还要按顺序跑 3 条命令。 合并为 dev_scripts/harness.py,提供 check / sync / archive / export 四个子命令, 各命令实现逻辑逐字取自原脚本,行为未改变;新增 sync --verify 一次完成 导出 → check --strict → 一致性校验。wiki_docs.py 作为库保持不变。 破坏性变更:4 个旧入口已删除,不保留兼容转发。已采用 DevHarness 的业务项目 升级基线时必须同步修改自己的命令与文档。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,131 +0,0 @@
|
||||
"""把 Gitea Wiki 任务归档人工按需导出到 docs/task。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from new_task_archive import safe_title
|
||||
from wiki_docs import (
|
||||
DEFAULT_CONFIG,
|
||||
ROOT,
|
||||
WikiClient,
|
||||
WikiDocsError,
|
||||
dirty_paths,
|
||||
load_config,
|
||||
parse_mirror,
|
||||
write_mirror,
|
||||
)
|
||||
|
||||
|
||||
TASK_PAGE_PATTERN = re.compile(r"^Task-(?P<number>\d+)-(?P<title>.+)$")
|
||||
|
||||
|
||||
def task_revision(metadata: dict[str, Any], page_name: str) -> str:
|
||||
last_commit = metadata.get("last_commit")
|
||||
revision = last_commit.get("sha") if isinstance(last_commit, dict) else None
|
||||
if not isinstance(revision, str) or not revision:
|
||||
raise WikiDocsError(f"Wiki 页面缺少 revision:{page_name}")
|
||||
return revision
|
||||
|
||||
|
||||
def existing_task_mirrors(root: Path = ROOT) -> dict[str, Path]:
|
||||
"""按镜像头匹配已有文件,兼容历史自定义文件名。"""
|
||||
|
||||
mirrors: dict[str, Path] = {}
|
||||
task_dir = root / "docs" / "task"
|
||||
if not task_dir.is_dir():
|
||||
return mirrors
|
||||
for path in task_dir.glob("*.md"):
|
||||
try:
|
||||
metadata, _ = parse_mirror(path.read_text(encoding="utf-8"))
|
||||
except (OSError, UnicodeDecodeError, WikiDocsError) as exc:
|
||||
raise WikiDocsError(f"已有任务镜像无效 {path.name}:{exc}") from exc
|
||||
page_name = metadata.get("wiki_page", "")
|
||||
if not TASK_PAGE_PATTERN.fullmatch(page_name):
|
||||
raise WikiDocsError(f"已有任务镜像页面名无效 {path.name}:{page_name}")
|
||||
if page_name in mirrors:
|
||||
raise WikiDocsError(f"任务页面存在重复本地镜像:{page_name}")
|
||||
mirrors[page_name] = path
|
||||
return mirrors
|
||||
|
||||
|
||||
def task_target(page_name: str, root: Path = ROOT) -> Path:
|
||||
match = TASK_PAGE_PATTERN.fullmatch(page_name)
|
||||
if match is None:
|
||||
raise WikiDocsError(f"不是任务归档页面:{page_name}")
|
||||
title = safe_title(match.group("title"))
|
||||
if not title:
|
||||
raise WikiDocsError(f"任务归档标题无效:{page_name}")
|
||||
return root / "docs" / "task" / f"{match.group('number')}-{title}.md"
|
||||
|
||||
|
||||
def export_task_archives(
|
||||
client: WikiClient, *, export_all: bool = False, root: Path = ROOT
|
||||
) -> list[str]:
|
||||
"""增量或全量读取任务归档;绝不删除本地文件。"""
|
||||
|
||||
dirty = dirty_paths(["docs/task"], root)
|
||||
if dirty:
|
||||
raise WikiDocsError(
|
||||
"本地任务镜像存在未提交改动,已停止以防覆盖:\n" + "\n".join(dirty)
|
||||
)
|
||||
|
||||
existing = existing_task_mirrors(root)
|
||||
pages = []
|
||||
for metadata in client.list_pages():
|
||||
title = metadata.get("title")
|
||||
if isinstance(title, str) and TASK_PAGE_PATTERN.fullmatch(title):
|
||||
pages.append((int(title.split("-", 2)[1]), title, metadata))
|
||||
pages.sort(key=lambda item: (item[0], item[1]))
|
||||
|
||||
messages: list[str] = []
|
||||
targets: set[Path] = set()
|
||||
for _, page_name, metadata in pages:
|
||||
target = existing.get(page_name, task_target(page_name, root))
|
||||
if target in targets:
|
||||
raise WikiDocsError(f"多个任务页面映射到同一本地路径:{target.name}")
|
||||
targets.add(target)
|
||||
revision = task_revision(metadata, page_name)
|
||||
if not export_all and target.is_file():
|
||||
local_metadata, _ = parse_mirror(target.read_text(encoding="utf-8"))
|
||||
if (
|
||||
local_metadata.get("wiki_page") == page_name
|
||||
and local_metadata.get("wiki_revision") == revision
|
||||
):
|
||||
messages.append(f"跳过:{target.relative_to(root)} <- {page_name}@{revision[:12]}")
|
||||
continue
|
||||
page = client.get_page_from_metadata(metadata, page_name)
|
||||
changed = write_mirror(target, page)
|
||||
action = "已导出" if changed else "无变化"
|
||||
messages.append(f"{action}:{target.relative_to(root)} <- {page_name}@{revision[:12]}")
|
||||
return messages
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="人工按需导出 Gitea Wiki 任务归档")
|
||||
parser.add_argument(
|
||||
"--all", action="store_true", help="全量读取全部线上任务归档;默认按 revision 增量"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--config", default=str(DEFAULT_CONFIG), help="核心 Wiki 映射配置"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
messages = export_task_archives(
|
||||
WikiClient(config), export_all=args.all
|
||||
)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
for message in messages:
|
||||
print(message)
|
||||
print("任务归档全量导出完成" if args.all else "任务归档增量导出完成")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,14 +1,37 @@
|
||||
"""检查 DevHarness 必需文件、核心文档和任务归档的基本结构。"""
|
||||
"""DevHarness 单一命令行入口。
|
||||
|
||||
子命令:
|
||||
check 检查必需文件、核心文档和任务归档结构
|
||||
sync 从 Gitea Wiki 单向导出或校验核心 docs 镜像
|
||||
archive 在 Gitea Wiki 创建任务归档
|
||||
export 人工按需把 Wiki 任务归档导出到 docs/task
|
||||
|
||||
各子命令的实现逻辑取自原来的 check_harness.py、sync_wiki_docs.py、
|
||||
new_task_archive.py 和 export_task_archives.py,行为未改变。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from wiki_docs import WikiDocsError, load_config, parse_mirror
|
||||
from wiki_docs import (
|
||||
DEFAULT_CONFIG,
|
||||
WikiClient,
|
||||
WikiDocsError,
|
||||
dirty_paths,
|
||||
load_config,
|
||||
parse_mirror,
|
||||
sync_all,
|
||||
write_mirror,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 结构检查
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CORE_PAGE_PATHS = {
|
||||
"Home": "docs/README.md",
|
||||
@@ -170,8 +193,7 @@ REQUIRED_FILES = (
|
||||
*CORE_DOCUMENT_REQUIREMENTS,
|
||||
"wiki-docs.json",
|
||||
"dev_scripts/wiki_docs.py",
|
||||
"dev_scripts/sync_wiki_docs.py",
|
||||
"dev_scripts/export_task_archives.py",
|
||||
"dev_scripts/harness.py",
|
||||
".gitea/issue_template/epic.md",
|
||||
".gitea/issue_template/mvp.md",
|
||||
".gitea/issue_template/task.md",
|
||||
@@ -344,7 +366,7 @@ def check_repository_readme(errors: list[str], root: Path = ROOT) -> None:
|
||||
"优先使用已配置的 Gitea MCP",
|
||||
"`Home` 不存在时先创建并回读 `Home`",
|
||||
"本地 `docs/` 的存在不能证明线上 Wiki 已初始化",
|
||||
"python dev_scripts/sync_wiki_docs.py --check",
|
||||
"python dev_scripts/harness.py sync --verify",
|
||||
)
|
||||
for section in missing_sections(content, required):
|
||||
errors.append(f"README.md 缺少:{section}")
|
||||
@@ -432,15 +454,121 @@ def check_wiki_mirrors(errors: list[str]) -> None:
|
||||
errors.append(f"{mapping.path} 缺少 synchronized_at")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="检查 DevHarness 项目结构")
|
||||
parser.add_argument(
|
||||
"--strict",
|
||||
action="store_true",
|
||||
help="项目档案有占位内容时返回失败",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
# ---------------------------------------------------------------- 任务归档
|
||||
|
||||
def safe_title(title: str) -> str:
|
||||
"""把标题转换为适合 Wiki 页面名和 Windows 文件名的短文本。"""
|
||||
|
||||
cleaned = re.sub(r'[<>:"/\\|?*]', "-", title.strip())
|
||||
cleaned = re.sub(r"\s+", "-", cleaned)
|
||||
cleaned = re.sub(r"-+", "-", cleaned)
|
||||
return cleaned.strip(".-")
|
||||
|
||||
|
||||
def build_archive(
|
||||
template: str,
|
||||
issue_number: str,
|
||||
title: str,
|
||||
page_name: str,
|
||||
issue_url: str,
|
||||
) -> str:
|
||||
content = template.replace("<工单号>", issue_number, 1)
|
||||
content = content.replace("<标题>", title.strip(), 1)
|
||||
content = content.replace("YYYY-MM-DD", date.today().isoformat(), 1)
|
||||
content = content.replace("<链接>", issue_url, 1)
|
||||
return content.replace("<页面名>", page_name, 1)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 归档导出
|
||||
|
||||
TASK_PAGE_PATTERN = re.compile(r"^Task-(?P<number>\d+)-(?P<title>.+)$")
|
||||
|
||||
|
||||
def task_revision(metadata: dict[str, Any], page_name: str) -> str:
|
||||
last_commit = metadata.get("last_commit")
|
||||
revision = last_commit.get("sha") if isinstance(last_commit, dict) else None
|
||||
if not isinstance(revision, str) or not revision:
|
||||
raise WikiDocsError(f"Wiki 页面缺少 revision:{page_name}")
|
||||
return revision
|
||||
|
||||
|
||||
def existing_task_mirrors(root: Path = ROOT) -> dict[str, Path]:
|
||||
"""按镜像头匹配已有文件,兼容历史自定义文件名。"""
|
||||
|
||||
mirrors: dict[str, Path] = {}
|
||||
task_dir = root / "docs" / "task"
|
||||
if not task_dir.is_dir():
|
||||
return mirrors
|
||||
for path in task_dir.glob("*.md"):
|
||||
try:
|
||||
metadata, _ = parse_mirror(path.read_text(encoding="utf-8"))
|
||||
except (OSError, UnicodeDecodeError, WikiDocsError) as exc:
|
||||
raise WikiDocsError(f"已有任务镜像无效 {path.name}:{exc}") from exc
|
||||
page_name = metadata.get("wiki_page", "")
|
||||
if not TASK_PAGE_PATTERN.fullmatch(page_name):
|
||||
raise WikiDocsError(f"已有任务镜像页面名无效 {path.name}:{page_name}")
|
||||
if page_name in mirrors:
|
||||
raise WikiDocsError(f"任务页面存在重复本地镜像:{page_name}")
|
||||
mirrors[page_name] = path
|
||||
return mirrors
|
||||
|
||||
|
||||
def task_target(page_name: str, root: Path = ROOT) -> Path:
|
||||
match = TASK_PAGE_PATTERN.fullmatch(page_name)
|
||||
if match is None:
|
||||
raise WikiDocsError(f"不是任务归档页面:{page_name}")
|
||||
title = safe_title(match.group("title"))
|
||||
if not title:
|
||||
raise WikiDocsError(f"任务归档标题无效:{page_name}")
|
||||
return root / "docs" / "task" / f"{match.group('number')}-{title}.md"
|
||||
|
||||
|
||||
def export_task_archives(
|
||||
client: WikiClient, *, export_all: bool = False, root: Path = ROOT
|
||||
) -> list[str]:
|
||||
"""增量或全量读取任务归档;绝不删除本地文件。"""
|
||||
|
||||
dirty = dirty_paths(["docs/task"], root)
|
||||
if dirty:
|
||||
raise WikiDocsError(
|
||||
"本地任务镜像存在未提交改动,已停止以防覆盖:\n" + "\n".join(dirty)
|
||||
)
|
||||
|
||||
existing = existing_task_mirrors(root)
|
||||
pages = []
|
||||
for metadata in client.list_pages():
|
||||
title = metadata.get("title")
|
||||
if isinstance(title, str) and TASK_PAGE_PATTERN.fullmatch(title):
|
||||
pages.append((int(title.split("-", 2)[1]), title, metadata))
|
||||
pages.sort(key=lambda item: (item[0], item[1]))
|
||||
|
||||
messages: list[str] = []
|
||||
targets: set[Path] = set()
|
||||
for _, page_name, metadata in pages:
|
||||
target = existing.get(page_name, task_target(page_name, root))
|
||||
if target in targets:
|
||||
raise WikiDocsError(f"多个任务页面映射到同一本地路径:{target.name}")
|
||||
targets.add(target)
|
||||
revision = task_revision(metadata, page_name)
|
||||
if not export_all and target.is_file():
|
||||
local_metadata, _ = parse_mirror(target.read_text(encoding="utf-8"))
|
||||
if (
|
||||
local_metadata.get("wiki_page") == page_name
|
||||
and local_metadata.get("wiki_revision") == revision
|
||||
):
|
||||
messages.append(f"跳过:{target.relative_to(root)} <- {page_name}@{revision[:12]}")
|
||||
continue
|
||||
page = client.get_page_from_metadata(metadata, page_name)
|
||||
changed = write_mirror(target, page)
|
||||
action = "已导出" if changed else "无变化"
|
||||
messages.append(f"{action}:{target.relative_to(root)} <- {page_name}@{revision[:12]}")
|
||||
return messages
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 子命令入口
|
||||
|
||||
|
||||
def run_check(args: argparse.Namespace) -> int:
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
check_required_files(errors)
|
||||
@@ -465,5 +593,132 @@ def main() -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def run_sync(args: argparse.Namespace) -> int:
|
||||
"""--verify 依次执行导出、结构检查和一致性校验,替代原来的三条命令。"""
|
||||
|
||||
if args.verify:
|
||||
steps = (
|
||||
("同步", lambda: run_sync(
|
||||
argparse.Namespace(check=False, verify=False, config=args.config))),
|
||||
("结构检查", lambda: run_check(argparse.Namespace(strict=True))),
|
||||
("一致性校验", lambda: run_sync(
|
||||
argparse.Namespace(check=True, verify=False, config=args.config))),
|
||||
)
|
||||
for name, step in steps:
|
||||
code = step()
|
||||
if code != 0:
|
||||
print(f"错误:{name}未通过,已停止")
|
||||
return code
|
||||
return 0
|
||||
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
messages = sync_all(config, WikiClient(config), check=args.check)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
for message in messages:
|
||||
print(message)
|
||||
print("Wiki 镜像检查通过" if args.check else "Wiki 镜像同步完成")
|
||||
return 0
|
||||
|
||||
|
||||
def run_archive(args: argparse.Namespace) -> int:
|
||||
short_title = safe_title(args.title)
|
||||
if not args.issue_number.isdigit():
|
||||
print("错误:工单号必须是数字")
|
||||
return 1
|
||||
if not short_title:
|
||||
print("错误:标题不能为空")
|
||||
return 1
|
||||
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
page_name = f"Task-{args.issue_number}-{short_title}"
|
||||
client = WikiClient(config)
|
||||
if any(item.get("title") == page_name for item in client.list_pages()):
|
||||
raise WikiDocsError(f"任务归档已经存在:{page_name}")
|
||||
template = client.get_page("Task-Archive-Template").text
|
||||
issue_url = (
|
||||
f"{config.gitea_url}/{config.owner}/{config.repository}/issues/"
|
||||
f"{args.issue_number}"
|
||||
)
|
||||
content = build_archive(
|
||||
template, args.issue_number, args.title, page_name, issue_url
|
||||
)
|
||||
page = client.create_page(
|
||||
page_name,
|
||||
content,
|
||||
f"docs: 创建任务 #{args.issue_number} 归档草稿",
|
||||
)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
|
||||
print(f"已创建 Wiki:{page.html_url}")
|
||||
print("未导出本地任务归档;需要时运行 harness.py export")
|
||||
return 0
|
||||
|
||||
|
||||
def run_export(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
messages = export_task_archives(WikiClient(config), export_all=args.all)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
for message in messages:
|
||||
print(message)
|
||||
print("任务归档全量导出完成" if args.all else "任务归档增量导出完成")
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="DevHarness 检查、同步与归档工具")
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
p_check = sub.add_parser("check", help="检查 DevHarness 项目结构")
|
||||
p_check.add_argument(
|
||||
"--strict", action="store_true", help="项目档案有占位内容时返回失败"
|
||||
)
|
||||
p_check.set_defaults(func=run_check)
|
||||
|
||||
p_sync = sub.add_parser("sync", help="从 Gitea Wiki 单向同步核心 docs 镜像")
|
||||
p_sync.add_argument(
|
||||
"--check", action="store_true", help="只检查 Wiki 与镜像是否一致,不写文件"
|
||||
)
|
||||
p_sync.add_argument(
|
||||
"--verify",
|
||||
action="store_true",
|
||||
help="依次执行导出、check --strict 和一致性校验",
|
||||
)
|
||||
p_sync.add_argument(
|
||||
"--config", default=str(DEFAULT_CONFIG), help="Wiki 页面映射 JSON 文件"
|
||||
)
|
||||
p_sync.set_defaults(func=run_sync)
|
||||
|
||||
p_archive = sub.add_parser("archive", help="在 Gitea Wiki 创建任务归档")
|
||||
p_archive.add_argument("issue_number", help="Gitea 工单号,例如 123")
|
||||
p_archive.add_argument("title", help="简短任务标题")
|
||||
p_archive.add_argument(
|
||||
"--config", default=str(DEFAULT_CONFIG), help="Wiki 映射配置"
|
||||
)
|
||||
p_archive.set_defaults(func=run_archive)
|
||||
|
||||
p_export = sub.add_parser("export", help="人工按需导出 Gitea Wiki 任务归档")
|
||||
p_export.add_argument(
|
||||
"--all",
|
||||
action="store_true",
|
||||
help="全量读取全部线上任务归档;默认按 revision 增量",
|
||||
)
|
||||
p_export.add_argument(
|
||||
"--config", default=str(DEFAULT_CONFIG), help="核心 Wiki 映射配置"
|
||||
)
|
||||
p_export.set_defaults(func=run_export)
|
||||
|
||||
args = parser.parse_args()
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,87 +0,0 @@
|
||||
"""只在 Gitea Wiki 创建任务归档;本地镜像由人工按需导出。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
|
||||
from wiki_docs import (
|
||||
DEFAULT_CONFIG,
|
||||
WikiClient,
|
||||
WikiDocsError,
|
||||
load_config,
|
||||
)
|
||||
|
||||
|
||||
def safe_title(title: str) -> str:
|
||||
"""把标题转换为适合 Wiki 页面名和 Windows 文件名的短文本。"""
|
||||
|
||||
cleaned = re.sub(r'[<>:"/\\|?*]', "-", title.strip())
|
||||
cleaned = re.sub(r"\s+", "-", cleaned)
|
||||
cleaned = re.sub(r"-+", "-", cleaned)
|
||||
return cleaned.strip(".-")
|
||||
|
||||
|
||||
def build_archive(
|
||||
template: str,
|
||||
issue_number: str,
|
||||
title: str,
|
||||
page_name: str,
|
||||
issue_url: str,
|
||||
) -> str:
|
||||
content = template.replace("<工单号>", issue_number, 1)
|
||||
content = content.replace("<标题>", title.strip(), 1)
|
||||
content = content.replace("YYYY-MM-DD", date.today().isoformat(), 1)
|
||||
content = content.replace("<链接>", issue_url, 1)
|
||||
return content.replace("<页面名>", page_name, 1)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="在 Gitea Wiki 创建任务归档,不自动导出本地镜像"
|
||||
)
|
||||
parser.add_argument("issue_number", help="Gitea 工单号,例如 123")
|
||||
parser.add_argument("title", help="简短任务标题")
|
||||
parser.add_argument("--config", default=str(DEFAULT_CONFIG), help="Wiki 映射配置")
|
||||
args = parser.parse_args()
|
||||
|
||||
short_title = safe_title(args.title)
|
||||
if not args.issue_number.isdigit():
|
||||
print("错误:工单号必须是数字")
|
||||
return 1
|
||||
if not short_title:
|
||||
print("错误:标题不能为空")
|
||||
return 1
|
||||
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
page_name = f"Task-{args.issue_number}-{short_title}"
|
||||
client = WikiClient(config)
|
||||
if any(item.get("title") == page_name for item in client.list_pages()):
|
||||
raise WikiDocsError(f"任务归档已经存在:{page_name}")
|
||||
template = client.get_page("Task-Archive-Template").text
|
||||
issue_url = (
|
||||
f"{config.gitea_url}/{config.owner}/{config.repository}/issues/"
|
||||
f"{args.issue_number}"
|
||||
)
|
||||
content = build_archive(
|
||||
template, args.issue_number, args.title, page_name, issue_url
|
||||
)
|
||||
page = client.create_page(
|
||||
page_name,
|
||||
content,
|
||||
f"docs: 创建任务 #{args.issue_number} 归档草稿",
|
||||
)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
|
||||
print(f"已创建 Wiki:{page.html_url}")
|
||||
print("未导出本地任务归档;需要时运行 export_task_archives.py")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,33 +0,0 @@
|
||||
"""从 Gitea Wiki 单向导出配置中的核心 docs 镜像。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from wiki_docs import DEFAULT_CONFIG, WikiClient, WikiDocsError, load_config, sync_all
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="从 Gitea Wiki 单向同步核心 docs 镜像")
|
||||
parser.add_argument(
|
||||
"--check", action="store_true", help="只检查 Wiki 与镜像是否一致,不写文件"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--config", default=str(DEFAULT_CONFIG), help="Wiki 页面映射 JSON 文件"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
config = load_config(Path(args.config).resolve())
|
||||
messages = sync_all(config, WikiClient(config), check=args.check)
|
||||
except WikiDocsError as exc:
|
||||
print(f"错误:{exc}")
|
||||
return 1
|
||||
for message in messages:
|
||||
print(message)
|
||||
print("Wiki 镜像检查通过" if args.check else "Wiki 镜像同步完成")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user