You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
5.4 KiB
Rust
152 lines
5.4 KiB
Rust
use std::env;
|
|
use std::process::Command;
|
|
|
|
use crate::{info, log};
|
|
|
|
pub fn clone(verbose: bool) {
|
|
// Read config struct from mlc.toml
|
|
let config = crate::internal::parse_cfg(verbose);
|
|
log!(verbose, "Config: {:?}", config);
|
|
// Parse repositories from config
|
|
let repos = &config.repositories;
|
|
log!(verbose, "Repos: {:?}", repos);
|
|
|
|
// Get a vector of all files/dirs in the current directory, excluding config file
|
|
let dir_paths = std::fs::read_dir(".").unwrap();
|
|
let mut dirs = dir_paths
|
|
.map(|x| x.unwrap().path().display().to_string())
|
|
.collect::<Vec<String>>();
|
|
|
|
// Remove mlc.toml and .git from output
|
|
dirs.retain(|x| *x != "./mlc.toml" && *x != ".\\mlc.toml");
|
|
dirs.retain(|x| *x != "./.git" && *x != ".\\.git");
|
|
|
|
// If mode is repository, also exclude repository mode directories
|
|
if config.mode.repository.is_some() {
|
|
dirs.retain(|x| {
|
|
*x != format!("./{}", config.mode.repository.as_ref().unwrap().name)
|
|
&& *x != format!(".\\{}", config.mode.repository.as_ref().unwrap().name)
|
|
});
|
|
dirs.retain(|x| *x != "./out" && *x != ".\\out");
|
|
}
|
|
log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs);
|
|
|
|
// Creates a vector of the difference between cloned repos and repos defined in config
|
|
let mut repo_diff = vec![];
|
|
for repo in repos {
|
|
let name = &repo.name;
|
|
|
|
if !dirs.contains(&format!("./{}", name)) && !dirs.contains(&format!(".\\{}", name)) {
|
|
repo_diff.push(repo);
|
|
}
|
|
}
|
|
|
|
// Diff logic
|
|
if repo_diff.is_empty() {
|
|
// No diff, do nothing
|
|
log!(verbose, "No diff");
|
|
info!("All repos are already cloned");
|
|
} else {
|
|
log!(verbose, "Diff: {:?}", repo_diff);
|
|
// This is just for pretty display purposes
|
|
let display = repo_diff
|
|
.iter()
|
|
.map(|x| x.name.to_string())
|
|
.collect::<Vec<String>>()
|
|
.join(" ");
|
|
info!("New/missing repos to clone: {}", display);
|
|
|
|
// Clone all diff repos
|
|
for r in repo_diff {
|
|
log!(verbose, "Depth: {:?}", r.extra);
|
|
log!(verbose, "Cloning {}", r.name);
|
|
|
|
if r.extra.is_some() && config.base.mode == "workspace" {
|
|
info!(
|
|
"Cloning ({} mode): {} with `--depth {}`",
|
|
config.base.mode,
|
|
r.name,
|
|
r.extra.as_ref().unwrap()
|
|
);
|
|
} else if r.extra.is_some() && config.base.mode == "repository" {
|
|
info!(
|
|
"Cloning ({} mode): {} at {}",
|
|
config.base.mode,
|
|
r.name,
|
|
r.extra.as_ref().unwrap()
|
|
);
|
|
} else {
|
|
info!("Cloning ({} mode): {}", config.base.mode, r.name);
|
|
}
|
|
|
|
if r.extra.is_some() && config.base.mode == "workspace" {
|
|
// Clone with specified extra depth
|
|
Command::new("git")
|
|
.args(&["clone", &r.url, &r.name])
|
|
// If a branch is specified, clone that specific branch
|
|
.args(if r.branch.is_some() {
|
|
vec!["-b", r.branch.as_ref().unwrap()]
|
|
} else {
|
|
vec![]
|
|
})
|
|
.args(if r.extra.is_some() {
|
|
vec!["--depth", r.extra.as_ref().unwrap()]
|
|
} else {
|
|
vec![]
|
|
})
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.unwrap();
|
|
} else if config.base.mode == "repository" {
|
|
// Clone and checkout specified hash
|
|
// Create an empty directory with repo.name and enter it
|
|
let root_dir = env::current_dir().unwrap();
|
|
|
|
// Git clone the repo
|
|
Command::new("git")
|
|
.args(&["clone", &r.url, &r.name])
|
|
.args(if r.branch.is_some() {
|
|
vec!["-b", r.branch.as_ref().unwrap()]
|
|
} else {
|
|
vec![]
|
|
})
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.unwrap();
|
|
|
|
std::env::set_current_dir(&r.name).unwrap();
|
|
log!(verbose, "Entered directory: {}", r.name);
|
|
|
|
// Git checkout the PKGBUILD from the hash
|
|
if r.extra.is_some() {
|
|
Command::new("git")
|
|
.args(&["checkout", r.extra.as_ref().unwrap()])
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.unwrap();
|
|
}
|
|
|
|
// Return to the root directory
|
|
std::env::set_current_dir(root_dir).unwrap();
|
|
log!(verbose, "Returned to root directory");
|
|
} else {
|
|
// Clone normally
|
|
Command::new("git")
|
|
.args(&["clone", &r.url, &r.name])
|
|
.args(if r.branch.is_some() {
|
|
vec!["-b", r.branch.as_ref().unwrap()]
|
|
} else {
|
|
vec![]
|
|
})
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|