Skip to content

Commit

Permalink
add setup step for generating rust-project.json
Browse files Browse the repository at this point in the history
Signed-off-by: onur-ozkan <work@onurozkan.dev>
  • Loading branch information
onur-ozkan committed Feb 3, 2024
1 parent e46ac21 commit 73b9848
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 17 deletions.
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

0 comments on commit 73b9848

Please sign in to comment.