Skip to content

Commit bd66115

Browse files
authored
Merge branch 'main' into fix/custom-vp-home-broken
2 parents 05645db + b99c778 commit bd66115

9 files changed

Lines changed: 56 additions & 66 deletions

File tree

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,33 @@ jobs:
5959
- '!.github/workflows/deploy-docs.yml'
6060
- '!netlify.toml'
6161
62+
docs-fmt:
63+
name: Docs format check
64+
needs: detect-changes
65+
# Docs-only changes skip the full CI matrix, so nothing else format-checks
66+
# them (code changes get `vp check` in cli-e2e-test). Non-blocking:
67+
# intentionally not listed in the `done` job's needs.
68+
if: needs.detect-changes.outputs.code-changed == 'false'
69+
runs-on: ubuntu-latest
70+
steps:
71+
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
72+
73+
- uses: voidzero-dev/setup-vp@35171c92dd08b67d5a9d3f2a4327800e58396f2a # v1.13.0
74+
with:
75+
# The workspace `vite-plus` version can be ahead of the registry, so
76+
# pin the released build instead of auto-detecting from package.json.
77+
version: latest
78+
run-install: false
79+
80+
- name: Run vp fmt --check
81+
run: |
82+
# `vp fmt` loads the root vite.config.ts, whose `import ... from 'vite-plus'`
83+
# must resolve at runtime. Link the released package out of the global
84+
# install instead of installing the whole workspace.
85+
mkdir -p node_modules
86+
ln -s "$HOME/.vite-plus/current/node_modules/vite-plus" node_modules/vite-plus
87+
vp fmt --check
88+
6289
download-previous-rolldown-binaries:
6390
needs: detect-changes
6491
if: needs.detect-changes.outputs.code-changed == 'true'

crates/vite_migration/src/prettier.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ mod tests {
225225
rewrite_prettier_script("prettier --check --list-different ."),
226226
"vp fmt --check ."
227227
);
228+
229+
// --list-different + --check (the other order) → still a single --check
230+
assert_eq!(
231+
rewrite_prettier_script("prettier --list-different --check ."),
232+
"vp fmt --check ."
233+
);
234+
235+
// two literal --check → still a single --check
236+
assert_eq!(rewrite_prettier_script("prettier --check --check ."), "vp fmt --check .");
228237
}
229238

230239
#[test]

crates/vite_migration/src/script_rewrite.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,14 @@ fn strip_flags_from_suffix(
497497
break;
498498
}
499499
if val == conv.dedup_flag {
500-
conversion_emitted[ci] = true;
500+
// Drop a duplicate if the target flag was already emitted;
501+
// otherwise keep this one and mark it emitted.
502+
if conversion_emitted[ci] {
503+
converted = true;
504+
} else {
505+
conversion_emitted[ci] = true;
506+
}
507+
break;
501508
}
502509
}
503510
if converted {

crates/vite_static_config/src/lib.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,9 @@ pub fn resolve_static_config(dir: &AbsolutePath) -> FieldMap {
115115

116116
let extension = config_path.as_path().extension().and_then(|e| e.to_str()).unwrap_or("");
117117

118-
if extension == "json" {
119-
return parse_json_config(&source);
120-
}
121-
122118
parse_js_ts_config(&source, extension)
123119
}
124120

125-
/// Parse a JSON config file into a map of field names to values.
126-
/// All fields in a valid JSON object are fully static.
127-
fn parse_json_config(source: &str) -> FieldMap {
128-
let Ok(serde_json::Value::Object(obj)) = serde_json::from_str(source) else {
129-
return FieldMap::unanalyzable();
130-
};
131-
let mut map = FxHashMap::with_capacity_and_hasher(obj.len(), Default::default());
132-
for (k, v) in &obj {
133-
map.insert(Box::from(k.as_str()), FieldValue::Json(v.clone()));
134-
}
135-
FieldMap(FieldMapInner::Closed(map))
136-
}
137-
138121
/// Parse a JS/TS config file, extracting the default export object's fields.
139122
fn parse_js_ts_config(source: &str, extension: &str) -> FieldMap {
140123
let allocator = Allocator::default();
@@ -518,10 +501,10 @@ mod tests {
518501
assert!(result.get("run").is_none());
519502
}
520503

521-
// ── JSON config parsing ─────────────────────────────────────────────
504+
// ── resolve_static_config from a config file─────────────────────────────────────────────
522505

523506
#[test]
524-
fn parses_json_config() {
507+
fn resolve_static_config_reads_run_from_config_file() {
525508
let dir = TempDir::new().unwrap();
526509
let dir_path = vite_path::AbsolutePathBuf::new(dir.path().to_path_buf()).unwrap();
527510
std::fs::write(

packages/cli/src/utils/__tests__/agent.spec.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
88
import {
99
COPILOT_SETUP_WORKFLOW_PATH,
1010
detectExistingAgentTargetPaths,
11-
detectExistingAgentTargetPath,
1211
hasExistingAgentInstructions,
1312
replaceMarkedAgentInstructionsSection,
1413
resolveAgentOptions,
@@ -376,7 +375,7 @@ describe('selectAgentTargetPaths', () => {
376375
});
377376
});
378377

379-
describe('detectExistingAgentTargetPath', () => {
378+
describe('detectExistingAgentTargetPaths', () => {
380379
it('detects all existing regular agent files', async () => {
381380
const dir = await createProjectDir();
382381
await mockFs.writeFile(path.join(dir, 'AGENTS.md'), '# Agents');
@@ -389,14 +388,14 @@ describe('detectExistingAgentTargetPath', () => {
389388
const dir = await createProjectDir();
390389
await mockFs.writeFile(path.join(dir, 'CLAUDE.md'), '# Claude');
391390

392-
expect(detectExistingAgentTargetPath(dir)).toBe('CLAUDE.md');
391+
expect(detectExistingAgentTargetPaths(dir)).toEqual(['CLAUDE.md']);
393392
});
394393

395394
it('ignores symlinked agent files', async () => {
396395
const dir = await createProjectDir();
397396
await mockFs.symlink('AGENTS.md', path.join(dir, 'CLAUDE.md'));
398397

399-
expect(detectExistingAgentTargetPath(dir)).toBeUndefined();
398+
expect(detectExistingAgentTargetPaths(dir)).toBeUndefined();
400399
});
401400
});
402401

packages/cli/src/utils/agent.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -174,19 +174,6 @@ export async function selectAgentTargetPaths({
174174
return selection.targetPaths;
175175
}
176176

177-
export async function selectAgentTargetPath({
178-
interactive,
179-
agent,
180-
onCancel,
181-
}: {
182-
interactive: boolean;
183-
agent?: AgentSelection;
184-
onCancel: () => void;
185-
}) {
186-
const targetPaths = await selectAgentTargetPaths({ interactive, agent, onCancel });
187-
return targetPaths?.[0];
188-
}
189-
190177
export function detectExistingAgentTargetPaths(projectRoot: string) {
191178
const detectedPaths: string[] = [];
192179
const seenTargetPaths = new Set<string>();
@@ -203,10 +190,6 @@ export function detectExistingAgentTargetPaths(projectRoot: string) {
203190
return detectedPaths.length > 0 ? detectedPaths : undefined;
204191
}
205192

206-
export function detectExistingAgentTargetPath(projectRoot: string) {
207-
return detectExistingAgentTargetPaths(projectRoot)?.[0];
208-
}
209-
210193
export function hasExistingAgentInstructions(projectRoot: string): boolean {
211194
const targetPaths = detectExistingAgentTargetPaths(projectRoot);
212195
if (!targetPaths) {
@@ -259,10 +242,6 @@ export function resolveAgentTargetPaths(agent?: string | string[]) {
259242
return getAgentTargetPaths(resolveAgentOptions(agent));
260243
}
261244

262-
export function resolveAgentTargetPath(agent?: string) {
263-
return resolveAgentTargetPaths(agent)[0] ?? 'AGENTS.md';
264-
}
265-
266245
export function resolveAgentOptions(agent?: string | string[]) {
267246
const agentNames = parseAgentNames(agent);
268247
const resolvedAgentNames = agentNames.length > 0 ? agentNames : [AGENT_DEFAULT_ID];

packages/cli/src/utils/editor.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,6 @@ export async function selectEditors({
273273
return undefined;
274274
}
275275

276-
export function detectExistingEditor(projectRoot: string): EditorId | undefined {
277-
return detectExistingEditors(projectRoot)?.[0];
278-
}
279-
280276
export function detectExistingEditors(projectRoot: string): EditorId[] | undefined {
281277
const editors: EditorId[] = [];
282278
for (const option of EDITORS) {

packages/cli/src/utils/terminal.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,7 @@ export function error(text: string) {
3737
}
3838

3939
// Standard message prefix functions matching the Rust CLI convention.
40-
// info/note go to stdout (normal output), warn/error go to stderr (diagnostics).
41-
42-
export function infoMsg(msg: string) {
43-
/* oxlint-disable-next-line no-console */
44-
console.log(styleText(['blue', 'bold'], 'info:'), msg);
45-
}
40+
// warn/error go to stderr (diagnostics).
4641

4742
export function warnMsg(msg: string) {
4843
/* oxlint-disable-next-line no-console */
@@ -53,8 +48,3 @@ export function errorMsg(msg: string) {
5348
/* oxlint-disable-next-line no-console */
5449
console.error(styleText(['red', 'bold'], 'error:'), msg);
5550
}
56-
57-
export function noteMsg(msg: string) {
58-
/* oxlint-disable-next-line no-console */
59-
console.log(styleText(['gray', 'bold'], 'note:'), msg);
60-
}

rfcs/init-editor-configs.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ When a config file already exists:
8181

8282
Mirrors `packages/cli/src/utils/agent.ts` structure:
8383

84-
| agent.ts | editor.ts |
85-
| --------------------------------- | ------------------------ |
86-
| `AGENTS` array | `EDITORS` array |
87-
| `selectAgentTargetPath()` | `selectEditor()` |
88-
| `detectExistingAgentTargetPath()` | `detectExistingEditor()` |
89-
| `writeAgentInstructions()` | `writeEditorConfigs()` |
84+
| agent.ts | editor.ts |
85+
| ---------------------------------- | ------------------------- |
86+
| `AGENTS` array | `EDITORS` array |
87+
| `selectAgentTargetPaths()` | `selectEditors()` |
88+
| `detectExistingAgentTargetPaths()` | `detectExistingEditors()` |
89+
| `writeAgentInstructions()` | `writeEditorConfigs()` |
9090

9191
Key difference from agent.ts: Uses JSON merge (via `utils/json.ts`) instead of file copy/append, since IDE configs are structured JSON.
9292

0 commit comments

Comments
 (0)