Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 402908e

Browse files
committed
Replace custom yaml parser with dependency
1 parent aa199d1 commit 402908e

4 files changed

Lines changed: 30 additions & 90 deletions

File tree

.changeset/lazy-ads-notice.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"ultracite": patch
3+
---
4+
5+
Replace custom yaml parser with dependency

bun.lock

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"glob": "^13.0.6",
6464
"jsonc-parser": "^3.3.1",
6565
"nypm": "^0.6.5",
66+
"yaml": "^2.8.3",
6667
"zod": "^4.3.2"
6768
},
6869
"devDependencies": {

packages/cli/src/integrations/lint-staged.ts

Lines changed: 19 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import deepmerge from "deepmerge";
55
import { parse } from "jsonc-parser";
66
import { addDevDependency, dlxCommand } from "nypm";
77
import type { PackageManager, PackageManagerName } from "nypm";
8+
import YAML from "yaml";
89

910
import { parsePackageJson } from "../schemas";
1011
import { exists, isMonorepo } from "../utils";
@@ -33,88 +34,6 @@ const configFiles = [
3334
"./.lintstagedrc",
3435
];
3536

36-
// Helper function to process YAML lines
37-
const processYamlLine = (
38-
line: string,
39-
result: Record<string, unknown>,
40-
currentKey: string | null,
41-
currentArray: string[]
42-
): { newCurrentKey: string | null; newCurrentArray: string[] } => {
43-
const trimmed = line.trim();
44-
45-
if (trimmed.includes(":") && !trimmed.startsWith("-")) {
46-
// Save previous array if exists
47-
if (currentKey && currentArray.length > 0) {
48-
result[currentKey] = currentArray;
49-
}
50-
51-
const [key, ...valueParts] = trimmed.split(":");
52-
const value = valueParts.join(":").trim();
53-
const newCurrentKey = key.trim().replaceAll(/['"]/g, "");
54-
55-
if (value && value !== "") {
56-
result[newCurrentKey] =
57-
value.startsWith("[") && value.endsWith("]")
58-
? value
59-
.slice(1, -1)
60-
.split(",")
61-
.map((v) => v.trim().replaceAll(/['"]/g, ""))
62-
: value.replaceAll(/['"]/g, "");
63-
return { newCurrentArray: [], newCurrentKey: null };
64-
}
65-
return { newCurrentArray: [], newCurrentKey };
66-
}
67-
68-
if (trimmed.startsWith("-") && currentKey) {
69-
const newCurrentArray = [
70-
...currentArray,
71-
trimmed.slice(1).trim().replaceAll(/['"]/g, ""),
72-
];
73-
return { newCurrentArray, newCurrentKey: currentKey };
74-
}
75-
76-
return { newCurrentArray: currentArray, newCurrentKey: currentKey };
77-
};
78-
79-
// Simple YAML parser for basic objects (limited but functional)
80-
const parseSimpleYaml = (content: string): Record<string, unknown> => {
81-
const lines = content
82-
.split("\n")
83-
.filter((line) => line.trim() && !line.trim().startsWith("#"));
84-
const result: Record<string, unknown> = {};
85-
let currentKey: string | null = null;
86-
let currentArray: string[] = [];
87-
88-
for (const line of lines) {
89-
const processed = processYamlLine(line, result, currentKey, currentArray);
90-
currentKey = processed.newCurrentKey;
91-
currentArray = processed.newCurrentArray;
92-
}
93-
94-
// Save final array if exists
95-
if (currentKey && currentArray.length > 0) {
96-
result[currentKey] = currentArray;
97-
}
98-
99-
return result;
100-
};
101-
102-
// Convert object to simple YAML format
103-
const stringifySimpleYaml = (obj: Record<string, unknown>): string => {
104-
let yaml = "";
105-
for (const [key, value] of Object.entries(obj)) {
106-
if (Array.isArray(value)) {
107-
yaml += `${key}:\n`;
108-
for (const item of value) {
109-
yaml += ` - '${item}'\n`;
110-
}
111-
} else {
112-
yaml += `${key}: '${value}'\n`;
113-
}
114-
}
115-
return yaml;
116-
};
117-
11837
// Check if project uses ESM
11938
const isProjectEsm = async (): Promise<boolean> => {
12039
try {
@@ -171,17 +90,29 @@ const updateJsonConfig = async (
17190
await writeFile(filename, `${JSON.stringify(mergedConfig, null, 2)}\n`);
17291
};
17392

93+
// Quote unquoted glob pattern keys that YAML would misinterpret as aliases or tags
94+
const quoteGlobKeys = (content: string): string =>
95+
content.replaceAll(
96+
/^([*?{[][^\n:]*):(.*)$/gm,
97+
(_match, key: string, rest: string) => `'${key}':${rest}`
98+
);
99+
174100
// Update YAML config files
175101
const updateYamlConfig = async (
176102
filename: string,
177103
packageManager: PackageManagerName
178104
): Promise<void> => {
179-
const content = await readFile(filename, "utf-8");
180-
const existingConfig = parseSimpleYaml(content) as
181-
| Record<string, unknown>
182-
| undefined;
105+
const raw = await readFile(filename, "utf-8");
106+
const content = quoteGlobKeys(raw);
107+
108+
let existingConfig: Record<string, unknown> | undefined;
109+
try {
110+
existingConfig = YAML.parse(content) as Record<string, unknown> | undefined;
111+
} catch {
112+
// If parsing fails (invalid YAML), treat as empty config and proceed gracefully
113+
return;
114+
}
183115

184-
// If parsing fails (invalid YAML), treat as empty config and proceed gracefully
185116
if (!existingConfig) {
186117
return;
187118
}
@@ -190,7 +121,7 @@ const updateYamlConfig = async (
190121
existingConfig,
191122
createLintStagedConfig(packageManager)
192123
);
193-
await writeFile(filename, stringifySimpleYaml(mergedConfig));
124+
await writeFile(filename, YAML.stringify(mergedConfig));
194125
};
195126

196127
// Update ESM config files

0 commit comments

Comments
 (0)