Disambiguate package.json tasks by parent directory as needed (#33798)

Closes #33701, cc @afgomez 

Release Notes:

- Added the parent directory to the label as needed to disambiguate
tasks from package.json
This commit is contained in:
Cole Miller 2025-07-02 16:37:36 -04:00 committed by GitHub
parent 610f4605d8
commit e224da8522
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 4 deletions

View file

@ -8,7 +8,8 @@ use futures::StreamExt;
use gpui::{App, AsyncApp, Task};
use http_client::github::{GitHubLspBinaryVersion, latest_github_release};
use language::{
ContextProvider, LanguageRegistry, LanguageToolchainStore, LspAdapter, LspAdapterDelegate,
ContextProvider, LanguageRegistry, LanguageToolchainStore, LocalFile as _, LspAdapter,
LspAdapterDelegate,
};
use lsp::{LanguageServerBinary, LanguageServerName};
use node_runtime::NodeRuntime;
@ -65,13 +66,14 @@ impl ContextProvider for JsonTaskProvider {
.ok()?
.await
.ok()?;
let path = cx.update(|cx| file.abs_path(cx)).ok()?.as_path().into();
let task_templates = if is_package_json {
let package_json = serde_json_lenient::from_str::<
HashMap<String, serde_json_lenient::Value>,
>(&contents.text)
.ok()?;
let package_json = PackageJsonData::new(file.path.clone(), package_json);
let package_json = PackageJsonData::new(path, package_json);
let command = package_json.package_manager.unwrap_or("npm").to_owned();
package_json
.scripts

View file

@ -221,15 +221,30 @@ impl PackageJsonData {
});
}
let script_name_counts: HashMap<_, usize> =
self.scripts
.iter()
.fold(HashMap::default(), |mut acc, (_, script)| {
*acc.entry(script).or_default() += 1;
acc
});
for (path, script) in &self.scripts {
let label = if script_name_counts.get(script).copied().unwrap_or_default() > 1
&& let Some(parent) = path.parent().and_then(|parent| parent.file_name())
{
let parent = parent.to_string_lossy();
format!("{parent}/package.json > {script}")
} else {
format!("package.json > {script}")
};
task_templates.0.push(TaskTemplate {
label: format!("package.json > {script}",),
label,
command: TYPESCRIPT_RUNNER_VARIABLE.template_value(),
args: vec!["run".to_owned(), script.to_owned()],
tags: vec!["package-script".into()],
cwd: Some(
path.parent()
.unwrap_or(Path::new(""))
.unwrap_or(Path::new("/"))
.to_string_lossy()
.to_string(),
),
@ -1014,6 +1029,7 @@ mod tests {
use language::language_settings;
use project::{FakeFs, Project};
use serde_json::json;
use task::TaskTemplates;
use unindent::Unindent;
use util::path;
@ -1135,5 +1151,42 @@ mod tests {
package_manager: None,
}
);
let mut task_templates = TaskTemplates::default();
package_json_data.fill_task_templates(&mut task_templates);
let task_templates = task_templates
.0
.into_iter()
.map(|template| (template.label, template.cwd))
.collect::<Vec<_>>();
pretty_assertions::assert_eq!(
task_templates,
[
(
"vitest file test".into(),
Some("$ZED_CUSTOM_TYPESCRIPT_VITEST_PACKAGE_PATH".into()),
),
(
"vitest test $ZED_SYMBOL".into(),
Some("$ZED_CUSTOM_TYPESCRIPT_VITEST_PACKAGE_PATH".into()),
),
(
"mocha file test".into(),
Some("$ZED_CUSTOM_TYPESCRIPT_MOCHA_PACKAGE_PATH".into()),
),
(
"mocha test $ZED_SYMBOL".into(),
Some("$ZED_CUSTOM_TYPESCRIPT_MOCHA_PACKAGE_PATH".into()),
),
(
"root/package.json > test".into(),
Some(path!("/root").into())
),
(
"sub/package.json > test".into(),
Some(path!("/root/sub").into())
),
]
);
}
}