mod structs;
pub use crate::structs::*;
use anyhow::bail;
pub(crate) use anyhow::Ok;
pub use anyhow::{Error, Result};
pub use flate2::{write::GzEncoder, Compression};
pub use serde::{Deserialize, Serialize};
pub use std::{cell::RefCell, path::Path};
use url::Url;
fn main() -> anyhow::Result<(), anyhow::Error> {
match std::path::Path::new("osbuilder.ron").exists() {
true => {
println!(">> Build File exists, everything's OK")
}
false => {
println!(">> Creating the config file right now");
let cfg = Cfg {
buildopts: BuildOpts {
tb_name: "mtos_latest".to_string(),
distro_name: "MatuushOS".to_string(),
version: 0.9999,
threads: 6,
to_fetch: vec!["".to_string()].into(),
bdir: "".to_string(),
dir_structure: "MatuushOS".to_string(),
xcscriptdir: String::from(""),
bscriptdir: String::from(""),
support_url: String::from(""),
}.into(),
};
println!(">> Creating config file at {:?}", std::env::current_dir());
std::fs::write(
Path::new("osbuilder.ron").to_path_buf(),
ron::ser::to_string(&cfg.buildopts)?,
)?;
println!(">> DONE\n>> Make sure you edit this file according to your needs or you'll screw it up.");
std::process::exit(0);
}
}
let ron: Cfg = ron::de::from_str::<Cfg>(&std::fs::read_to_string("osbuilder.ron")?)?;
match std::path::Path::new(std::path::Path::new(&ron.buildopts.bdir)).exists() {
true => std::fs::remove_dir_all(Path::new(&ron.buildopts.bdir))?,
false => {
println!(">> Builddir does not exists, creating it right now");
let mut clfs: String = String::new();
clfs.push_str(&ron.buildopts.bdir);
println!(">> Using {} as the build directory", clfs);
println!(">> Creating build directory");
std::fs::DirBuilder::new().create(clfs)?;
std::fs::DirBuilder::new().create(Path::new(&ron.buildopts.bdir).join("vfs"))?;
std::fs::DirBuilder::new()
.create(Path::new(&ron.buildopts.bdir).join("vfs").join("scripts"))?;
std::fs::DirBuilder::new()
.create(Path::new(&ron.buildopts.bdir).join("vfs").join("src"))?;
}
}
println!(">> Build directory created, moving on\n>> Creating the virtual filesystem");
if &ron.buildopts.dir_structure == "Standard Linux" {
std::env::set_current_dir(Path::new(&ron.buildopts.bdir).join("vfs"))?;
for i in [
"bin", "lib", "sbin", "usr", "etc", "var",
]
.iter()
{
std::fs::DirBuilder::new().recursive(true).create(i)?;
println!("\t>> Created directory {:?}", i);
}
for sym in ["bin", "lib", "sbin"].iter() {
#[cfg(target_os = "linux")]
std::os::unix::fs::symlink(sym, Path::new("usr").join(sym))?;
}
}
println!(">> Copying buildscripts");
match std::path::Path::new(std::path::Path::new(&ron.buildopts.bscriptdir)).exists() {
true => std::fs::copy(
&ron.buildopts.bscriptdir,
Path::new(&ron.buildopts.bdir).join("scripts"),
)?,
false => {
bail!(
"!! The directory {:?} doesn't exists",
std::path::Path::new(&ron.buildopts.bscriptdir).to_str()
);
}
};
println!(">> Downloading sources");
for dl in ron.buildopts.to_fetch.borrow().iter() {
let u = Url::parse(dl)?;
fetch_data::download(
dl,
Path::new(&ron.buildopts.bdir)
.join("vfs")
.join("src")
.join(u.path()),
)?;
println!("\t>> Downloaded {} from {}", u.path(), dl);
}
println!(">> Let's finally build {:?}", ron.buildopts.distro_name);
println!("\t>> Running crosscompiling scripts");
for entry in
walkdir::WalkDir::new(Path::new(&ron.buildopts.bdir).join(&ron.buildopts.xcscriptdir))
.sort_by_file_name()
{
let path = std::path::PathBuf::from(entry?.path());
if let Some(ext) = path.extension() {
if ext == "sh" {
let path_string = path.display().to_string();
let args: Vec<&str> = vec![path_string.as_str()];
std::process::Command::new("sh -c").args(args).output()?;
}
}
}
println!("\t>> Running build scripts");
for entry in walkdir::WalkDir::new(Path::new(&ron.buildopts.bdir).join("vfs/scripts"))
.sort_by_file_name()
{
let path = std::path::PathBuf::from(entry?.path());
if let Some(ext) = path.extension() {
if ext == "sh" {
let path_string = path.display().to_string();
let args: Vec<&str> = vec![path_string.as_str()];
std::process::Command::new("bash -c").args(args).output()?;
}
}
}
println!(">> Compressing final file system");
let mut filename = String::from(&ron.buildopts.tb_name);
filename.push_str(".tar.gz");
let f = std::fs::File::create(filename)?;
let enc = GzEncoder::new(f, Compression::default());
let mut tar = tar::Builder::new(enc);
tar.append_dir_all(".", Path::new(&ron.buildopts.bdir).join("vfs"))?;
Ok(())
}