Fix bugs in `Creator` so that it works now

This commit is contained in:
Nathan Fisher 2023-03-28 00:09:16 -04:00
parent 3b88759665
commit e1f7fbe4fe
9 changed files with 78 additions and 133 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/target /target
tags tags
package.specs package.specs
/pkg

37
Cargo.lock generated
View File

@ -56,17 +56,6 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bootstrap"
version = "0.1.0"
dependencies = [
"clap",
"clap_complete",
"clap_complete_nushell",
"clap_mangen",
"cli",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.12.0" version = "3.12.0"
@ -551,11 +540,11 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
name = "hpk" name = "hpk"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bootstrap",
"chrono", "chrono",
"clap", "clap",
"cli", "cli",
"deku", "deku",
"package-bootstrap",
"rayon", "rayon",
"reqwest", "reqwest",
"ron", "ron",
@ -923,6 +912,18 @@ version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
[[package]]
name = "package-bootstrap"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e99c0257afd97e84d5b56d8cfd9f3c551047119db7664652b544a1061622b2e9"
dependencies = [
"clap",
"clap_complete",
"clap_complete_nushell",
"clap_mangen",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.2.0" version = "2.2.0"
@ -959,9 +960,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.53" version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1014,9 +1015,9 @@ dependencies = [
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.15" version = "0.11.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949" checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254"
dependencies = [ dependencies = [
"base64 0.21.0", "base64 0.21.0",
"bytes", "bytes",
@ -1161,9 +1162,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.94" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",

View File

@ -7,7 +7,7 @@ license = "GPL-3.0-only"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace] [workspace]
members = [ "bootstrap", "cli", "tar" ] members = [ "cli", "tar" ]
[[bin]] [[bin]]
name = "hpk" name = "hpk"
@ -23,7 +23,6 @@ cli = { path = "cli" }
deku = "0.16" deku = "0.16"
[dependencies] [dependencies]
bootstrap = { path = "bootstrap" }
clap.workspace = true clap.workspace = true
cli.workspace = true cli.workspace = true
deku.workspace = true deku.workspace = true
@ -38,6 +37,10 @@ zstd = "0.12"
version = "0.4" version = "0.4"
features = ["serde"] features = ["serde"]
[dependencies.package-bootstrap]
version = "0.1.0"
features = ["mangen"]
[dependencies.reqwest] [dependencies.reqwest]
version = "0.11" version = "0.11"
features = ["blocking"] features = ["blocking"]

View File

@ -1,11 +0,0 @@
[package]
name = "bootstrap"
version = "0.1.0"
edition = "2021"
[dependencies]
cli.workspace = true
clap.workspace = true
clap_complete = "4.1"
clap_complete_nushell = "0.1"
clap_mangen = "0.2"

View File

@ -1,77 +0,0 @@
use {
clap_complete::{generate_to, shells},
clap_complete_nushell::Nushell,
std::{
error::Error,
fs,
ops::Deref,
path::{Path, PathBuf},
},
};
static PROGNAME: &str = "hpk";
fn gencomp(outdir: PathBuf, gen: &str) -> Result<(), Box<dyn Error>> {
let mut cmd = cli::cli();
let path = match gen {
"bash" => generate_to(shells::Bash, &mut cmd, PROGNAME, outdir)?,
"fish" => generate_to(shells::Fish, &mut cmd, PROGNAME, outdir)?,
"nu" => generate_to(Nushell, &mut cmd, PROGNAME, outdir)?,
"pwsh" => generate_to(shells::PowerShell, &mut cmd, PROGNAME, outdir)?,
"zsh" => generate_to(shells::Zsh, &mut cmd, PROGNAME, outdir)?,
_ => unimplemented!(),
};
println!(" {}", path.display());
Ok(())
}
fn completions<P: Deref<Target = Path>>(dir: P) -> Result<(), Box<dyn Error>> {
println!("Generating completions:");
["bash", "fish", "nu", "pwsh", "zsh"]
.iter()
.try_for_each(|gen| {
let mut outdir = dir.to_path_buf();
let base = match *gen {
"bash" => ["share", "bash-completion", "completions"],
"zsh" => ["share", "zsh", "site-functions"],
"nu" => ["share", "nu", "completions"],
"pwsh" => ["share", "pwsh", "completions"],
"fish" => ["share", "fish", "completions"],
_ => unimplemented!(),
};
base.iter().for_each(|d| outdir.push(d));
if !outdir.exists() {
fs::create_dir_all(&outdir)?;
}
gencomp(outdir, gen)
})?;
Ok(())
}
fn copy_bin<P: Deref<Target = Path>>(dir: P, arch: Option<String>) -> Result<(), Box<dyn Error>> {
println!("Copying binary:");
let mut bindir = dir.to_path_buf();
bindir.push("bin");
if !bindir.exists() {
fs::create_dir_all(&bindir)?;
}
let mut outfile = bindir;
outfile.push("hpk");
let infile: PathBuf = if let Some(arch) = arch {
["target", &arch, "release", PROGNAME].iter().collect()
} else {
["target", "release", PROGNAME].iter().collect()
};
if !infile.exists() {
eprintln!("Error: you must run \"cargo build --release\" first");
}
fs::copy(&infile, &outfile)?;
println!(" {} -> {}", infile.display(), outfile.display());
Ok(())
}
pub fn install(dir: PathBuf, arch: Option<String>) -> Result<(), Box<dyn Error>> {
copy_bin(dir.as_path(), arch)?;
completions(dir.as_path())?;
Ok(())
}

View File

@ -1,6 +1,7 @@
use { use {
clap::{Arg, Command}, clap::{Arg, Command},
std::error::Error, package_bootstrap::Bootstrap,
std::{error::Error, path::PathBuf},
}; };
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
@ -20,12 +21,9 @@ fn main() -> Result<(), Box<dyn Error>> {
.num_args(1), .num_args(1),
]) ])
.get_matches(); .get_matches();
let outdir = matches let outdir = matches.get_one::<String>("output").unwrap().to_string();
.get_one::<String>("output") let outdir = PathBuf::from(&outdir);
.unwrap()
.to_string()
.into();
let arch = matches.get_one::<String>("arch").map(|x| x.to_string()); let arch = matches.get_one::<String>("arch").map(|x| x.to_string());
bootstrap::install(outdir, arch)?; Bootstrap::new("hpk", cli::cli()).install(&outdir, arch, 1)?;
Ok(()) Ok(())
} }

View File

@ -1,3 +1,5 @@
use std::{fs, path::PathBuf};
use { use {
crate::{Entry, Item, Package, Plist, Specs}, crate::{Entry, Item, Package, Plist, Specs},
rayon::prelude::{IntoParallelRefIterator, ParallelIterator}, rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
@ -10,7 +12,7 @@ use {
path::Path, path::Path,
sync::{ sync::{
atomic::{AtomicUsize, Ordering}, atomic::{AtomicUsize, Ordering},
mpsc::{self, Receiver, Sender}, mpsc::Sender,
Mutex, Mutex,
}, },
}, },
@ -19,47 +21,55 @@ use {
}; };
pub enum Message { pub enum Message {
MemberAdded(String),
Success(String), Success(String),
Failure(String), Failure(String),
} }
pub struct Creator { pub struct Creator {
path: PathBuf,
entries: Vec<Result<DirEntry, walkdir::Error>>, entries: Vec<Result<DirEntry, walkdir::Error>>,
specs: Specs, specs: Specs,
sender: Sender<Message>,
receiver: Receiver<Message>,
} }
impl Creator { impl Creator {
pub fn new(path: &Path, specs: Specs) -> Result<Self, io::Error> { pub fn new(path: &Path, specs: Specs) -> Result<Self, io::Error> {
let d = env::current_dir()?;
env::set_current_dir(path)?; env::set_current_dir(path)?;
let path = path.to_path_buf();
let entries = WalkDir::new(".").into_iter().collect::<Vec<_>>(); let entries = WalkDir::new(".").into_iter().collect::<Vec<_>>();
let (sender, receiver) = mpsc::channel(); env::set_current_dir(d)?;
Ok(Self { Ok(Self {
path,
entries, entries,
specs, specs,
sender,
receiver,
}) })
} }
pub fn create(self, outdir: &Path) -> Result<(), Box<dyn Error>> { pub fn create(self, outdir: &Path, sender: Sender<Message>) -> Result<(), Box<dyn Error>> {
let d = env::current_dir()?;
let plist = Mutex::new(Plist::default()); let plist = Mutex::new(Plist::default());
let totalsize: AtomicUsize = 0.into(); let totalsize: AtomicUsize = 0.into();
let fullname = format!( let fullname = format!(
"{}-{}_{}", "{}-{}_{}",
&self.specs.name, self.specs.version, self.specs.release &self.specs.name, self.specs.version, self.specs.release
); );
let mut archive = outdir.to_path_buf(); if !outdir.exists() {
fs::create_dir_all(&outdir)?;
}
let outdir = outdir.canonicalize()?;
let mut archive = outdir.clone();
archive.push(&fullname); archive.push(&fullname);
archive.set_extension("tar.zst"); archive.set_extension("tar.zst");
let fd = File::create(&archive)?; let fd = File::create(&archive)?;
let writer = Mutex::new(Encoder::new(fd, 0)?); let writer = Mutex::new(Encoder::new(fd, 0)?);
let sender = Mutex::new(self.sender.clone()); let sender = Mutex::new(sender);
env::set_current_dir(&self.path)?;
self.entries self.entries
.par_iter() .par_iter()
.filter(|x| x.is_ok()) .filter(|x| x.is_ok())
.map(|x| x.as_ref().unwrap()) .map(|x| x.as_ref().unwrap())
.filter(|x| x.path() != Path::new("."))
.for_each(|x| { .for_each(|x| {
let sender = sender.lock().unwrap().clone(); let sender = sender.lock().unwrap().clone();
if let Ok(item) = Item::try_create(x.path().to_path_buf().as_path()) { if let Ok(item) = Item::try_create(x.path().to_path_buf().as_path()) {
@ -85,7 +95,7 @@ impl Creator {
plist.lock().unwrap().borrow_mut().entries.push(item.entry); plist.lock().unwrap().borrow_mut().entries.push(item.entry);
match writer.lock().unwrap().borrow_mut().write_all(&item.data) { match writer.lock().unwrap().borrow_mut().write_all(&item.data) {
Ok(_) => sender Ok(_) => sender
.send(Message::Success(format!( .send(Message::MemberAdded(format!(
"{} added to archive", "{} added to archive",
path.display() path.display()
))) )))
@ -96,18 +106,24 @@ impl Creator {
} }
} else { } else {
sender sender
.send(Message::Failure("Could not process DirEntry".to_string())) .send(Message::Failure(format!(
"Could not process DirEntry for {}",
x.path().display()
)))
.expect("could not send message"); .expect("could not send message");
} }
}); });
let mut package: Package = self.specs.into(); let mut package: Package = self.specs.into();
package.size = totalsize.into_inner(); package.size = totalsize.into_inner();
let node = package.save_ron_and_create_tar_node(outdir)?; let plist = plist.into_inner()?;
package.plist = plist;
let node = package.save_ron_and_create_tar_node(&outdir)?;
let mut writer = writer.into_inner()?; let mut writer = writer.into_inner()?;
writer.write_all(&node.to_vec()?)?; writer.write_all(&node.to_vec()?)?;
let _fd = writer.finish()?; let _fd = writer.finish()?;
self.sender let sender = sender.into_inner()?;
.send(Message::Success(format!("{} saved", archive.display())))?; sender.send(Message::Success(format!("{} saved", archive.display())))?;
env::set_current_dir(d)?;
Ok(()) Ok(())
} }
} }

View File

@ -1,9 +1,11 @@
use std::io;
use { use {
clap::ArgMatches, clap::ArgMatches,
cli::cli, cli::cli,
hpk::{Dependency, Specs, Version}, hpk::{Creator, Dependency, Message, Specs, Version},
ron::ser::{to_writer_pretty, PrettyConfig}, ron::ser::{to_writer_pretty, PrettyConfig},
std::{env, error::Error, fs::File, io::BufWriter, path::PathBuf}, std::{env, error::Error, fs::File, io::BufWriter, path::PathBuf, sync::mpsc},
}; };
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
@ -55,7 +57,19 @@ fn create(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
specs.dependencies.push(d); specs.dependencies.push(d);
} }
} }
hpk::create_package(&dir, specs, &outdir)?; let creator = Creator::new(&dir, specs)?;
let (sender, receiver) = mpsc::channel();
creator.create(&outdir, sender)?;
for msg in receiver.iter() {
match msg {
Message::MemberAdded(_s) => {}
Message::Success(s) => println!("{s}"),
Message::Failure(s) => {
eprint!("{s}");
return Err(io::Error::new(io::ErrorKind::Other, s).into());
}
}
}
Ok(()) Ok(())
} }

View File

@ -9,7 +9,7 @@ mod repository;
mod version; mod version;
pub use { pub use {
creator::Creator, creator::{Creator, Message},
db::Database, db::Database,
hooks::Hooks, hooks::Hooks,
item::Item, item::Item,