fix(clean): 物理 tgz 按文件匹配删除 + semver 完整语义排序
- 新增 tgz.js:统一列出包目录物理 .tgz 文件,支持新版 {version}.tgz 精确匹配
与旧版 {pkgname}-{version}.tgz 后缀匹配,删除按真实文件 size 统计
- semver.js 重写:完整 npm 语义比较(prerelease 逐标识比较、数字<非数字、
公共前缀更长者更大),修复原实现剥离 prerelease 导致 beta 挤掉正式版的隐患
- clean.js / scanner.js / server.js 接入统一口径
- 新增 test/semver.test.js 与 test/tgz.test.js 回归测试(node --test)
This commit is contained in:
+7
-12
@@ -7,6 +7,7 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { getSetting } from './db.js'
|
||||
import { listTgzFiles } from './tgz.js'
|
||||
|
||||
// —— storage 目录解析 ——
|
||||
export function resolveStorageDir() {
|
||||
@@ -153,22 +154,16 @@ export function scanStorage(storageDir) {
|
||||
for (const pkgDir of pkgDirs) {
|
||||
const pkgFile = path.join(pkgDir, 'package.json')
|
||||
|
||||
// 物理 .tgz 文件:先列目录建立文件名 → 大小索引
|
||||
// (Verdaccio 各版本命名不同:{version}.tgz 或 {pkgname}-{version}.tgz,不猜、直接扫)
|
||||
// 物理 .tgz 文件:命名规则({version}.tgz / {pkgname}-{version}.tgz)统一由 tgz.js 解析
|
||||
// 先统计再读元数据:即使元数据损坏也能算出真实占用
|
||||
const tgzSizes = new Map()
|
||||
let tgzTotal = 0
|
||||
let tgzLatest = 0 // 最新 .tgz 文件 mtime(毫秒):今天缓存了新版本也算「今天更新」
|
||||
try {
|
||||
for (const f of fs.readdirSync(pkgDir)) {
|
||||
if (!f.endsWith('.tgz')) continue
|
||||
const st = fs.statSync(path.join(pkgDir, f))
|
||||
const size = st.size
|
||||
tgzTotal += size
|
||||
tgzSizes.set(f.slice(0, -4), size)
|
||||
if (st.mtimeMs > tgzLatest) tgzLatest = st.mtimeMs
|
||||
}
|
||||
} catch {}
|
||||
for (const f of listTgzFiles(pkgDir)) {
|
||||
tgzTotal += f.size
|
||||
tgzSizes.set(f.key, f.size)
|
||||
if (f.mtimeMs > tgzLatest) tgzLatest = f.mtimeMs
|
||||
}
|
||||
|
||||
const meta = readJson(pkgFile)
|
||||
if (!meta) {
|
||||
|
||||
Reference in New Issue
Block a user