统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口 完成项目 TypeScript/Prettier 与 Rust 全量格式化 修复 Pingora expected executable 门禁的空白敏感误报 同步开发运维文档与 AGC skill pack 格式化忽略规则
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import {mkdtempSync, readFileSync, rmSync, writeFileSync} from 'node:fs';
|
||||
import {createServer} from 'node:net';
|
||||
import {tmpdir} from 'node:os';
|
||||
import {join} from 'node:path';
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { createServer } from 'node:net';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
findAvailablePort,
|
||||
@@ -37,7 +37,7 @@ async function reserveConsecutivePorts() {
|
||||
|
||||
try {
|
||||
const secondServer = await reservePort(firstPort + 1);
|
||||
return {firstServer, secondServer, firstPort};
|
||||
return { firstServer, secondServer, firstPort };
|
||||
} catch {
|
||||
await new Promise((resolve) => firstServer.close(resolve));
|
||||
}
|
||||
@@ -67,7 +67,8 @@ describe('dev stack port utils', () => {
|
||||
});
|
||||
|
||||
it('使用端口可用性检查为被占用端口寻找后续可用端口', async () => {
|
||||
const {firstServer, secondServer, firstPort} = await reserveConsecutivePorts();
|
||||
const { firstServer, secondServer, firstPort } =
|
||||
await reserveConsecutivePorts();
|
||||
|
||||
try {
|
||||
const availablePort = await findAvailablePort({
|
||||
@@ -106,18 +107,18 @@ describe('dev stack port utils', () => {
|
||||
findAvailablePort({
|
||||
host: '127.0.0.1',
|
||||
preferredPort: 9999,
|
||||
portRange: {start: 10000, end: 10099, label: '10000-10099'},
|
||||
portRange: { start: 10000, end: 10099, label: '10000-10099' },
|
||||
}),
|
||||
).rejects.toThrow('不在允许端口段');
|
||||
});
|
||||
|
||||
it('为 npm run dev 的所有后续流程解析互不冲突的端口', async () => {
|
||||
const resolvedPorts = await resolveDevStackPorts({
|
||||
spacetime: {host: '127.0.0.1', preferredPort: 0},
|
||||
api: {host: '127.0.0.1', preferredPort: 0},
|
||||
web: {host: '127.0.0.1', preferredPort: 0},
|
||||
adminWeb: {host: '127.0.0.1', preferredPort: 0},
|
||||
bgfilterWorker: {host: '127.0.0.1', preferredPort: 0},
|
||||
spacetime: { host: '127.0.0.1', preferredPort: 0 },
|
||||
api: { host: '127.0.0.1', preferredPort: 0 },
|
||||
web: { host: '127.0.0.1', preferredPort: 0 },
|
||||
adminWeb: { host: '127.0.0.1', preferredPort: 0 },
|
||||
bgfilterWorker: { host: '127.0.0.1', preferredPort: 0 },
|
||||
});
|
||||
|
||||
expect(new Set(Object.values(resolvedPorts)).size).toBe(5);
|
||||
@@ -130,9 +131,9 @@ describe('dev stack port utils', () => {
|
||||
|
||||
const resolvedPorts = await resolveDevStackPorts(
|
||||
{
|
||||
api: {host: '127.0.0.1', preferredPort},
|
||||
api: { host: '127.0.0.1', preferredPort },
|
||||
},
|
||||
{reservedPorts: new Set([preferredPort])},
|
||||
{ reservedPorts: new Set([preferredPort]) },
|
||||
);
|
||||
|
||||
expect(resolvedPorts.api).toBeGreaterThan(preferredPort);
|
||||
@@ -142,14 +143,18 @@ describe('dev stack port utils', () => {
|
||||
const rangeStart = 10000;
|
||||
const rangeEnd = 10300;
|
||||
const reservedPorts = new Set(
|
||||
Array.from({length: 201}, (_, index) => rangeStart + index),
|
||||
Array.from({ length: 201 }, (_, index) => rangeStart + index),
|
||||
);
|
||||
|
||||
const availablePort = await findAvailablePort({
|
||||
host: '127.0.0.1',
|
||||
preferredPort: rangeStart,
|
||||
reservedPorts,
|
||||
portRange: {start: rangeStart, end: rangeEnd, label: `${rangeStart}-${rangeEnd}`},
|
||||
portRange: {
|
||||
start: rangeStart,
|
||||
end: rangeEnd,
|
||||
label: `${rangeStart}-${rangeEnd}`,
|
||||
},
|
||||
});
|
||||
|
||||
expect(availablePort).toBeGreaterThan(rangeStart + 200);
|
||||
@@ -172,7 +177,7 @@ describe('dev stack port utils', () => {
|
||||
allocations: {
|
||||
alice: {
|
||||
username: 'alice',
|
||||
range: {start: 10000, end: 10004, label: '10000-10004'},
|
||||
range: { start: 10000, end: 10004, label: '10000-10004' },
|
||||
claimedAt: '2026-08-01T00:00:00.000Z',
|
||||
updatedAt: '2026-08-01T00:00:00.000Z',
|
||||
source: 'manual',
|
||||
@@ -198,7 +203,7 @@ describe('dev stack port utils', () => {
|
||||
expect(registry.allocations.alice.range.label).toBe('10000-10004');
|
||||
expect(registry.allocations.bob.range.label).toBe('10100-10199');
|
||||
} finally {
|
||||
rmSync(tempRoot, {recursive: true, force: true});
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -216,7 +221,7 @@ describe('dev stack port utils', () => {
|
||||
allocations: {
|
||||
alice: {
|
||||
username: 'alice',
|
||||
range: {start: 10000, end: 10004, label: '10000-10004'},
|
||||
range: { start: 10000, end: 10004, label: '10000-10004' },
|
||||
claimedAt: '2026-08-01T00:00:00.000Z',
|
||||
updatedAt: '2026-08-01T00:00:00.000Z',
|
||||
source: 'manual',
|
||||
@@ -243,47 +248,50 @@ describe('dev stack port utils', () => {
|
||||
.label,
|
||||
).toBe('10000-10005');
|
||||
} finally {
|
||||
rmSync(tempRoot, {recursive: true, force: true});
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
linuxIt('Linux 未手动指定端口段时从 10000 开始按 100 端口块自动分配', async () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), 'genarrative-port-range-'));
|
||||
const registryPath = join(tempRoot, 'registry.json');
|
||||
const lockPath = join(tempRoot, 'registry.lock');
|
||||
linuxIt(
|
||||
'Linux 未手动指定端口段时从 10000 开始按 100 端口块自动分配',
|
||||
async () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), 'genarrative-port-range-'));
|
||||
const registryPath = join(tempRoot, 'registry.json');
|
||||
const lockPath = join(tempRoot, 'registry.lock');
|
||||
|
||||
try {
|
||||
const aliceAllocation = await reserveLinuxDevPortRange({
|
||||
env: {
|
||||
USER: 'alice',
|
||||
LOGNAME: 'alice',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
},
|
||||
username: 'alice',
|
||||
requestedRange: null,
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
const bobAllocation = await reserveLinuxDevPortRange({
|
||||
env: {
|
||||
USER: 'bob',
|
||||
LOGNAME: 'bob',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
},
|
||||
username: 'bob',
|
||||
requestedRange: null,
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
try {
|
||||
const aliceAllocation = await reserveLinuxDevPortRange({
|
||||
env: {
|
||||
USER: 'alice',
|
||||
LOGNAME: 'alice',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
},
|
||||
username: 'alice',
|
||||
requestedRange: null,
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
const bobAllocation = await reserveLinuxDevPortRange({
|
||||
env: {
|
||||
USER: 'bob',
|
||||
LOGNAME: 'bob',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
},
|
||||
username: 'bob',
|
||||
requestedRange: null,
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
|
||||
expect(aliceAllocation.range.label).toBe('10000-10099');
|
||||
expect(aliceAllocation.source).toBe('auto');
|
||||
expect(bobAllocation.range.label).toBe('10100-10199');
|
||||
expect(bobAllocation.source).toBe('auto');
|
||||
} finally {
|
||||
rmSync(tempRoot, {recursive: true, force: true});
|
||||
}
|
||||
});
|
||||
expect(aliceAllocation.range.label).toBe('10000-10099');
|
||||
expect(aliceAllocation.source).toBe('auto');
|
||||
expect(bobAllocation.range.label).toBe('10100-10199');
|
||||
expect(bobAllocation.source).toBe('auto');
|
||||
} finally {
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
linuxIt('Linux 系统级端口段记录会阻止两个用户拿到同一段', async () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), 'genarrative-port-range-'));
|
||||
@@ -308,7 +316,9 @@ describe('dev stack port utils', () => {
|
||||
expect(aliceAllocation.range.label).toBe('10000-10099');
|
||||
|
||||
const registryAfterAlice = JSON.parse(readFileSync(registryPath, 'utf8'));
|
||||
expect(registryAfterAlice.allocations.alice.range.label).toBe('10000-10099');
|
||||
expect(registryAfterAlice.allocations.alice.range.label).toBe(
|
||||
'10000-10099',
|
||||
);
|
||||
|
||||
await expect(
|
||||
reserveLinuxDevPortRange({
|
||||
@@ -355,7 +365,9 @@ describe('dev stack port utils', () => {
|
||||
).toBe('10000-10099');
|
||||
|
||||
const registryAfterReuse = JSON.parse(readFileSync(registryPath, 'utf8'));
|
||||
expect(registryAfterReuse.allocations.alice.range.label).toBe('10000-10099');
|
||||
expect(registryAfterReuse.allocations.alice.range.label).toBe(
|
||||
'10000-10099',
|
||||
);
|
||||
|
||||
const bobAllocation = await reserveLinuxDevPortRange({
|
||||
env: {
|
||||
@@ -372,45 +384,49 @@ describe('dev stack port utils', () => {
|
||||
|
||||
expect(bobAllocation.range.label).toBe('10100-10199');
|
||||
} finally {
|
||||
rmSync(tempRoot, {recursive: true, force: true});
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
linuxIt('Linux 同一用户第二个 dev 会话会复用同一用户段并继续在段内漂移', async () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), 'genarrative-port-range-'));
|
||||
const registryPath = join(tempRoot, 'registry.json');
|
||||
const lockPath = join(tempRoot, 'registry.lock');
|
||||
linuxIt(
|
||||
'Linux 同一用户第二个 dev 会话会复用同一用户段并继续在段内漂移',
|
||||
async () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), 'genarrative-port-range-'));
|
||||
const registryPath = join(tempRoot, 'registry.json');
|
||||
const lockPath = join(tempRoot, 'registry.lock');
|
||||
|
||||
try {
|
||||
const baseEnv = {
|
||||
USER: 'alice',
|
||||
LOGNAME: 'alice',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
GENARRATIVE_DEV_PORT_RANGE: '10000-10099',
|
||||
};
|
||||
try {
|
||||
const baseEnv = {
|
||||
USER: 'alice',
|
||||
LOGNAME: 'alice',
|
||||
GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR: tempRoot,
|
||||
GENARRATIVE_DEV_PORT_RANGE: '10000-10099',
|
||||
};
|
||||
|
||||
const first = await reserveLinuxDevPortRange({
|
||||
env: baseEnv,
|
||||
username: 'alice',
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
const first = await reserveLinuxDevPortRange({
|
||||
env: baseEnv,
|
||||
username: 'alice',
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
|
||||
const second = await reserveLinuxDevPortRange({
|
||||
env: baseEnv,
|
||||
username: 'alice',
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
const second = await reserveLinuxDevPortRange({
|
||||
env: baseEnv,
|
||||
username: 'alice',
|
||||
registryPath,
|
||||
lockPath,
|
||||
});
|
||||
|
||||
expect(first.range.label).toBe('10000-10099');
|
||||
expect(second.range.label).toBe('10000-10099');
|
||||
expect(second.username).toBe('alice');
|
||||
expect(JSON.parse(readFileSync(registryPath, 'utf8')).allocations.alice.range.label).toBe(
|
||||
'10000-10099',
|
||||
);
|
||||
} finally {
|
||||
rmSync(tempRoot, {recursive: true, force: true});
|
||||
}
|
||||
});
|
||||
expect(first.range.label).toBe('10000-10099');
|
||||
expect(second.range.label).toBe('10000-10099');
|
||||
expect(second.username).toBe('alice');
|
||||
expect(
|
||||
JSON.parse(readFileSync(registryPath, 'utf8')).allocations.alice.range
|
||||
.label,
|
||||
).toBe('10000-10099');
|
||||
} finally {
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user