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
tags
package.specs
/pkg

37
Cargo.lock generated
View File

@ -56,17 +56,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bootstrap"
version = "0.1.0"
dependencies = [
"clap",
"clap_complete",
"clap_complete_nushell",
"clap_mangen",
"cli",
]
[[package]]
name = "bumpalo"
version = "3.12.0"
@ -551,11 +540,11 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
name = "hpk"
version = "0.1.0"
dependencies = [
"bootstrap",
"chrono",
"clap",
"cli",
"deku",
"package-bootstrap",
"rayon",
"reqwest",
"ron",
@ -923,6 +912,18 @@ version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "percent-encoding"
version = "2.2.0"
@ -959,9 +960,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.53"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
dependencies = [
"unicode-ident",
]
@ -1014,9 +1015,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.11.15"
version = "0.11.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949"
checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254"
dependencies = [
"base64 0.21.0",
"bytes",
@ -1161,9 +1162,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
dependencies = [
"itoa",
"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
[workspace]
members = [ "bootstrap", "cli", "tar" ]
members = [ "cli", "tar" ]
[[bin]]
name = "hpk"
@ -23,7 +23,6 @@ cli = { path = "cli" }
deku = "0.16"
[dependencies]
bootstrap = { path = "bootstrap" }
clap.workspace = true
cli.workspace = true
deku.workspace = true
@ -38,6 +37,10 @@ zstd = "0.12"
version = "0.4"
features = ["serde"]
[dependencies.package-bootstrap]
version = "0.1.0"
features = ["mangen"]
[dependencies.reqwest]
version = "0.11"
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 {
clap::{Arg, Command},
std::error::Error,
package_bootstrap::Bootstrap,
std::{error::Error, path::PathBuf},
};
fn main() -> Result<(), Box<dyn Error>> {
@ -20,12 +21,9 @@ fn main() -> Result<(), Box<dyn Error>> {
.num_args(1),
])
.get_matches();
let outdir = matches
.get_one::<String>("output")
.unwrap()
.to_string()
.into();
let outdir = matches.get_one::<String>("output").unwrap().to_string();
let outdir = PathBuf::from(&outdir);
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(())
}

View File

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

View File

@ -1,9 +1,11 @@
use std::io;
use {
clap::ArgMatches,
cli::cli,
hpk::{Dependency, Specs, Version},
hpk::{Creator, Dependency, Message, Specs, Version},
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>> {
@ -55,7 +57,19 @@ fn create(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
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(())
}

View File

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