Skip to content

Commit 0ff292c

Browse files
authored
Merge branch 'main' into deps/upstream-update
2 parents 4a84367 + e3c79b9 commit 0ff292c

14 files changed

Lines changed: 228 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/vite_shared/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ supports-color = "3"
1717
tracing-subscriber = { workspace = true }
1818
vite_path = { workspace = true }
1919
vite_str = { workspace = true }
20+
which = { workspace = true }
2021

2122
[target.'cfg(not(target_os = "windows"))'.dependencies]
2223
rustls = { workspace = true }

crates/vite_shared/src/home.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use directories::BaseDirs;
22
use vite_path::{AbsolutePathBuf, current_dir};
3+
use which::which;
34

45
use crate::EnvConfig;
56

@@ -8,7 +9,9 @@ const VITE_PLUS_HOME_DIR: &str = ".vite-plus";
89

910
/// Get the vite-plus home directory.
1011
///
11-
/// Uses `EnvConfig::get().vite_plus_home` if set, otherwise defaults to `~/.vite-plus`.
12+
/// Uses `EnvConfig::get().vite_plus_home` if set,
13+
/// or the `node` executable's grandparent directory if it ends with `.vite-plus`,
14+
/// otherwise defaults to `~/.vite-plus`.
1215
/// Falls back to `$CWD/.vite-plus` if the home directory cannot be determined.
1316
pub fn get_vite_plus_home() -> std::io::Result<AbsolutePathBuf> {
1417
let config = EnvConfig::get();
@@ -18,6 +21,16 @@ pub fn get_vite_plus_home() -> std::io::Result<AbsolutePathBuf> {
1821
}
1922
}
2023

24+
// Get from `node` executable file's grandparent directory (~/.vite-plus/bin/node)
25+
// For the case where `$HOME` is overridden
26+
if let Ok(path) = which("node")
27+
&& let Some(parent) = path.parent()
28+
&& let Some(grandparent) = parent.parent()
29+
&& grandparent.ends_with(VITE_PLUS_HOME_DIR)
30+
{
31+
return Ok(AbsolutePathBuf::new(grandparent.to_path_buf()).unwrap());
32+
}
33+
2134
// Default to ~/.vite-plus
2235
match BaseDirs::new() {
2336
Some(dirs) => {
@@ -49,4 +62,63 @@ mod tests {
4962
assert_eq!(home.as_path(), temp_dir.as_path());
5063
});
5164
}
65+
66+
#[test]
67+
fn test_get_vite_plus_without_home() {
68+
use std::path::PathBuf;
69+
70+
// Create a temp directory structure: /tmp/xxx/.vite-plus/bin/node
71+
let temp_dir = PathBuf::from(
72+
std::env::temp_dir().join(format!("vp-test-node-path-{}", std::process::id())),
73+
);
74+
let vite_plus_home = temp_dir.join(".vite-plus");
75+
let bin_dir = vite_plus_home.join("bin");
76+
std::fs::create_dir_all(&bin_dir).unwrap();
77+
78+
// Create a fake node executable with platform-specific extension
79+
#[cfg(windows)]
80+
let node_path = bin_dir.join("node.exe");
81+
#[cfg(not(windows))]
82+
let node_path = bin_dir.join("node");
83+
84+
// Write minimal content - on Windows, the file just needs to exist with .exe extension
85+
// On Unix, we need a shebang and executable permissions
86+
#[cfg(windows)]
87+
std::fs::write(&node_path, b"MZ").unwrap(); // Minimal PE header for Windows
88+
#[cfg(not(windows))]
89+
{
90+
std::fs::write(&node_path, "#!/bin/sh\necho 'fake node'").unwrap();
91+
use std::os::unix::fs::PermissionsExt;
92+
let mut perms = std::fs::metadata(&node_path).unwrap().permissions();
93+
perms.set_mode(0o755);
94+
std::fs::set_permissions(&node_path, perms).unwrap();
95+
}
96+
97+
// Set PATH to include the fake node directory FIRST (prepended)
98+
let original_path = std::env::var("PATH").unwrap_or_default();
99+
#[cfg(windows)]
100+
let path_separator = ';';
101+
#[cfg(not(windows))]
102+
let path_separator = ':';
103+
let new_path = format!("{}{}{}", bin_dir.display(), path_separator, original_path);
104+
// SAFETY: restore PATH after test
105+
unsafe {
106+
std::env::set_var("PATH", &new_path);
107+
}
108+
109+
// Clear any existing VITE_PLUS_HOME env var by using a test config without it
110+
EnvConfig::test_scope(EnvConfig::for_test(), || {
111+
// Test: get_vite_plus_home should return /tmp/xxx/.vite-plus
112+
let home = get_vite_plus_home().unwrap();
113+
assert_eq!(home.as_path(), vite_plus_home.as_path());
114+
});
115+
116+
// SAFETY: restore PATH after test
117+
unsafe {
118+
std::env::set_var("PATH", original_path);
119+
}
120+
121+
// Cleanup
122+
let _ = std::fs::remove_dir_all(&temp_dir);
123+
}
52124
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "./node_modules/oxlint/configuration_schema.json",
3+
"categories": {
4+
"correctness": "error"
5+
},
6+
"rules": {
7+
// this is a comment
8+
"no-console": "error"
9+
},
10+
"globals": {},
11+
"ignorePatterns": []
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devDependencies": {
3+
"oxlint": "1"
4+
}
5+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
> vp migrate --no-interactive 2>&1 # migration should handle .oxlintrc.json with JSONC comments
2+
VITE+ - The Unified Toolchain for the Web
3+
4+
◇ Migrated . to Vite+<repeat>
5+
• Node <semver> pnpm <semver>
6+
• 3 config updates applied
7+
8+
> cat vite.config.ts # check vite.config.ts
9+
import { defineConfig } from 'vite-plus';
10+
11+
export default defineConfig({
12+
staged: {
13+
"*": "vp check --fix"
14+
},
15+
fmt: {},
16+
lint: {
17+
"categories": {
18+
"correctness": "error"
19+
},
20+
"rules": {
21+
"no-console": "error"
22+
},
23+
"globals": {},
24+
"ignorePatterns": [],
25+
"options": {
26+
"typeAware": true,
27+
"typeCheck": true
28+
}
29+
},
30+
});
31+
32+
> test ! -f .oxlintrc.json # check .oxlintrc.json is removed
33+
> cat package.json # check package.json
34+
{
35+
"devDependencies": {
36+
"vite-plus": "latest"
37+
},
38+
"pnpm": {
39+
"overrides": {
40+
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
41+
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
42+
}
43+
},
44+
"packageManager": "pnpm@<semver>",
45+
"scripts": {
46+
"prepare": "vp config"
47+
}
48+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"commands": [
3+
"vp migrate --no-interactive 2>&1 # migration should handle .oxlintrc.json with JSONC comments",
4+
"cat vite.config.ts # check vite.config.ts",
5+
"test ! -f .oxlintrc.json # check .oxlintrc.json is removed",
6+
"cat package.json # check package.json"
7+
]
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"printWidth": 100,
3+
"tabWidth": 2,
4+
"semi": true,
5+
"singleQuote": true,
6+
"trailingComma": "es5",
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"rules": {
3+
// this is a comment
4+
"no-unused-vars": "error",
5+
},
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"devDependencies": {
3+
"oxfmt": "1",
4+
"oxlint": "1"
5+
}
6+
}

0 commit comments

Comments
 (0)