diff --git a/crates/starpls/src/commands/server.rs b/crates/starpls/src/commands/server.rs index 7dc07e9..d859155 100644 --- a/crates/starpls/src/commands/server.rs +++ b/crates/starpls/src/commands/server.rs @@ -42,6 +42,10 @@ pub(crate) struct ServerCommand { #[clap(long = "analysis_debounce_interval", default_value_t = 250)] pub(crate) analysis_debounce_interval: u64, + /// Whether to use buildozer to query for targets. + #[clap(long = "use_buildozer", default_value_t = false)] + pub(crate) use_buildozer: bool, + #[command(flatten)] pub(crate) inference_options: InferenceOptions, } diff --git a/crates/starpls/src/server.rs b/crates/starpls/src/server.rs index 64eefac..7c6d8fa 100644 --- a/crates/starpls/src/server.rs +++ b/crates/starpls/src/server.rs @@ -90,7 +90,8 @@ impl Server { // Determine Bazel configuration. let mut has_bazel_init_err = false; - let bazel_client = Arc::new(BazelCLI::new(&bazel_path)); + let bazel_client = + Arc::new(BazelCLI::new(&bazel_path).with_buildozer(config.args.use_buildozer)); let bazel_cx = match BazelContext::new(&*bazel_client) { Ok(cx) => cx, Err(err) => { diff --git a/crates/starpls_bazel/src/client.rs b/crates/starpls_bazel/src/client.rs index 9122b85..dddbd44 100644 --- a/crates/starpls_bazel/src/client.rs +++ b/crates/starpls_bazel/src/client.rs @@ -39,16 +39,23 @@ pub trait BazelClient: Send + Sync + 'static { pub struct BazelCLI { executable: PathBuf, repo_mappings: RwLock>>, + use_buildozer: bool, } impl BazelCLI { pub fn new(executable: impl AsRef) -> Self { Self { executable: executable.as_ref().to_path_buf(), - ..Default::default() + repo_mappings: Default::default(), + use_buildozer: false, } } + pub fn with_buildozer(mut self, use_buildozer: bool) -> Self { + self.use_buildozer = use_buildozer; + self + } + fn run_command(&self, args: I) -> anyhow::Result> where I: IntoIterator, @@ -64,6 +71,22 @@ impl BazelCLI { } Ok(output.stdout) } + + fn run_buildozer_command(&self, args: I) -> anyhow::Result> + where + I: IntoIterator, + S: AsRef, + { + let output = Command::new("buildozer").args(args).output()?; + if !output.status.success() { + bail!( + "failed to run buildozer command with exit status {}, stderr={:?}", + output.status, + str::from_utf8(&output.stderr)?, + ); + } + Ok(output.stdout) + } } impl BazelClient for BazelCLI { @@ -174,12 +197,24 @@ impl BazelClient for BazelCLI { } fn query_all_workspace_targets(&self) -> anyhow::Result> { - let output = self.run_command(["query", "kind('.* rule', ...)"])?; - let targets = str::from_utf8(&output)? - .lines() - .map(|line| line.to_string()) - .collect(); - Ok(targets) + if self.use_buildozer { + // Use buildozer to query targets + let output = self.run_buildozer_command(["print label", "//...:*"])?; + let targets = str::from_utf8(&output)? + .lines() + .filter(|line| !line.is_empty()) + .map(|line| line.to_string()) + .collect(); + Ok(targets) + } else { + // Use bazel query + let output = self.run_command(["query", "kind('.* rule', ...)"])?; + let targets = str::from_utf8(&output)? + .lines() + .map(|line| line.to_string()) + .collect(); + Ok(targets) + } } fn fetch_repo(&self, repo: &str) -> anyhow::Result<()> { @@ -202,6 +237,7 @@ impl Default for BazelCLI { Self { executable: "bazel".into(), repo_mappings: Default::default(), + use_buildozer: false, } } }