Skip to content

Commit

Permalink
refactor: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
llenotre committed Nov 10, 2024
1 parent 8b11918 commit e45e128
Show file tree
Hide file tree
Showing 14 changed files with 89 additions and 221 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion builder/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::{desc::BuildDescriptor, WORK_DIR};
use anyhow::Result;
use common::serde_json;
use flate2::{write::GzEncoder, Compression};
use std::{
fs,
Expand Down Expand Up @@ -37,7 +38,8 @@ impl BuildProcess {
/// `input_path` is the path to the directory containing information to build the package.
pub fn new(input_path: PathBuf) -> io::Result<Self> {
let build_desc_path = input_path.join("package.json");
let build_desc = common::util::read_json::<BuildDescriptor>(&build_desc_path)?;
let build_desc = fs::read_to_string(build_desc_path)?;
let build_desc = serde_json::from_str(&build_desc)?;
Ok(Self {
input_path,
build_desc,
Expand Down
37 changes: 23 additions & 14 deletions builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::{
util::{get_build_triplet, get_jobs_count},
};
use anyhow::{anyhow, bail, Result};
use common::repository::Repository;
use std::{env, fs, path::PathBuf, process::exit, str};
use common::{repository::Repository, serde_json};
use std::{env, fs, io, path::PathBuf, process::exit, str};
use tokio::runtime::Runtime;

/// The path to the work directory.
Expand Down Expand Up @@ -41,6 +41,25 @@ fn print_usage(bin: &str) {
eprintln!("All environment variable are optional");
}

/// Prepares the repository's directory for the package.
///
/// On success, the function returns the output archive path.
fn prepare(build_process: &BuildProcess, to: PathBuf) -> io::Result<PathBuf> {
// Create directory
let build_desc = build_process.get_build_desc();
let name = &build_desc.package.name;
let version = &build_desc.package.version;
let package_path = to.join(name).join(version.to_string());
fs::create_dir_all(&package_path)?;
// Create descriptor
let desc_path = package_path.join("desc");
let desc = serde_json::to_string(&build_desc.package)?;
fs::write(desc_path, desc)?;
// Get archive path
let repo = Repository::load(to)?;
Ok(repo.get_archive_path(name, version))
}

/// Builds the package.
///
/// `from` and `to` correspond to the command line arguments.
Expand Down Expand Up @@ -70,18 +89,8 @@ fn build(from: PathBuf, to: PathBuf) -> Result<()> {
bail!("Package build failed!");
}
println!("[INFO] Prepare repository at `{}`...", to.display());
// TODO Move to separate function
let archive_path = {
let build_desc = build_process.get_build_desc();
let name = &build_desc.package.name;
let version = &build_desc.package.version;
let package_path = to.join(name).join(version.to_string());
fs::create_dir_all(&package_path)?;
let desc_path = package_path.join("desc");
common::util::write_json(&desc_path, &build_desc.package)?;
let repo = Repository::load(to)?;
repo.get_archive_path(name, version)
};
let archive_path = prepare(&build_process, to)
.map_err(|e| anyhow!("Failed to prepare directory for package: {e}"))?;
println!("[INFO] Create archive...");
build_process
.create_archive(&archive_path)
Expand Down
1 change: 0 additions & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"

[dependencies]
common = { path = "../common" }
tokio = { version = "1.41.1", features = ["macros", "rt", "rt-multi-thread"] }

[features]
default = []
Expand Down
55 changes: 13 additions & 42 deletions client/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use common::{
repository::Repository,
Environment,
};
use std::{collections::HashMap, path::PathBuf};
use std::{collections::HashMap, io, path::PathBuf};

// TODO Clean
/// Installs the given list of packages.
Expand All @@ -22,20 +22,17 @@ use std::{collections::HashMap, path::PathBuf};
pub async fn install(
names: &[String],
env: &mut Environment,
local_repos: &[PathBuf],
local_repos: Vec<PathBuf>,
) -> Result<()> {
let installed = env.load_installed_list()?;

let mut failed = false;

// The list of repositories
let repos = local_repos
.iter()
.map(|path| Repository::load(path.clone()))
.collect::<Result<Vec<_>, _>>()?;
.into_iter()
.map(Repository::load)
.collect::<io::Result<Vec<_>>>()?;
// Tells whether the operation failed
let mut failed = false;
// The list of packages to install with their respective repository
let mut packages = HashMap::<Package, &Repository>::new();

for name in names {
let pkg = repository::get_package_with_constraint(&repos, name, None)?;
let Some((repo, pkg)) = pkg else {
Expand All @@ -44,23 +41,17 @@ pub async fn install(
continue;
};
packages.insert(pkg, repo);

if let Some(installed) = installed.get(name) {
println!(
"Package `{name}` version `{}` is already installed. Reinstalling",
installed.desc.version
);
// If already installed, print message
if let Some(version) = env.get_installed_version(name) {
println!("Package `{name}` version `{version}` is already installed. Reinstalling",);
}
}
if failed {
bail!("installation failed");
}

println!("Resolving dependencies...");

// The list of all packages, dependencies included
let mut total_packages = packages.clone();

// TODO check dependencies for all packages at once to avoid duplicate errors
// Resolving dependencies
for (package, _) in packages {
Expand All @@ -79,14 +70,11 @@ pub async fn install(
return None;
}
};

match pkg {
Some((repo, pkg)) => Some((pkg, repo)),

// If not present, check on remote
None => {
// TODO
todo!();
todo!()
}
}
},
Expand All @@ -95,39 +83,31 @@ pub async fn install(
for e in errs {
eprintln!("{e}");
}

failed = true;
}
}
if failed {
bail!("installation failed");
}

println!("Packages to be installed:");

// List packages to be installed
#[cfg(feature = "network")]
{
let mut total_size = 0;
for (pkg, repo) in &total_packages {
let name = &pkg.name;
let version = &pkg.version;

match repo.get_package(name, version)? {
Some(_) => println!("\t- {name} ({version}) - cached"),

None => {
let remote = repo.get_remote().unwrap();

// Get package size from remote
let remote = repo.get_remote().unwrap();
let size = remote.get_size(pkg).await?;
total_size += size;

println!("\t- {name} ({version}) - download size: {size}");
}
}
}

println!(
"Total download size: {}",
common::maestro_utils::util::ByteSize(total_size)
Expand All @@ -139,24 +119,20 @@ pub async fn install(
println!("\t- {} ({}) - cached", pkg.name, pkg.version);
}
}

if !confirm::prompt() {
println!("Aborting.");
return Ok(());
}

#[cfg(feature = "network")]
{
println!("Downloading packages...");
let mut futures = Vec::new();

// TODO download biggest packages first (sort_unstable by decreasing size)
for (pkg, repo) in &total_packages {
if repo.is_in_cache(&pkg.name, &pkg.version) {
println!("`{}` is in cache.", &pkg.name);
continue;
}

if let Some(remote) = repo.get_remote() {
// TODO limit the number of packages downloaded concurrently
futures.push((
Expand All @@ -173,7 +149,6 @@ pub async fn install(
));
}
}

// TODO Add progress bar
for (name, version, f) in futures {
match f.await {
Expand All @@ -187,14 +162,11 @@ pub async fn install(
bail!("installation failed");
}
}

println!();
println!("Installing packages...");

// Installing all packages
// Install all packages
for (pkg, repo) in total_packages {
println!("Installing `{}`...", pkg.name);

let archive_path = repo.get_archive_path(&pkg.name, &pkg.version);
if let Err(e) = env.install(&pkg, &archive_path) {
eprintln!("Failed to install `{}`: {e}", &pkg.name);
Expand All @@ -204,6 +176,5 @@ pub async fn install(
if failed {
bail!("installation failed");
}

Ok(())
}
18 changes: 8 additions & 10 deletions client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod update;

use common::{
anyhow::{anyhow, Result},
Environment,
tokio, Environment,
};
use install::install;
use remove::remove;
Expand All @@ -19,7 +19,6 @@ use std::{
path::{Path, PathBuf},
process::exit,
};
use tokio::runtime::Runtime;

/// Prints command line usage.
fn print_usage() {
Expand Down Expand Up @@ -73,7 +72,7 @@ fn get_env(sysroot: &Path) -> Result<Environment> {
Environment::with_root(sysroot)?.ok_or(anyhow!("failed to acquire lockfile"))
}

fn main_impl(sysroot: &Path, local_repos: &[PathBuf]) -> Result<bool> {
async fn main_impl(sysroot: &Path, local_repos: Vec<PathBuf>) -> Result<bool> {
// If no argument is specified, print usage
let args: Vec<String> = env::args().collect();
if args.len() <= 1 {
Expand All @@ -93,8 +92,7 @@ fn main_impl(sysroot: &Path, local_repos: &[PathBuf]) -> Result<bool> {
#[cfg(feature = "network")]
"update" => {
let mut env = get_env(sysroot)?;
let rt = Runtime::new()?;
rt.block_on(update::update(&mut env))?;
update::update(&mut env).await?;
Ok(true)
}
"install" => {
Expand All @@ -104,8 +102,7 @@ fn main_impl(sysroot: &Path, local_repos: &[PathBuf]) -> Result<bool> {
return Ok(false);
}
let mut env = get_env(sysroot)?;
let rt = Runtime::new()?;
rt.block_on(install(names, &mut env, local_repos))?;
install(names, &mut env, local_repos).await?;
Ok(true)
}
"upgrade" => {
Expand Down Expand Up @@ -134,7 +131,7 @@ fn main_impl(sysroot: &Path, local_repos: &[PathBuf]) -> Result<bool> {
#[cfg(feature = "network")]
"remote-list" => {
let env = get_env(sysroot)?;
remote::list(&env)?;
remote::list(&env).await?;
Ok(true)
}
#[cfg(feature = "network")]
Expand Down Expand Up @@ -180,10 +177,11 @@ async fn main() {
let sysroot = env::var_os("SYSROOT")
.map(PathBuf::from)
.unwrap_or(PathBuf::from("/"));
let local_repos: Vec<PathBuf> = env::var("LOCAL_REPO") // TODO var_os
let local_repos = env::var("LOCAL_REPO") // TODO var_os
.map(|s| s.split(':').map(PathBuf::from).collect())
.unwrap_or_default();
match main_impl(&sysroot, &local_repos) {
let res = main_impl(&sysroot, local_repos).await;
match res {
Ok(false) => exit(1),
Err(e) => {
eprintln!("error: {e}");
Expand Down
4 changes: 2 additions & 2 deletions client/src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
use common::{repository::remote::Remote, Environment};

/// Lists remotes.
pub fn list(env: &Environment) -> std::io::Result<()> {
pub async fn list(env: &Environment) -> std::io::Result<()> {
let remotes = Remote::load_list(env)?;
println!("Remotes list:");
for remote in remotes {
let host = &remote.host;
match remote.fetch_motd() {
match remote.fetch_motd().await {
Ok(motd) => println!("- {host} (status: UP): {motd}"),
Err(_) => println!("- {host} (status: DOWN)"),
}
Expand Down
Loading

0 comments on commit e45e128

Please sign in to comment.