三处写入侧的缺口,都是被下游"模块银行"(module_bank,把模块打包进 svfs 包 再按需导入)真实逼出来的: - add_bytes(rel_path, data, ...):从内存写文件,不经过磁盘。受保护的字节码、 密文这类绝对不能落盘的内容因此可以直接入库——先写临时文件再 add_file 会把 明文留在磁盘上,而磁盘残留是这类工具最容易被忽视的泄漏点。 - make_parents=True(默认):补齐缺失的父目录行。list_directory 是按 parent_path 过滤的,而"某个目录存在"的唯一标志就是它自己那一行——少一层 目录行,export_directory 从根就递归不下去,export_filesystem() 会静默导出 一个空目录。add_file 一并受益(内部改为读盘后调 add_bytes,行为不变, 含 created_time 取 st_ctime 这个细节)。 - commit=False + 公开的 commit():一组相关文件可以写成一个事务,中途任何一步 失败整批回滚,不会在库里留下半套数据。 - rename_snapshot(id, name):create/list/delete 都有,唯独缺改名;而"把发布名 落在快照上"是版本管理的基本动作。**定格一个版本靠的正是它**:先给当前快照 改名,再另建一个工作快照接手后续写入——直接 create_snapshot(name) 的话, 名字落在会继续被写入的那一版上,下一次改动就把这个"版本"改了。 - DEFAULT_DIR_PERMISSIONS:补出来的目录行用 0o755(表的默认值 0o644 是按文件 定的,套到目录上会让导出的目录不可进入)。 - 版本 0.3.0 → 0.4.0(add_file 开始建父目录行属于可见的行为变化)。 测试:tests/test_core_add_bytes.py(22 条:往返/空内容/bytearray/时间戳与权限/ 压缩/去重/覆盖/空路径/只读拒绝/父目录行与 export 目录树/批量提交与回滚/ add_file 委托行为)+ tests/test_snapshots.py 新增 5 条改名用例(只改名字不动 内容与摘要/空名拒绝/不存在的快照报错/允许重名/改名+派生工作快照之后 已定格的版本不被后续写入改动)。完整测试套件逐个文件跑通。
93 lines
3.9 KiB
TOML
93 lines
3.9 KiB
TOML
[project]
|
||
dependencies = []
|
||
description = "sqlite virtual file system"
|
||
name = "sqlite-vfs"
|
||
readme = "README.md"
|
||
# 版本门槛按实际用到的 API 推导,不是拍的:
|
||
# * contrib/fastapi_static.py 用了 hashlib.md5(..., usedforsecurity=False) → 3.9+
|
||
# * 测试用了 random.Random.randbytes → 3.9+
|
||
# 核心(core/compression/migration/publish/folder_*)本身只用到 3.7 就有的东西;
|
||
# 仓库里没有 3.10+ 的语法(无 match、无 PEP 604 注解、无 zip(strict=))。
|
||
# 说明:这里只在本机的 3.13 上跑过,"3.9 可用"是代码审查的结论,没有在 3.9 上实测。
|
||
requires-python = ">=3.9"
|
||
# 0.4.0: 新增 SQLiteVFS.add_bytes() / commit()(从内存写文件,不经过磁盘),
|
||
# 且 add_file/add_bytes 默认会补齐缺失的父目录行——后者是可见的行为变化
|
||
# (会让 export_directory/export_filesystem 从根递归得下去),所以抬次版本号。
|
||
version = "0.4.0"
|
||
|
||
# 可选集成:核心功能只用标准库,第三方框架一律走 extras。
|
||
# 例如 pip install "sqlite-vfs[fastapi]" 才会装上 FastAPI/Starlette。
|
||
[project.optional-dependencies]
|
||
fastapi = [
|
||
"fastapi>=0.100",
|
||
"starlette>=0.27",
|
||
"uvicorn>=0.23",
|
||
"python-multipart>=0.0.6",
|
||
]
|
||
# 消息模块的 MQTT 推送通道(服务端主动推消息给客户端)。
|
||
# 不装也不影响消息中心:登录后的 HTTP 补齐照常工作,只是没有实时推送。
|
||
# 客户端在缺这个库时会在消息中心显示"未启用 MQTT",不会报错。
|
||
mqtt = [
|
||
"paho-mqtt>=2.0",
|
||
]
|
||
# 桌面工具用的 Qt 绑定。核心库与 CLI 依然零第三方依赖,所以放在 extra 里。
|
||
#
|
||
# 三个 extra 的分工(都装着 PySide6,区别只在要不要 WebEngine):
|
||
# studio —— svfs-studio(仅 QtCore/QtGui/QtWidgets,Essentials 就够)
|
||
# client —— svfs-client(QWebEngineView 在 PySide6-Essentials 里**没有**,
|
||
# 必须完整版)
|
||
# gui —— 两个桌面应用都装的合集,保留它是为了不破坏既有文档里的
|
||
# `uv sync --extra gui` / `sqlite-vfs[gui]` 写法
|
||
studio = [
|
||
"PySide6-Essentials>=6.6",
|
||
]
|
||
client = [
|
||
"PySide6>=6.6",
|
||
]
|
||
gui = [
|
||
"PySide6>=6.6",
|
||
]
|
||
|
||
[[tool.uv.index]]
|
||
default = true
|
||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||
|
||
# 说明:这里原先有 [tool.uv.workspace] members = ["devmo"],但仓库里没有 devmo 目录。
|
||
# 实测 uv 0.11.8 容忍这种写法(uv sync --dry-run 退出码 0),所以它不是阻塞项,
|
||
# 只是会误导人,因此删掉。
|
||
|
||
[build-system]
|
||
build-backend = "hatchling.build"
|
||
requires = ["hatchling"]
|
||
|
||
[dependency-groups]
|
||
dev = [
|
||
"twine>=4.0.2",
|
||
# starlette 1.6+ 的 TestClient(tests/test_plugin_server.py 用)需要它
|
||
"httpx2>=0.1",
|
||
# 消息模块的 MQTT 通道:测试里用真 paho 客户端对自建的最小 broker 跑端到端
|
||
# (见 tests/test_client_mqtt.py),所以开发环境需要它
|
||
"paho-mqtt>=2.0",
|
||
]
|
||
|
||
[project.scripts]
|
||
# 统一入口(推荐):svfs <子命令>
|
||
svfs = "sqlite_vfs.cli.main:main"
|
||
# 旧的独立命令保留为别名(与 svfs <同名子命令> 同一段实现)
|
||
vfspack = "sqlite_vfs.cli.packer:pack"
|
||
vfsunpack = "sqlite_vfs.cli.unpacker:unpack"
|
||
vfsverify = "sqlite_vfs.cli.verify:verify"
|
||
vfsmigrate = "sqlite_vfs.cli.migrate:main"
|
||
vfspublish = "sqlite_vfs.cli.publish:publish_objects"
|
||
vfsfetch = "sqlite_vfs.cli.fetch:fetch_objects"
|
||
svfs-studio = "svfs_studio.__main__:main"
|
||
svfs-client = "svfs_client.__main__:main"
|
||
|
||
[tool.hatch.build.targets.wheel]
|
||
# 三个包必须一起打:`svfs-studio` / `svfs-client` 两个 console script 在上面
|
||
# 声明了,svfs_client 还 import svfs_studio 的主题与基础部件(UI 套件)——
|
||
# 只打 sqlite_vfs 的话,pip 装完命令存在但模块不在(ImportError)。
|
||
# 不装 Qt([gui] extra)也能安全安装:这三个包在导入前都不会碰 PySide6
|
||
# (纯标准库层见 svfs_client/__init__.py 的分层说明)。
|
||
packages = ["src/sqlite_vfs", "src/svfs_studio", "src/svfs_client"]
|