mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Support flychecking for cargo scripts
This commit is contained in:
parent
ff56cb6e49
commit
fa754becc4
7 changed files with 61 additions and 44 deletions
|
@ -125,8 +125,10 @@ impl FlycheckHandle {
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
sysroot_root: Option<AbsPathBuf>,
|
sysroot_root: Option<AbsPathBuf>,
|
||||||
workspace_root: AbsPathBuf,
|
workspace_root: AbsPathBuf,
|
||||||
|
manifest_path: Option<AbsPathBuf>,
|
||||||
) -> FlycheckHandle {
|
) -> FlycheckHandle {
|
||||||
let actor = FlycheckActor::new(id, sender, config, sysroot_root, workspace_root);
|
let actor =
|
||||||
|
FlycheckActor::new(id, sender, config, sysroot_root, workspace_root, manifest_path);
|
||||||
let (sender, receiver) = unbounded::<StateChange>();
|
let (sender, receiver) = unbounded::<StateChange>();
|
||||||
let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
|
let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
|
||||||
.name("Flycheck".to_owned())
|
.name("Flycheck".to_owned())
|
||||||
|
@ -205,6 +207,7 @@ struct FlycheckActor {
|
||||||
id: usize,
|
id: usize,
|
||||||
sender: Box<dyn Fn(Message) + Send>,
|
sender: Box<dyn Fn(Message) + Send>,
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
|
manifest_path: Option<AbsPathBuf>,
|
||||||
/// Either the workspace root of the workspace we are flychecking,
|
/// Either the workspace root of the workspace we are flychecking,
|
||||||
/// or the project root of the project.
|
/// or the project root of the project.
|
||||||
root: AbsPathBuf,
|
root: AbsPathBuf,
|
||||||
|
@ -233,6 +236,7 @@ impl FlycheckActor {
|
||||||
config: FlycheckConfig,
|
config: FlycheckConfig,
|
||||||
sysroot_root: Option<AbsPathBuf>,
|
sysroot_root: Option<AbsPathBuf>,
|
||||||
workspace_root: AbsPathBuf,
|
workspace_root: AbsPathBuf,
|
||||||
|
manifest_path: Option<AbsPathBuf>,
|
||||||
) -> FlycheckActor {
|
) -> FlycheckActor {
|
||||||
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
|
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
|
||||||
FlycheckActor {
|
FlycheckActor {
|
||||||
|
@ -241,6 +245,7 @@ impl FlycheckActor {
|
||||||
config,
|
config,
|
||||||
sysroot_root,
|
sysroot_root,
|
||||||
root: workspace_root,
|
root: workspace_root,
|
||||||
|
manifest_path,
|
||||||
command_handle: None,
|
command_handle: None,
|
||||||
command_receiver: None,
|
command_receiver: None,
|
||||||
}
|
}
|
||||||
|
@ -388,8 +393,13 @@ impl FlycheckActor {
|
||||||
"--message-format=json"
|
"--message-format=json"
|
||||||
});
|
});
|
||||||
|
|
||||||
cmd.arg("--manifest-path");
|
if let Some(manifest_path) = &self.manifest_path {
|
||||||
cmd.arg(self.root.join("Cargo.toml"));
|
cmd.arg("--manifest-path");
|
||||||
|
cmd.arg(manifest_path);
|
||||||
|
if manifest_path.extension().map_or(false, |ext| ext == "rs") {
|
||||||
|
cmd.arg("-Zscript");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.apply_on_command(&mut cmd);
|
options.apply_on_command(&mut cmd);
|
||||||
(cmd, options.extra_args.clone())
|
(cmd, options.extra_args.clone())
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub enum ProjectWorkspaceKind {
|
||||||
/// The file in question.
|
/// The file in question.
|
||||||
file: ManifestPath,
|
file: ManifestPath,
|
||||||
/// Is this file a cargo script file?
|
/// Is this file a cargo script file?
|
||||||
cargo_script: Option<(CargoWorkspace, WorkspaceBuildScripts)>,
|
cargo: Option<(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||||
/// Environment variables set in the `.cargo/config` file.
|
/// Environment variables set in the `.cargo/config` file.
|
||||||
cargo_config_extra_env: FxHashMap<String, String>,
|
cargo_config_extra_env: FxHashMap<String, String>,
|
||||||
},
|
},
|
||||||
|
@ -135,7 +135,11 @@ impl fmt::Debug for ProjectWorkspace {
|
||||||
.field("n_cfg_overrides", &cfg_overrides.len());
|
.field("n_cfg_overrides", &cfg_overrides.len());
|
||||||
debug_struct.finish()
|
debug_struct.finish()
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::DetachedFile { file, cargo_script, cargo_config_extra_env } => f
|
ProjectWorkspaceKind::DetachedFile {
|
||||||
|
file,
|
||||||
|
cargo: cargo_script,
|
||||||
|
cargo_config_extra_env,
|
||||||
|
} => f
|
||||||
.debug_struct("DetachedFiles")
|
.debug_struct("DetachedFiles")
|
||||||
.field("file", &file)
|
.field("file", &file)
|
||||||
.field("cargo_script", &cargo_script.is_some())
|
.field("cargo_script", &cargo_script.is_some())
|
||||||
|
@ -451,7 +455,7 @@ impl ProjectWorkspace {
|
||||||
Ok(ProjectWorkspace {
|
Ok(ProjectWorkspace {
|
||||||
kind: ProjectWorkspaceKind::DetachedFile {
|
kind: ProjectWorkspaceKind::DetachedFile {
|
||||||
file: detached_file.to_owned(),
|
file: detached_file.to_owned(),
|
||||||
cargo_script,
|
cargo: cargo_script,
|
||||||
cargo_config_extra_env,
|
cargo_config_extra_env,
|
||||||
},
|
},
|
||||||
sysroot,
|
sysroot,
|
||||||
|
@ -476,7 +480,7 @@ impl ProjectWorkspace {
|
||||||
progress: &dyn Fn(String),
|
progress: &dyn Fn(String),
|
||||||
) -> anyhow::Result<WorkspaceBuildScripts> {
|
) -> anyhow::Result<WorkspaceBuildScripts> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. }
|
ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. }
|
||||||
| ProjectWorkspaceKind::Cargo { cargo, .. } => {
|
| ProjectWorkspaceKind::Cargo { cargo, .. } => {
|
||||||
WorkspaceBuildScripts::run_for_workspace(
|
WorkspaceBuildScripts::run_for_workspace(
|
||||||
config,
|
config,
|
||||||
|
@ -489,7 +493,7 @@ impl ProjectWorkspace {
|
||||||
format!("Failed to run build scripts for {}", cargo.workspace_root())
|
format!("Failed to run build scripts for {}", cargo.workspace_root())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::DetachedFile { cargo_script: None, .. }
|
ProjectWorkspaceKind::DetachedFile { cargo: None, .. }
|
||||||
| ProjectWorkspaceKind::Json { .. } => Ok(WorkspaceBuildScripts::default()),
|
| ProjectWorkspaceKind::Json { .. } => Ok(WorkspaceBuildScripts::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,9 +544,9 @@ impl ProjectWorkspace {
|
||||||
pub fn set_build_scripts(&mut self, bs: WorkspaceBuildScripts) {
|
pub fn set_build_scripts(&mut self, bs: WorkspaceBuildScripts) {
|
||||||
match &mut self.kind {
|
match &mut self.kind {
|
||||||
ProjectWorkspaceKind::Cargo { build_scripts, .. }
|
ProjectWorkspaceKind::Cargo { build_scripts, .. }
|
||||||
| ProjectWorkspaceKind::DetachedFile {
|
| ProjectWorkspaceKind::DetachedFile { cargo: Some((_, build_scripts)), .. } => {
|
||||||
cargo_script: Some((_, build_scripts)), ..
|
*build_scripts = bs
|
||||||
} => *build_scripts = bs,
|
}
|
||||||
_ => assert_eq!(bs, WorkspaceBuildScripts::default()),
|
_ => assert_eq!(bs, WorkspaceBuildScripts::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,7 +678,7 @@ impl ProjectWorkspace {
|
||||||
}))
|
}))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::DetachedFile { file, cargo_script, .. } => {
|
ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => {
|
||||||
iter::once(PackageRoot {
|
iter::once(PackageRoot {
|
||||||
is_local: true,
|
is_local: true,
|
||||||
include: vec![file.as_ref().to_owned()],
|
include: vec![file.as_ref().to_owned()],
|
||||||
|
@ -736,7 +740,7 @@ impl ProjectWorkspace {
|
||||||
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
||||||
cargo.packages().len() + sysroot_package_len + rustc_package_len
|
cargo.packages().len() + sysroot_package_len + rustc_package_len
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::DetachedFile { cargo_script, .. } => {
|
ProjectWorkspaceKind::DetachedFile { cargo: cargo_script, .. } => {
|
||||||
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
||||||
sysroot_package_len
|
sysroot_package_len
|
||||||
+ cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len())
|
+ cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len())
|
||||||
|
@ -781,7 +785,7 @@ impl ProjectWorkspace {
|
||||||
),
|
),
|
||||||
sysroot,
|
sysroot,
|
||||||
),
|
),
|
||||||
ProjectWorkspaceKind::DetachedFile { file, cargo_script, .. } => (
|
ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => (
|
||||||
if let Some((cargo, build_scripts)) = cargo_script {
|
if let Some((cargo, build_scripts)) = cargo_script {
|
||||||
cargo_to_crate_graph(
|
cargo_to_crate_graph(
|
||||||
&mut |path| load(path),
|
&mut |path| load(path),
|
||||||
|
@ -851,12 +855,12 @@ impl ProjectWorkspace {
|
||||||
(
|
(
|
||||||
ProjectWorkspaceKind::DetachedFile {
|
ProjectWorkspaceKind::DetachedFile {
|
||||||
file,
|
file,
|
||||||
cargo_script: Some((cargo_script, _)),
|
cargo: Some((cargo_script, _)),
|
||||||
cargo_config_extra_env,
|
cargo_config_extra_env,
|
||||||
},
|
},
|
||||||
ProjectWorkspaceKind::DetachedFile {
|
ProjectWorkspaceKind::DetachedFile {
|
||||||
file: o_file,
|
file: o_file,
|
||||||
cargo_script: Some((o_cargo_script, _)),
|
cargo: Some((o_cargo_script, _)),
|
||||||
cargo_config_extra_env: o_cargo_config_extra_env,
|
cargo_config_extra_env: o_cargo_config_extra_env,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl Tester {
|
||||||
let workspace = ProjectWorkspace {
|
let workspace = ProjectWorkspace {
|
||||||
kind: ProjectWorkspaceKind::DetachedFile {
|
kind: ProjectWorkspaceKind::DetachedFile {
|
||||||
file: ManifestPath::try_from(tmp_file).unwrap(),
|
file: ManifestPath::try_from(tmp_file).unwrap(),
|
||||||
cargo_script: None,
|
cargo: None,
|
||||||
cargo_config_extra_env: Default::default(),
|
cargo_config_extra_env: Default::default(),
|
||||||
},
|
},
|
||||||
sysroot,
|
sysroot,
|
||||||
|
|
|
@ -521,7 +521,7 @@ impl GlobalStateSnapshot {
|
||||||
let path = path.as_path()?;
|
let path = path.as_path()?;
|
||||||
self.workspaces.iter().find_map(|ws| match &ws.kind {
|
self.workspaces.iter().find_map(|ws| match &ws.kind {
|
||||||
ProjectWorkspaceKind::Cargo { cargo, .. }
|
ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||||
| ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. } => {
|
| ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => {
|
||||||
cargo.target_by_root(path).map(|it| (cargo, it))
|
cargo.target_by_root(path).map(|it| (cargo, it))
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::Json { .. } => None,
|
ProjectWorkspaceKind::Json { .. } => None,
|
||||||
|
|
|
@ -292,7 +292,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
|
||||||
let package = match &ws.kind {
|
let package = match &ws.kind {
|
||||||
project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
|
project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||||
| project_model::ProjectWorkspaceKind::DetachedFile {
|
| project_model::ProjectWorkspaceKind::DetachedFile {
|
||||||
cargo_script: Some((cargo, _)),
|
cargo: Some((cargo, _)),
|
||||||
..
|
..
|
||||||
} => cargo.packages().find_map(|pkg| {
|
} => cargo.packages().find_map(|pkg| {
|
||||||
let has_target_with_root = cargo[pkg]
|
let has_target_with_root = cargo[pkg]
|
||||||
|
|
|
@ -767,7 +767,8 @@ pub(crate) fn handle_parent_module(
|
||||||
.workspaces
|
.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ws| match &ws.kind {
|
.filter_map(|ws| match &ws.kind {
|
||||||
ProjectWorkspaceKind::Cargo { cargo, .. } => {
|
ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||||
|
| ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => {
|
||||||
cargo.parent_manifests(&manifest_path)
|
cargo.parent_manifests(&manifest_path)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1759,7 +1760,7 @@ pub(crate) fn handle_open_docs(
|
||||||
|
|
||||||
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind {
|
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind {
|
||||||
ProjectWorkspaceKind::Cargo { cargo, .. }
|
ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||||
| ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. } => {
|
| ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => {
|
||||||
Some((cargo, ws.sysroot.as_ref().ok()))
|
Some((cargo, ws.sysroot.as_ref().ok()))
|
||||||
}
|
}
|
||||||
ProjectWorkspaceKind::Json { .. } => None,
|
ProjectWorkspaceKind::Json { .. } => None,
|
||||||
|
|
|
@ -502,7 +502,7 @@ impl GlobalState {
|
||||||
let env = match &ws.kind {
|
let env = match &ws.kind {
|
||||||
ProjectWorkspaceKind::Cargo { cargo_config_extra_env, .. }
|
ProjectWorkspaceKind::Cargo { cargo_config_extra_env, .. }
|
||||||
| ProjectWorkspaceKind::DetachedFile {
|
| ProjectWorkspaceKind::DetachedFile {
|
||||||
cargo_script: Some(_),
|
cargo: Some(_),
|
||||||
cargo_config_extra_env,
|
cargo_config_extra_env,
|
||||||
..
|
..
|
||||||
} => cargo_config_extra_env
|
} => cargo_config_extra_env
|
||||||
|
@ -669,36 +669,37 @@ impl GlobalState {
|
||||||
config,
|
config,
|
||||||
None,
|
None,
|
||||||
self.config.root_path().clone(),
|
self.config.root_path().clone(),
|
||||||
|
None,
|
||||||
)],
|
)],
|
||||||
flycheck::InvocationStrategy::PerWorkspace => {
|
flycheck::InvocationStrategy::PerWorkspace => {
|
||||||
self.workspaces
|
self.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(id, ws)| match &ws.kind {
|
.filter_map(|(id, ws)| {
|
||||||
ProjectWorkspaceKind::Cargo { cargo, .. } => Some((
|
Some((
|
||||||
id,
|
id,
|
||||||
cargo.workspace_root(),
|
match &ws.kind {
|
||||||
|
ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||||
|
| ProjectWorkspaceKind::DetachedFile {
|
||||||
|
cargo: Some((cargo, _)),
|
||||||
|
..
|
||||||
|
} => (cargo.workspace_root(), Some(cargo.manifest_path())),
|
||||||
|
ProjectWorkspaceKind::Json(project) => {
|
||||||
|
// Enable flychecks for json projects if a custom flycheck command was supplied
|
||||||
|
// in the workspace configuration.
|
||||||
|
match config {
|
||||||
|
FlycheckConfig::CustomCommand { .. } => {
|
||||||
|
(project.path(), None)
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProjectWorkspaceKind::DetachedFile { .. } => return None,
|
||||||
|
},
|
||||||
ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()),
|
ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()),
|
||||||
)),
|
))
|
||||||
ProjectWorkspaceKind::Json(project) => {
|
|
||||||
// Enable flychecks for json projects if a custom flycheck command was supplied
|
|
||||||
// in the workspace configuration.
|
|
||||||
match config {
|
|
||||||
FlycheckConfig::CustomCommand { .. } => Some((
|
|
||||||
id,
|
|
||||||
project.path(),
|
|
||||||
ws.sysroot
|
|
||||||
.as_ref()
|
|
||||||
.ok()
|
|
||||||
.map(|sysroot| sysroot.root().to_owned()),
|
|
||||||
)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME
|
|
||||||
ProjectWorkspaceKind::DetachedFile { .. } => None,
|
|
||||||
})
|
})
|
||||||
.map(|(id, root, sysroot_root)| {
|
.map(|(id, (root, manifest_path), sysroot_root)| {
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
FlycheckHandle::spawn(
|
FlycheckHandle::spawn(
|
||||||
id,
|
id,
|
||||||
|
@ -706,6 +707,7 @@ impl GlobalState {
|
||||||
config.clone(),
|
config.clone(),
|
||||||
sysroot_root,
|
sysroot_root,
|
||||||
root.to_path_buf(),
|
root.to_path_buf(),
|
||||||
|
manifest_path.map(|it| it.to_path_buf()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
Loading…
Reference in a new issue