Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add setup step for generating rust-project.json
Signed-off-by: onur-ozkan <[email protected]>
  • Loading branch information
onur-ozkan committed Feb 3, 2024
commit e1259243f3a34bb24b3663bf442239e88938dd96
52 changes: 52 additions & 0 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::t;
use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
use crate::utils::helpers::hex_encode;
use crate::utils::ra_project::RustAnalyzerProject;
use crate::Config;
use sha2::Digest;
use std::env::consts::EXE_SUFFIX;
Expand Down Expand Up @@ -624,3 +625,54 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
}
Ok(should_create)
}

/// Sets up `rust-project.json`
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct RustProjectJson;

impl Step for RustProjectJson {
type Output = ();
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.alias("rust-project")
}
fn make_run(run: RunConfig<'_>) {
if run.builder.config.dry_run() {
return;
}

if let [cmd] = &run.paths[..] {
if cmd.assert_single_path().path.as_path().as_os_str() == "rust-project" {
run.builder.ensure(RustProjectJson);
}
}
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
let config = &builder.config;
if config.dry_run() {
return;
}

while !t!(create_ra_project_json_maybe(&config)) {}
}
}

fn create_ra_project_json_maybe(config: &Config) -> io::Result<bool> {
println!("\nx.py can automatically generate `rust-project.json` file for rust-analyzer");

let should_create = match prompt_user("Would you like to create rust-project.json?: [y/N]")? {
Some(PromptResult::Yes) => true,
_ => {
println!("Ok, skipping rust-project.json!");
return Ok(true);
}
};

if should_create {
let ra_project = RustAnalyzerProject::collect_ra_project_data(&config);
ra_project.generate_file(&config.src.join("rust-project.json"))?;
println!("Created `rust-project.json`");
}

Ok(should_create)
}
8 changes: 7 additions & 1 deletion src/bootstrap/src/core/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,13 @@ impl<'a> Builder<'a> {
run::GenerateWindowsSys,
run::GenerateCompletions,
),
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
Kind::Setup => describe!(
setup::Profile,
setup::Hook,
setup::Link,
setup::Vscode,
setup::RustProjectJson
),
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
// special-cased in Build::build()
Kind::Format | Kind::Suggest => vec![],
Expand Down
16 changes: 8 additions & 8 deletions src/bootstrap/src/core/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde_derive::Deserialize;

use crate::utils::cache::INTERNER;
use crate::utils::helpers::output;
use crate::{t, Build, Crate};
use crate::{t, Build, Config, Crate};

/// For more information, see the output of
/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
Expand Down Expand Up @@ -45,7 +45,7 @@ pub(crate) struct Target {
/// Collects and stores package metadata of each workspace members into `build`,
/// by executing `cargo metadata` commands.
pub fn build(build: &mut Build) {
for package in workspace_members(build) {
for package in workspace_members(&build.config) {
if package.source.is_none() {
let name = INTERNER.intern_string(package.name);
let mut path = PathBuf::from(package.manifest_path);
Expand Down Expand Up @@ -74,9 +74,9 @@ pub fn build(build: &mut Build) {
///
/// Note that `src/tools/cargo` is no longer a workspace member but we still
/// treat it as one here, by invoking an additional `cargo metadata` command.
pub(crate) fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
pub(crate) fn workspace_members(config: &Config) -> impl Iterator<Item = Package> {
let collect_metadata = |manifest_path| {
let mut cargo = Command::new(&build.initial_cargo);
let mut cargo = Command::new(&config.initial_cargo);
cargo
// Will read the libstd Cargo.toml
// which uses the unstable `public-dependency` feature.
Expand All @@ -86,7 +86,7 @@ pub(crate) fn workspace_members(build: &Build) -> impl Iterator<Item = Package>
.arg("1")
.arg("--no-deps")
.arg("--manifest-path")
.arg(build.src.join(manifest_path));
.arg(config.src.join(manifest_path));
let metadata_output = output(&mut cargo);
let Output { packages, .. } = t!(serde_json::from_str(&metadata_output));
packages
Expand All @@ -105,9 +105,9 @@ pub(crate) fn workspace_members(build: &Build) -> impl Iterator<Item = Package>
}

/// Invokes `cargo metadata` to get package metadata of whole workspace including the dependencies.
pub(crate) fn project_metadata(build: &Build) -> impl Iterator<Item = Package> {
pub(crate) fn project_metadata(config: &Config) -> impl Iterator<Item = Package> {
let collect_metadata = |manifest_path| {
let mut cargo = Command::new(&build.initial_cargo);
let mut cargo = Command::new(&config.initial_cargo);
cargo
// Will read the libstd Cargo.toml
// which uses the unstable `public-dependency` feature.
Expand All @@ -116,7 +116,7 @@ pub(crate) fn project_metadata(build: &Build) -> impl Iterator<Item = Package> {
.arg("--format-version")
.arg("1")
.arg("--manifest-path")
.arg(build.src.join(manifest_path));
.arg(config.src.join(manifest_path));
let metadata_output = output(&mut cargo);
let Output { packages, .. } = t!(serde_json::from_str(&metadata_output));
packages
Expand Down
17 changes: 9 additions & 8 deletions src/bootstrap/src/utils/ra_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use std::io;
use std::path::Path;

use crate::core::metadata::{project_metadata, workspace_members, Dependency};
use crate::Build;
use crate::Config;

#[derive(Debug, Deserialize, Serialize)]
/// FIXME(before-merge): doc-comment
struct RustAnalyzerProject {
pub(crate) struct RustAnalyzerProject {
crates: Vec<Crate>,
sysroot: String,
sysroot_src: String,
Expand All @@ -33,6 +33,7 @@ struct Crate {
edition: String,
env: BTreeMap<String, String>,
is_proc_macro: bool,
#[serde(skip_serializing_if = "Option::is_none")]
proc_macro_dylib_path: Option<String>,
is_workspace_member: bool,
root_module: String,
Expand All @@ -47,15 +48,15 @@ struct Dep {

impl RustAnalyzerProject {
#[allow(dead_code)] // FIXME(before-merge): remove this
pub(crate) fn collect_ra_project_data(build: &mut Build) -> Self {
pub(crate) fn collect_ra_project_data(config: &Config) -> Self {
let mut ra_project = RustAnalyzerProject {
crates: vec![],
sysroot: format!("{}", build.out.join("host").join("stage0").display()),
sysroot_src: format!("{}", build.src.join("library").display()),
sysroot: format!("{}", config.out.join("host").join("stage0").display()),
sysroot_src: format!("{}", config.src.join("library").display()),
};

let packages: Vec<_> = project_metadata(build).collect();
let workspace_members: Vec<_> = workspace_members(build).collect();
let packages: Vec<_> = project_metadata(config).collect();
let workspace_members: Vec<_> = workspace_members(config).collect();

for package in &packages {
let is_not_indirect_dependency = packages
Expand Down Expand Up @@ -94,7 +95,7 @@ impl RustAnalyzerProject {

if target
.src_path
.starts_with(&build.src.join("library").to_string_lossy().to_string())
.starts_with(&config.src.join("library").to_string_lossy().to_string())
{
krate.cfg.push("bootstrap".into());
}
Expand Down