Skip to content

Commit

Permalink
refactor src/tools/x
Browse files Browse the repository at this point in the history
Signed-off-by: ozkanonur <[email protected]>
  • Loading branch information
onur-ozkan committed May 16, 2023
1 parent a8f85ae commit 8ad8906
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 146 deletions.
56 changes: 52 additions & 4 deletions src/bootstrap/bin/bootstrap-shim.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,56 @@
use std::{env, process::Command};
use std::{
env, io,
process::{self, Command, ExitStatus},
};

use bootstrap::{Flags, MinimalConfig};

#[path = "../../../src/tools/x/src/main.rs"]
mod run_python;
mod x;

/// We are planning to exclude python logic from x script by executing bootstrap-shim
/// immediately. Since `find_and_run_available_bootstrap_script` executes x script first,
/// any changes on bootstrap will not be seen. To prevent this problem, in bootstrap-shim
/// we want to call the python script directly.
fn find_and_run_py_bootstrap_script() {
#[cfg(unix)]
fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
use std::os::unix::process::CommandExt;
Err(command.exec())
}

#[cfg(not(unix))]
fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
command.status()
}

let current_path = match env::current_dir() {
Ok(dir) => dir,
Err(err) => {
eprintln!("Failed to get current directory: {err}");
process::exit(1);
}
};

for dir in current_path.ancestors() {
let candidate = dir.join("x.py");
if candidate.exists() {
let mut cmd: Command;
cmd = Command::new(x::python());
cmd.arg(&candidate).args(env::args().skip(1)).current_dir(dir);
let result = exec_or_status(&mut cmd);

match result {
Err(error) => {
eprintln!("Failed to invoke `{:?}`: {}", cmd, error);
}
Ok(status) => {
process::exit(status.code().unwrap_or(1));
}
}
}
}
}

fn main() {
let args = env::args().skip(1).collect::<Vec<_>>();
Expand All @@ -15,16 +62,17 @@ fn main() {
let bootstrap_bin = if let Some(commit) = last_modified_bootstrap_commit(&config) {
config.download_bootstrap(&commit)
} else {
return run_python::main();
return find_and_run_py_bootstrap_script();
};

let args: Vec<_> = std::env::args().skip(1).collect();
println!("Running pre-compiled bootstrap binary");
Command::new(bootstrap_bin).args(args).status().expect("failed to spawn bootstrap binairy");
}

fn last_modified_bootstrap_commit(config: &MinimalConfig) -> Option<String> {
config.last_modified_commit(
&["src/bootstrap", "src/tools/build_helper"],
&["src/bootstrap", "src/tools/build_helper", "src/tools/x"],
"download-bootstrap",
true,
)
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,6 @@ impl<'a> Builder<'a> {
check::RustAnalyzer,
check::Rustfmt,
check::Bootstrap,
check::BootstrapShim,
),
Kind::Test => describe!(
crate::toolstate::ToolStateCheck,
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,6 @@ tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InT

// FIXME: currently these are marked as ToolRustc, but they should be ToolBootstrap instead to avoid having to build the compiler first
tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
tool_check_step!(BootstrapShim, "src/bootstrap/bin/bootstrap-shim", SourceType::InTree, false);

/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
Expand Down
21 changes: 11 additions & 10 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ pub struct Config {
pub jobs: Option<u32>,
pub cmd: Subcommand,
pub incremental: bool,
pub dry_run: DryRun,
/// Arguments appearing after `--` to be forwarded to tools,
/// e.g. `--fix-broken` or test arguments.
pub free_args: Vec<String>,
Expand Down Expand Up @@ -395,7 +394,7 @@ impl Target {
/// `Config` structure.
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub struct TomlConfig {
struct TomlConfig {
changelog_seen: Option<usize>,
build: Option<Build>,
install: Option<Install>,
Expand Down Expand Up @@ -774,17 +773,19 @@ impl Config {
args
}

pub fn parse(args: &[String], custom_toml_config: Option<TomlConfig>) -> Config {
pub fn parse(args: &[String], custom_toml_config: Option<&str>) -> Config {
let mut flags = Flags::parse(&args);
let mut config = Config::default_opts();

let mut toml: TomlConfig = custom_toml_config.unwrap_or_else(|| {
let mut toml: TomlConfig = if let Some(custom_toml_config) = custom_toml_config {
toml::from_str(custom_toml_config).unwrap()
} else {
set_cfg_path_and_return_toml_cfg(
config.src.clone(),
flags.config.clone(),
&mut config.config,
)
});
};

config.minimal_config = MinimalConfig::parse(&flags, toml.build.clone());

Expand Down Expand Up @@ -814,11 +815,6 @@ impl Config {
crate::detail_exit(1);
}

let build = toml.build.clone().unwrap_or_default();
if let Some(file_build) = build.build.as_ref() {
config.build = TargetSelection::from_user(file_build);
};

if let Some(include) = &toml.profile {
let mut include_path = config.src.clone();
include_path.push("src");
Expand All @@ -831,6 +827,11 @@ impl Config {

config.changelog_seen = toml.changelog_seen;

let build = toml.build.unwrap_or_default();
if let Some(file_build) = build.build {
config.build = TargetSelection::from_user(&file_build);
};

set(&mut config.out, flags.build_dir.or_else(|| build.build_dir.map(PathBuf::from)));
// NOTE: Bootstrap spawns various commands with different working directories.
// To avoid writing to random places on the file system, `config.out` needs to be an absolute path.
Expand Down
8 changes: 2 additions & 6 deletions src/bootstrap/config/tests.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use super::{Config, Flags, TomlConfig};
use super::{Config, Flags};
use clap::CommandFactory;
use std::{env, path::Path};

fn toml(config: &str) -> TomlConfig {
toml::from_str(config).unwrap()
}

fn parse(config: &str) -> Config {
Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()], Some(toml(config)))
Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()], Some(config))
}

#[test]
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2327,7 +2327,6 @@ impl Step for BootstrapShim {
const ONLY_HOSTS: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
// Create this even with only `dist bootstrap` to avoid having to update all CI builders.
run.alias("bootstrap-shim")
}

Expand Down
Loading

0 comments on commit 8ad8906

Please sign in to comment.