Merge pull request #456 from GuillaumeGomez/clone-gcc
Add clone-gcc command
This commit is contained in:
commit
64fc213926
79
build_system/src/clone_gcc.rs
Normal file
79
build_system/src/clone_gcc.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
use crate::config::ConfigInfo;
|
||||||
|
use crate::utils::{git_clone, run_command_with_output};
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
fn show_usage() {
|
||||||
|
println!(
|
||||||
|
r#"
|
||||||
|
`clone-gcc` command help:
|
||||||
|
|
||||||
|
--out-path : Location where the GCC repository will be cloned (default: `./gcc`)"#
|
||||||
|
);
|
||||||
|
ConfigInfo::show_usage();
|
||||||
|
println!(" --help : Show this help");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Args {
|
||||||
|
out_path: PathBuf,
|
||||||
|
config_info: ConfigInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Args {
|
||||||
|
fn new() -> Result<Option<Self>, String> {
|
||||||
|
let mut command_args = Self::default();
|
||||||
|
|
||||||
|
let mut out_path = None;
|
||||||
|
|
||||||
|
// We skip binary name and the `clone-gcc` command.
|
||||||
|
let mut args = std::env::args().skip(2);
|
||||||
|
|
||||||
|
while let Some(arg) = args.next() {
|
||||||
|
match arg.as_str() {
|
||||||
|
"--out-path" => match args.next() {
|
||||||
|
Some(path) if !path.is_empty() => out_path = Some(path),
|
||||||
|
_ => {
|
||||||
|
return Err("Expected an argument after `--out-path`, found nothing".into())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"--help" => {
|
||||||
|
show_usage();
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
arg => {
|
||||||
|
if !command_args.config_info.parse_argument(arg, &mut args)? {
|
||||||
|
return Err(format!("Unknown option {}", arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
command_args.out_path = match out_path {
|
||||||
|
Some(p) => p.into(),
|
||||||
|
None => PathBuf::from("./gcc"),
|
||||||
|
};
|
||||||
|
return Ok(Some(command_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run() -> Result<(), String> {
|
||||||
|
let Some(args) = Args::new()? else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = git_clone("https://github.com/antoyo/gcc", Some(&args.out_path), false)?;
|
||||||
|
if result.ran_clone {
|
||||||
|
let gcc_commit = args.config_info.get_gcc_commit()?;
|
||||||
|
println!("Checking out GCC commit `{}`...", gcc_commit);
|
||||||
|
run_command_with_output(
|
||||||
|
&[&"git", &"checkout", &gcc_commit],
|
||||||
|
Some(Path::new(&result.repo_dir)),
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"There is already a GCC folder in `{}`, leaving things as is...",
|
||||||
|
args.out_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -192,9 +192,7 @@ impl ConfigInfo {
|
|||||||
command
|
command
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download_gccjit_if_needed(&mut self) -> Result<(), String> {
|
pub fn get_gcc_commit(&self) -> Result<String, String> {
|
||||||
let output_dir = Path::new(crate::BUILD_DIR).join("libgccjit");
|
|
||||||
|
|
||||||
let commit_hash_file = self.compute_path("libgccjit.version");
|
let commit_hash_file = self.compute_path("libgccjit.version");
|
||||||
let content = fs::read_to_string(&commit_hash_file).map_err(|_| {
|
let content = fs::read_to_string(&commit_hash_file).map_err(|_| {
|
||||||
format!(
|
format!(
|
||||||
@ -212,7 +210,14 @@ impl ConfigInfo {
|
|||||||
commit,
|
commit,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let output_dir = output_dir.join(commit);
|
Ok(commit.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn download_gccjit_if_needed(&mut self) -> Result<(), String> {
|
||||||
|
let output_dir = Path::new(crate::BUILD_DIR).join("libgccjit");
|
||||||
|
let commit = self.get_gcc_commit()?;
|
||||||
|
|
||||||
|
let output_dir = output_dir.join(&commit);
|
||||||
if !output_dir.is_dir() {
|
if !output_dir.is_dir() {
|
||||||
std::fs::create_dir_all(&output_dir).map_err(|err| {
|
std::fs::create_dir_all(&output_dir).map_err(|err| {
|
||||||
format!(
|
format!(
|
||||||
|
@ -4,6 +4,7 @@ use std::process;
|
|||||||
mod build;
|
mod build;
|
||||||
mod cargo;
|
mod cargo;
|
||||||
mod clean;
|
mod clean;
|
||||||
|
mod clone_gcc;
|
||||||
mod config;
|
mod config;
|
||||||
mod info;
|
mod info;
|
||||||
mod prepare;
|
mod prepare;
|
||||||
@ -27,19 +28,21 @@ fn usage() {
|
|||||||
"\
|
"\
|
||||||
Available commands for build_system:
|
Available commands for build_system:
|
||||||
|
|
||||||
cargo : Run cargo command
|
cargo : Run cargo command
|
||||||
clean : Run clean command
|
clean : Run clean command
|
||||||
prepare : Run prepare command
|
prepare : Run prepare command
|
||||||
build : Run build command
|
build : Run build command
|
||||||
test : Run test command
|
test : Run test command
|
||||||
info: : Run info command
|
info : Run info command
|
||||||
--help : Show this message"
|
clone-gcc : Run clone-gcc command
|
||||||
|
--help : Show this message"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Cargo,
|
Cargo,
|
||||||
Clean,
|
Clean,
|
||||||
|
CloneGcc,
|
||||||
Prepare,
|
Prepare,
|
||||||
Build,
|
Build,
|
||||||
Test,
|
Test,
|
||||||
@ -58,6 +61,7 @@ fn main() {
|
|||||||
Some("build") => Command::Build,
|
Some("build") => Command::Build,
|
||||||
Some("test") => Command::Test,
|
Some("test") => Command::Test,
|
||||||
Some("info") => Command::Info,
|
Some("info") => Command::Info,
|
||||||
|
Some("clone-gcc") => Command::CloneGcc,
|
||||||
Some("--help") => {
|
Some("--help") => {
|
||||||
usage();
|
usage();
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
@ -77,6 +81,7 @@ fn main() {
|
|||||||
Command::Build => build::run(),
|
Command::Build => build::run(),
|
||||||
Command::Test => test::run(),
|
Command::Test => test::run(),
|
||||||
Command::Info => info::run(),
|
Command::Info => info::run(),
|
||||||
|
Command::CloneGcc => clone_gcc::run(),
|
||||||
} {
|
} {
|
||||||
eprintln!("Command failed to run: {e}");
|
eprintln!("Command failed to run: {e}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::rustc_info::get_rustc_path;
|
use crate::rustc_info::get_rustc_path;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
cargo_install, git_clone, remove_file, run_command, run_command_with_output, walk_dir,
|
cargo_install, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -152,7 +152,7 @@ fn clone_and_setup<F>(repo_url: &str, checkout_commit: &str, extra: Option<F>) -
|
|||||||
where
|
where
|
||||||
F: Fn(&Path) -> Result<(), String>,
|
F: Fn(&Path) -> Result<(), String>,
|
||||||
{
|
{
|
||||||
let clone_result = git_clone(repo_url, Some(&Path::new(crate::BUILD_DIR)), false)?;
|
let clone_result = git_clone_root_dir(repo_url, &Path::new(crate::BUILD_DIR), false)?;
|
||||||
if !clone_result.ran_clone {
|
if !clone_result.ran_clone {
|
||||||
println!("`{}` has already been cloned", clone_result.repo_name);
|
println!("`{}` has already been cloned", clone_result.repo_name);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::build;
|
use crate::build;
|
||||||
use crate::config::{Channel, ConfigInfo};
|
use crate::config::{Channel, ConfigInfo};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
get_toolchain, git_clone, remove_file, run_command, run_command_with_env,
|
get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, run_command_with_env,
|
||||||
run_command_with_output_and_env, rustc_version_info, split_args, walk_dir,
|
run_command_with_output_and_env, rustc_version_info, split_args, walk_dir,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -487,15 +487,10 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> {
|
|||||||
);
|
);
|
||||||
let rust_dir_path = Path::new(crate::BUILD_DIR).join("rust");
|
let rust_dir_path = Path::new(crate::BUILD_DIR).join("rust");
|
||||||
// If the repository was already cloned, command will fail, so doesn't matter.
|
// If the repository was already cloned, command will fail, so doesn't matter.
|
||||||
let _ = run_command_with_output_and_env(
|
let _ = git_clone(
|
||||||
&[
|
"https://github.com/rust-lang/rust.git",
|
||||||
&"git",
|
Some(&rust_dir_path),
|
||||||
&"clone",
|
false,
|
||||||
&"https://github.com/rust-lang/rust.git",
|
|
||||||
&rust_dir_path,
|
|
||||||
],
|
|
||||||
None,
|
|
||||||
Some(env),
|
|
||||||
);
|
);
|
||||||
let rust_dir: Option<&Path> = Some(&rust_dir_path);
|
let rust_dir: Option<&Path> = Some(&rust_dir_path);
|
||||||
run_command(&[&"git", &"checkout", &"--", &"tests/"], rust_dir)?;
|
run_command(&[&"git", &"checkout", &"--", &"tests/"], rust_dir)?;
|
||||||
@ -720,7 +715,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||||||
|
|
||||||
let run_tests = |projects_path, iter: &mut dyn Iterator<Item = &&str>| -> Result<(), String> {
|
let run_tests = |projects_path, iter: &mut dyn Iterator<Item = &&str>| -> Result<(), String> {
|
||||||
for project in iter {
|
for project in iter {
|
||||||
let clone_result = git_clone(project, Some(projects_path), true)?;
|
let clone_result = git_clone_root_dir(project, projects_path, true)?;
|
||||||
let repo_path = Path::new(&clone_result.repo_dir);
|
let repo_path = Path::new(&clone_result.repo_dir);
|
||||||
run_cargo_command(&[&"build", &"--release"], Some(repo_path), env, args)?;
|
run_cargo_command(&[&"build", &"--release"], Some(repo_path), env, args)?;
|
||||||
run_cargo_command(&[&"test"], Some(repo_path), env, args)?;
|
run_cargo_command(&[&"test"], Some(repo_path), env, args)?;
|
||||||
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, ExitStatus, Output};
|
use std::process::{Command, ExitStatus, Output};
|
||||||
|
|
||||||
fn get_command_inner(
|
fn get_command_inner(
|
||||||
@ -254,20 +254,12 @@ pub struct CloneResult {
|
|||||||
pub repo_dir: String,
|
pub repo_dir: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn git_clone(
|
fn git_clone_inner(
|
||||||
to_clone: &str,
|
to_clone: &str,
|
||||||
dest: Option<&Path>,
|
dest: &Path,
|
||||||
shallow_clone: bool,
|
shallow_clone: bool,
|
||||||
|
repo_name: String,
|
||||||
) -> Result<CloneResult, String> {
|
) -> Result<CloneResult, String> {
|
||||||
let repo_name = to_clone.split('/').last().unwrap();
|
|
||||||
let repo_name = match repo_name.strip_suffix(".git") {
|
|
||||||
Some(n) => n.to_string(),
|
|
||||||
None => repo_name.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let dest = dest
|
|
||||||
.map(|dest| dest.join(&repo_name))
|
|
||||||
.unwrap_or_else(|| Path::new(&repo_name).into());
|
|
||||||
if dest.is_dir() {
|
if dest.is_dir() {
|
||||||
return Ok(CloneResult {
|
return Ok(CloneResult {
|
||||||
ran_clone: false,
|
ran_clone: false,
|
||||||
@ -289,6 +281,51 @@ pub fn git_clone(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_repo_name(url: &str) -> String {
|
||||||
|
let repo_name = url.split('/').last().unwrap();
|
||||||
|
match repo_name.strip_suffix(".git") {
|
||||||
|
Some(n) => n.to_string(),
|
||||||
|
None => repo_name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn git_clone(
|
||||||
|
to_clone: &str,
|
||||||
|
dest: Option<&Path>,
|
||||||
|
shallow_clone: bool,
|
||||||
|
) -> Result<CloneResult, String> {
|
||||||
|
let repo_name = get_repo_name(to_clone);
|
||||||
|
let tmp: PathBuf;
|
||||||
|
|
||||||
|
let dest = match dest {
|
||||||
|
Some(dest) => dest,
|
||||||
|
None => {
|
||||||
|
tmp = repo_name.clone().into();
|
||||||
|
&tmp
|
||||||
|
}
|
||||||
|
};
|
||||||
|
git_clone_inner(to_clone, dest, shallow_clone, repo_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function differs from `git_clone` in how it handles *where* the repository will be cloned.
|
||||||
|
/// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is
|
||||||
|
/// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into
|
||||||
|
/// `a/b`.
|
||||||
|
pub fn git_clone_root_dir(
|
||||||
|
to_clone: &str,
|
||||||
|
dest_parent_dir: &Path,
|
||||||
|
shallow_clone: bool,
|
||||||
|
) -> Result<CloneResult, String> {
|
||||||
|
let repo_name = get_repo_name(to_clone);
|
||||||
|
|
||||||
|
git_clone_inner(
|
||||||
|
to_clone,
|
||||||
|
&dest_parent_dir.join(&repo_name),
|
||||||
|
shallow_clone,
|
||||||
|
repo_name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_dir<P, D, F>(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String>
|
pub fn walk_dir<P, D, F>(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user