feat: 变更名限制为中文、英文和短横线
This commit is contained in:
12
src/cli.ts
12
src/cli.ts
@@ -26,6 +26,15 @@ function requireProjectRoot(): string {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateChangeName(name: string): void {
|
||||||
|
if (!/^[\u4e00-\u9fa5a-zA-Z-]+$/.test(name)) {
|
||||||
|
throw new CommandError(
|
||||||
|
`变更名 "${name}" 包含不支持的字符`,
|
||||||
|
{ hint: "变更名仅支持中文、英文和短横线(-)" },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function formatChangeStatus(change: ChangeStatus): string {
|
function formatChangeStatus(change: ChangeStatus): string {
|
||||||
const lines: string[] = [];
|
const lines: string[] = [];
|
||||||
lines.push(`变更:${change.name}`);
|
lines.push(`变更:${change.name}`);
|
||||||
@@ -129,6 +138,7 @@ cli.command("discuss", "讨论阶段").action(async () => {
|
|||||||
|
|
||||||
cli.command("plan <change-name> <document-name>", "规划阶段").action(
|
cli.command("plan <change-name> <document-name>", "规划阶段").action(
|
||||||
async (changeName: string, documentName: string) => {
|
async (changeName: string, documentName: string) => {
|
||||||
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
const config = await loadConfig(root);
|
const config = await loadConfig(root);
|
||||||
const planDocs = config.stages.plan?.documents;
|
const planDocs = config.stages.plan?.documents;
|
||||||
@@ -166,6 +176,7 @@ cli.command("plan <change-name> <document-name>", "规划阶段").action(
|
|||||||
|
|
||||||
cli.command("build <change-name>", "构建阶段").action(
|
cli.command("build <change-name>", "构建阶段").action(
|
||||||
async (changeName: string) => {
|
async (changeName: string) => {
|
||||||
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
@@ -181,6 +192,7 @@ cli.command("build <change-name>", "构建阶段").action(
|
|||||||
|
|
||||||
cli.command("archive <change-name>", "归档阶段").action(
|
cli.command("archive <change-name>", "归档阶段").action(
|
||||||
async (changeName: string) => {
|
async (changeName: string) => {
|
||||||
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
|
|||||||
@@ -153,3 +153,24 @@ describe("完整 SDD 流程", () => {
|
|||||||
expect(taskDoc!.dependMet).toBe(true);
|
expect(taskDoc!.dependMet).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("变更名校验", () => {
|
||||||
|
it("合法变更名(中文、英文、短横线)通过校验", async () => {
|
||||||
|
await runInit(TMP_DIR, ["opencode"]);
|
||||||
|
const config = await loadConfig(TMP_DIR);
|
||||||
|
await mkdir(getChangeDir(TMP_DIR, "用户-login"), { recursive: true });
|
||||||
|
await writeFile(join(getChangeDir(TMP_DIR, "用户-login"), "design.md"), "# 设计");
|
||||||
|
await writeFile(join(getChangeDir(TMP_DIR, "用户-login"), "task.md"), "- [ ] 任务");
|
||||||
|
const prompt = await assemblePlanPrompt(config, TMP_DIR, "用户-login", "design");
|
||||||
|
expect(prompt).toContain("用户-login");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("非法变更名(空格、下划线、特殊符号)被拒绝", () => {
|
||||||
|
const validRegex = /^[\u4e00-\u9fa5a-zA-Z-]+$/;
|
||||||
|
expect(validRegex.test("my change")).toBe(false);
|
||||||
|
expect(validRegex.test("my_change")).toBe(false);
|
||||||
|
expect(validRegex.test("my-change!")).toBe(false);
|
||||||
|
expect(validRegex.test("my.change")).toBe(false);
|
||||||
|
expect(validRegex.test("")).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user