дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
feat(run): choose the Node interpreter of an npm configuration (#1120)
npm configurations get a "Node interpreter" field; the script and the package manager run on that node (its directory first on the PATH). Empty keeps the project's interpreter from Settings › Languages & Frameworks › Node.js. Saving drops the PATH settings derived before the choice, so a stale project PATH isn't kept. Closes #997
Цей коміт міститься в:
1 джерело
6bf1d25711
коміт
4c5b6de9ad
4 files changed
+49
-5
No files matched your search
@@ -703,8 +703,10 @@ pub fn apply_to_run_configs(configs: &mut [RunConfig], root: &Path, s: &Settings
|
||||
{
|
||||
c.command = pm.to_owned();
|
||||
}
|
||||
if let Some(dir) = &node {
|
||||
path_dirs.push(dir.clone());
|
||||
// The configuration's own Node interpreter, else the project's.
|
||||
let own = c.extras.params.get("nodeInterpreter").and_then(|p| setting_path(root, p));
|
||||
if let Some(dir) = own.and_then(|p| p.parent().map(Path::to_path_buf)).or_else(|| node.clone()) {
|
||||
path_dirs.push(dir);
|
||||
}
|
||||
}
|
||||
"php" | "phpunit" | "composer" => {
|
||||
@@ -825,14 +827,17 @@ pub fn without_derived(config: &RunConfig, root: &Path, s: &Settings) -> RunConf
|
||||
};
|
||||
let mut out = config.clone();
|
||||
// Until nothing changes: some entries are derived only once others are gone
|
||||
// (the virtualenv's `PATH` is added only without `VIRTUAL_ENV`).
|
||||
// (the virtualenv's `PATH` is added only without `VIRTUAL_ENV`). An entry derived before
|
||||
// the configuration's own choice (an npm script's Node interpreter) is derived too.
|
||||
while let Some(key) = out
|
||||
.env
|
||||
.iter()
|
||||
.find(|(key, value)| {
|
||||
let mut probe = out.clone();
|
||||
probe.env.remove(*key);
|
||||
applied(&probe).env.get(*key) == Some(*value)
|
||||
let mut plain = probe.clone();
|
||||
plain.extras.params.clear();
|
||||
applied(&probe).env.get(*key) == Some(*value) || applied(&plain).env.get(*key) == Some(*value)
|
||||
})
|
||||
.map(|(key, _)| key.clone())
|
||||
{
|
||||
|
||||
@@ -173,6 +173,35 @@ fn run_configs_use_selected_interpreter_and_package_manager() {
|
||||
assert_eq!(configs[6].args, ["manage.py", "test", "polls"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn npm_config_runs_on_its_own_node_interpreter() {
|
||||
if cfg!(windows) {
|
||||
return; // Unix paths
|
||||
}
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let mut s = Settings::default();
|
||||
s.languages.node.interpreter = "/opt/node22/bin/node".into();
|
||||
let mut own = run("npm", "npm", &["run", "dev"]);
|
||||
own.extras.params.insert("nodeInterpreter".into(), "/opt/node18/bin/node".into());
|
||||
let mut configs = vec![own, run("npm", "npm", &["run", "build"])];
|
||||
apply_to_run_configs(&mut configs, tmp.path(), &s);
|
||||
let first = |c: &RunConfig| c.env["PATH"].split(':').next().unwrap().to_owned();
|
||||
assert_eq!(first(&configs[0]), "/opt/node18/bin");
|
||||
assert_eq!(first(&configs[1]), "/opt/node22/bin", "the project's Node.js without one");
|
||||
// Saved without the derived PATH, keeping the choice itself.
|
||||
let saved = without_derived(&configs[0], tmp.path(), &s);
|
||||
assert!(!saved.env.contains_key("PATH"));
|
||||
assert_eq!(saved.extras.params["nodeInterpreter"], "/opt/node18/bin/node");
|
||||
// Chosen on a configuration loaded with the project's PATH: that PATH isn't kept either.
|
||||
let mut edited = configs[1].clone();
|
||||
edited.extras.params.insert("nodeInterpreter".into(), "/opt/node18/bin/node".into());
|
||||
let saved = without_derived(&edited, tmp.path(), &s);
|
||||
assert!(!saved.env.contains_key("PATH"));
|
||||
let mut reloaded = vec![saved];
|
||||
apply_to_run_configs(&mut reloaded, tmp.path(), &s);
|
||||
assert_eq!(first(&reloaded[0]), "/opt/node18/bin");
|
||||
}
|
||||
|
||||
fn fake_jdk(dir: &Path) {
|
||||
std::fs::create_dir_all(dir.join("bin")).unwrap();
|
||||
std::fs::write(dir.join("bin").join(exe("java")), "").unwrap();
|
||||
|
||||
@@ -232,6 +232,14 @@ const npm: RunConfigTypeContribution = {
|
||||
control: "select",
|
||||
options: PACKAGE_MANAGERS.map((v) => ({ value: v, label: v })),
|
||||
},
|
||||
{
|
||||
key: "nodeInterpreter",
|
||||
label: "Node interpreter",
|
||||
mono: true,
|
||||
browse: "file",
|
||||
placeholder: "Project default",
|
||||
hint: "The node executable this script runs on; empty uses Settings › Languages & Frameworks › Node.js.",
|
||||
},
|
||||
],
|
||||
commandLine(p) {
|
||||
const command = p.command || "run";
|
||||
|
||||
@@ -5802,5 +5802,7 @@
|
||||
"Not in Local History: {names}. They are in the Trash.": "本地历史中没有:{names}。它们在回收站中。",
|
||||
"Show All Commits": "显示所有提交",
|
||||
"Pin": "固定",
|
||||
"Unpin": "取消固定"
|
||||
"Unpin": "取消固定",
|
||||
"Project default": "项目默认",
|
||||
"The node executable this script runs on; empty uses Settings › Languages & Frameworks › Node.js.": "运行此脚本的 node 可执行文件;留空则使用“设置 › 语言和框架 › Node.js”中的解释器。"
|
||||
}
|
||||
Reference in new issue
Заблокувати користувача