diff --git a/integrations/rust-project/src/cli/develop.rs b/integrations/rust-project/src/cli/develop.rs index d075e9d500fe8..9b1c130b7ee46 100644 --- a/integrations/rust-project/src/cli/develop.rs +++ b/integrations/rust-project/src/cli/develop.rs @@ -107,14 +107,27 @@ impl Develop { } if let crate::Command::DevelopJson { + sysroot_mode, args, log_scuba_to_stdout: _, } = command { let out = Output::Stdout; - let sysroot = SysrootConfig::BuckConfig; let mode = select_mode(None); + let sysroot = match sysroot_mode { + crate::SysrootMode::BuckConfig => SysrootConfig::BuckConfig, + crate::SysrootMode::Rustup => SysrootConfig::Rustup, + crate::SysrootMode::FullPath(path) => SysrootConfig::Sysroot(path), + crate::SysrootMode::Command(cmd_args) => { + let cmd = cmd_args[0].clone(); + let args = cmd_args[1..].to_vec(); + let output = std::process::Command::new(cmd).args(args).output().unwrap(); + let path = String::from_utf8(output.stdout).unwrap(); + SysrootConfig::Sysroot(PathBuf::from(path.trim())) + } + }; + let buck = buck::Buck::new(mode); let develop = Develop { diff --git a/integrations/rust-project/src/main.rs b/integrations/rust-project/src/main.rs index afb4b12f79ba9..9b1bd80370a28 100644 --- a/integrations/rust-project/src/main.rs +++ b/integrations/rust-project/src/main.rs @@ -120,6 +120,16 @@ enum Command { #[clap(long, hide = true)] log_scuba_to_stdout: bool, + // FIXME XXX: remove this after everything in fbcode is migrated off + // of buckconfig implicitly. + #[cfg(fbcode_build)] + #[clap(long, default_value = "buckconfig")] + sysroot_mode: SysrootMode, + + #[cfg(not(fbcode_build))] + #[clap(long, default_value = "rustup")] + sysroot_mode: SysrootMode, + args: JsonArguments, }, /// Build the saved file's owning target. This is meant to be used by IDEs to provide diagnostics on save. @@ -137,6 +147,43 @@ enum Command { }, } +/// The 'develop-json' command needs to have 3 modes: +/// 1. Static `.buckconfig` setting +/// 2. Absolute path setting +/// 3. Use `rustc --print=sysroot` ("rustup mode") +/// 4. Run a command and take the output from stdout +#[derive(PartialEq, Clone, Debug, Deserialize)] +enum SysrootMode { + Rustup, + Command(Vec), + FullPath(PathBuf), + BuckConfig, +} + +impl FromStr for SysrootMode { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if s == "rustup" { + Ok(SysrootMode::Rustup) + } else if s == "buckconfig" { + Ok(SysrootMode::BuckConfig) + } else if s.starts_with("path:") { + let s = s.trim_start_matches("path:"); + Ok(SysrootMode::FullPath(PathBuf::from(s))) + } else if s.starts_with("cmd:") { + let s = s.trim_start_matches("cmd:"); + Ok(SysrootMode::Command( + s.split_whitespace() + .map(|s| s.to_owned()) + .collect::>(), + )) + } else { + Err(anyhow::anyhow!("Invalid mode: {}", s)) + } + } +} + #[derive(PartialEq, Clone, Debug, Deserialize)] #[serde(rename_all = "camelCase")] enum JsonArguments { @@ -325,6 +372,7 @@ fn json_args_pass() { let expected = Opt { command: Some(Command::DevelopJson { args, + sysroot_mode: SysrootMode::Rustup, log_scuba_to_stdout: false, }), version: false, @@ -341,6 +389,7 @@ fn json_args_pass() { let expected = Opt { command: Some(Command::DevelopJson { args, + sysroot_mode: SysrootMode::Rustup, log_scuba_to_stdout: false, }), version: false, @@ -357,6 +406,7 @@ fn json_args_pass() { let expected = Opt { command: Some(Command::DevelopJson { args, + sysroot_mode: SysrootMode::Rustup, log_scuba_to_stdout: false, }), version: false,