Skip to content

Commit

Permalink
Rejigger everything to have a conversion module, refactoring time
Browse files Browse the repository at this point in the history
Signed-off-by: Ikey Doherty <[email protected]>
  • Loading branch information
ikeycode committed Nov 1, 2023
1 parent 6ac8fb3 commit fb0ceec
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 70 deletions.
88 changes: 88 additions & 0 deletions src/converter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-FileCopyrightText: Copyright © 2020-2023 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0

//! Convert input package to a yaml file

use std::{path::PathBuf, vec};

use thiserror::Error;
use url::Url;

use crate::eopkg::index::Package;

pub struct HashedPackage {
/// Finalised hash
pub hash: [u8; 32],

/// Actual package itself
pub package: Package,
}

/// For the given input packages, yield a functioning
/// boulder recipe as a string
pub fn convert(input: Vec<HashedPackage>, base_uri: Url) -> Result<String, Error> {
let mut upstreams = vec![];
for pkg in input.iter() {
let uri = base_uri.join(&pkg.package.package_uri)?.to_string();
upstreams.push(format!(
" - {}:\n unpack: false\n hash: {}",
uri,
const_hex::encode(pkg.hash)
));
}

let sample = &input.first().ok_or(Error::NoPackage)?;
let homepage = sample
.package
.source
.homepage
.clone()
.unwrap_or("no-homepage-set".into());
let licenses = sample.package.licenses.iter().map(|l| format!(" - {l}"));
let yml = vec![
format!("name: {}", sample.package.source.name),
format!("version: {}", sample.package.history.updates[0].version),
format!("release: {}", sample.package.history.updates[0].release),
format!("homepage: {}", homepage),
"upstreams:".into(),
upstreams.join("\n"),
format!("summary: {}", sample.package.summary),
format!("description: {}", sample.package.description),
"strip: false".into(),
"license: ".into(),
licenses.collect::<Vec<String>>().join("\n"),
"install: |".into(),
generate_install_script(&input, &base_uri)?,
];

Ok(yml.join("\n"))
}

fn generate_install_script(input: &[HashedPackage], base_uri: &Url) -> Result<String, Error> {
let mut zips = vec![];
for pkg in input.iter() {
let url = base_uri.join(&pkg.package.package_uri)?;
let path = PathBuf::from(url.path());
let name = path.file_name().ok_or(Error::Path)?.to_string_lossy();
zips.push(format!(" unzip -o %(sourcedir)/{name}"));
zips.push(" tar xf install.tar.xz -C %(installroot)".to_string());
}

Ok(format!(
" %install_dir %(installroot)\n{}",
zips.join("\n")
))
}

#[derive(Debug, Error)]
pub enum Error {
#[error("path issue")]
Path,

#[error("no package")]
NoPackage,

#[error("url: {0}")]
Url(#[from] url::ParseError),
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
//
// SPDX-License-Identifier: MPL-2.0

pub mod converter;
pub mod eopkg;
88 changes: 18 additions & 70 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
//
// SPDX-License-Identifier: MPL-2.0

use std::{collections::BTreeSet, ffi::OsStr, fs::File, io::Cursor, path::PathBuf, time::Duration};

use a_piece_of_pisi::eopkg::{
self,
index::{Index, Package},
use std::{collections::BTreeSet, fs::File, io::Cursor, time::Duration};

use a_piece_of_pisi::{
converter::{convert, HashedPackage},
eopkg::{
self,
index::{Index, Package},
},
};
use crossterm::style::Stylize;
use indicatif::{style::TemplateError, MultiProgress, ProgressBar, ProgressStyle};
Expand Down Expand Up @@ -39,14 +42,8 @@ pub enum Error {
Template(#[from] TemplateError),
}

#[derive(Default)]
struct FetchedPackage {
package: Package,
hash: String,
}

/// Asynchronously fetch a package (TODO: Stop hardcoding the origin URI base!)
async fn fetch(multi: &MultiProgress, p: &Package) -> Result<FetchedPackage, Error> {
async fn fetch(multi: &MultiProgress, p: &Package) -> Result<HashedPackage, Error> {
let full_url = format!("https://packages.getsol.us/unstable/{}", &p.package_uri);
let uri = Url::parse(&full_url)?;
let path = uri
Expand Down Expand Up @@ -79,9 +76,9 @@ async fn fetch(multi: &MultiProgress, p: &Package) -> Result<FetchedPackage, Err
let hash = hasher.finalize();

pbar.println(format!("{} {}", "Fetched".green(), path.clone().bold()));
Ok(FetchedPackage {
Ok(HashedPackage {
package: p.clone(),
hash: const_hex::encode(hash),
hash: hash.into(),
})
}

Expand Down Expand Up @@ -110,24 +107,6 @@ async fn parse_index() -> Result<Index, Error> {
Ok(doc)
}

fn generate_install_script<'a, T: IntoIterator<Item = &'a FetchedPackage>>(pkgs: T) -> String {
let pkgs = pkgs.into_iter();
let script = " %install_dir %(installroot)";
let zips = pkgs
.map(|p| {
let path = PathBuf::from(&p.package.package_uri);
format!(
" unzip -o %(sourcedir)/{}\n tar xf install.tar.xz -C %(installroot)",
path.file_name()
.unwrap_or(OsStr::new("no-exist.eopkg"))
.to_string_lossy()
)
})
.collect::<Vec<_>>()
.join("\n");
format!("{}\n{}", script, zips)
}

#[tokio::main]
async fn main() -> Result<()> {
color_eyre::install()?;
Expand All @@ -143,52 +122,21 @@ async fn main() -> Result<()> {
.collect::<BTreeSet<String>>();
eprintln!("Unique source IDs: {}", names.len());

let results: Vec<FetchedPackage> = stream::iter(
let results: Vec<HashedPackage> = stream::iter(
index
.packages
.iter()
.take(300)
.filter(|p| p.source.name == "nano")
.map(|f| async { fetch(&multi, f).await }),
)
.buffer_unordered(16)
.try_collect()
.await?;
let sample = results.first().unwrap();
let upstreams = results.iter().map(|p| {
format!(
" - https://packages.getsol.us/unstable/{}:\n unpack: false\n hash: {}",
p.package.package_uri, p.hash
)
});
let homepage = sample
.package
.source
.homepage
.clone()
.unwrap_or("no-homepage-set".to_string());
let mut yml = vec![
format!("name: {}", sample.package.source.name),
format!("version: {}", sample.package.history.updates[0].version),
format!("release: {}", sample.package.history.updates[0].release),
format!("summary: {}", sample.package.summary),
format!("description: {}", sample.package.description),
format!("homepage: {}", homepage),
"strip: false".to_string(),
"license: ".to_string(),
];
yml.extend(
sample
.package
.licenses
.iter()
.map(|l| format!(" - {}", l)),

println!("YML:\n\n");
println!(
"{}",
convert(results, Url::parse("https://packages.getsol.us/unstable")?)?
);
yml.push("upstreams:".to_string());
yml.extend(upstreams);
let steps = vec!["install: |".to_string(), generate_install_script(&results)];
yml.extend(steps);
for i in yml {
println!("{}", i);
}
Ok(())
}

0 comments on commit fb0ceec

Please sign in to comment.