Library is almost working but install_package no worky :c
This commit is contained in:
parent
ba36e3b7fc
commit
af2897efb1
4 changed files with 27323 additions and 34 deletions
|
@ -15,7 +15,9 @@ path = "src/lib/lib.rs"
|
|||
base64 = "0.22.1"
|
||||
bytes = "1.10.1"
|
||||
flate2 = "1.1.0"
|
||||
gpgme = { version = "0.11.0", features = ["v1_18"] }
|
||||
reqwest = { version = "0.12.12", features = ["blocking"] }
|
||||
ruzstd = "0.8.0"
|
||||
sha256 = "1.6.0"
|
||||
tar = "0.4.44"
|
||||
time = { version = "0.3.39", features = ["formatting"] }
|
||||
|
|
26958
src/lib/archlinux.gpg
Normal file
26958
src/lib/archlinux.gpg
Normal file
File diff suppressed because it is too large
Load diff
379
src/lib/lib.rs
379
src/lib/lib.rs
|
@ -5,6 +5,7 @@
|
|||
clippy::empty_docs,
|
||||
clippy::missing_panics_doc
|
||||
)]
|
||||
#![feature(str_as_str)]
|
||||
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
|
@ -14,6 +15,7 @@ use std::{
|
|||
|
||||
use base64::Engine;
|
||||
use bytes::Buf;
|
||||
use gpgme::SignatureSummary;
|
||||
|
||||
/// A descriptor of a repository.
|
||||
#[derive(Clone, Default, Debug)]
|
||||
|
@ -23,7 +25,7 @@ pub struct RepoDescriptor {
|
|||
/// The architecture to use.
|
||||
arch: String,
|
||||
/// The hash of the (repo).db file.
|
||||
hash: Option<Vec<u8>>
|
||||
hash: Option<String>,
|
||||
}
|
||||
|
||||
impl RepoDescriptor {
|
||||
|
@ -54,20 +56,21 @@ impl RepoDescriptor {
|
|||
}
|
||||
|
||||
/// The hash of the (repo).db file.
|
||||
pub fn hash(&self) -> Option<Vec<u8>> {
|
||||
pub fn hash(&self) -> Option<String> {
|
||||
self.hash.clone()
|
||||
}
|
||||
/// Sets [`hash`].
|
||||
/// [`hash`]: [RepoDescriptor::hash]
|
||||
pub fn set_hash(&mut self, hash: Option<Vec<u8>>) -> &mut Self {
|
||||
pub fn set_hash(&mut self, hash: Option<String>) -> &mut Self {
|
||||
self.hash = hash;
|
||||
self
|
||||
}
|
||||
|
||||
/// Formats the repo descriptor into a string.
|
||||
#[allow(clippy::missing_panics_doc)] // function won't ever actually panic
|
||||
pub fn format(&self) -> String {
|
||||
if self.hash().is_some() {
|
||||
format!("{:x?}-{}-{}", self.hash().unwrap(), self.repo(), self.arch())
|
||||
format!("{}-{}-{}", self.hash().unwrap(), self.repo(), self.arch())
|
||||
} else {
|
||||
format!("{}-{}", self.repo(), self.arch())
|
||||
}
|
||||
|
@ -120,6 +123,7 @@ impl Package {
|
|||
}
|
||||
|
||||
/// A mirror to use.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Mirror(url::Url);
|
||||
|
||||
impl Mirror {
|
||||
|
@ -187,16 +191,32 @@ pub fn get_current_user() -> OsString {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the base dir for pacwoman. Use this instead of hard-coding /pacwoman for the case
|
||||
/// of debugging in a different directory.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! If you need it to, use [base_dir]!
|
||||
pub fn get_base_dir() -> PathBuf {
|
||||
PathBuf::from("/home/arthur/pacwoman/debug")
|
||||
}
|
||||
|
||||
/// Same as [get_base_dir]; however, this function will create the directory if it doesn't
|
||||
/// exist. If [std::fs::create_dir_all] returns an error, it will be propagated.
|
||||
pub fn base_dir() -> std::io::Result<PathBuf> {
|
||||
let dir = get_base_dir();
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Get the config directory. If for the entire system, then it will be /pacwoman/config, otherwise
|
||||
/// it will be /pacwomand/user/{user name from [get_current_user]}/config.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! If you need it to, use [config_directory]!
|
||||
pub fn get_config_directory(system: bool) -> PathBuf {
|
||||
if system {
|
||||
PathBuf::from("/pacwoman/config")
|
||||
get_base_dir().join("config")
|
||||
} else {
|
||||
PathBuf::from(format!(
|
||||
"/pacwoman/user/{}/config",
|
||||
get_base_dir().join(format!(
|
||||
"user/{}/config",
|
||||
get_current_user().to_string_lossy()
|
||||
))
|
||||
}
|
||||
|
@ -211,15 +231,15 @@ pub fn config_directory(system: bool) -> std::io::Result<PathBuf> {
|
|||
}
|
||||
|
||||
/// Get the store directory. If for the entire system, then it will be /pacwoman/store, otherwise
|
||||
/// it will be /pacwomand/user/{user name from [get_current_user]}/store.
|
||||
/// it will be /pacwoman/user/{user name from [get_current_user]}/store.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! If you need it to, use [store_directory]!
|
||||
pub fn get_store_directory(system: bool) -> PathBuf {
|
||||
if system {
|
||||
PathBuf::from("/home/arthur/pacwoman/store")
|
||||
get_base_dir().join("store")
|
||||
} else {
|
||||
PathBuf::from(format!(
|
||||
"/home/arthur/pacwoman/user/{}/store",
|
||||
get_base_dir().join(format!(
|
||||
"user/{}/store",
|
||||
get_current_user().to_string_lossy()
|
||||
))
|
||||
}
|
||||
|
@ -234,6 +254,8 @@ pub fn store_directory(system: bool) -> std::io::Result<PathBuf> {
|
|||
}
|
||||
|
||||
/// Gets the store directory for a repo.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! See [repo_store_directory] if you need it too.
|
||||
pub fn get_repo_store_directory(system: bool, repo: RepoDescriptor) -> PathBuf {
|
||||
get_store_directory(system).join(repo.format())
|
||||
}
|
||||
|
@ -251,7 +273,7 @@ pub fn repo_store_directory(system: bool, repo: RepoDescriptor) -> std::io::Resu
|
|||
///
|
||||
/// This directory is not guaranteed to exist! If you need it to, use [index_directory]!
|
||||
pub fn get_index_directory() -> PathBuf {
|
||||
PathBuf::from("/home/arthur/pacwoman/index")
|
||||
get_base_dir().join("index")
|
||||
}
|
||||
|
||||
/// Same as [get_index_directory]; however, this function will create the directory if it doesn't
|
||||
|
@ -278,6 +300,41 @@ pub fn repo_index_dir(repo: RepoDescriptor) -> std::io::Result<PathBuf> {
|
|||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Directory for storing GPG keys and other miscellaneous GPG stuff.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! See [gpg_dir] if you need it too.
|
||||
pub fn get_gpg_dir() -> PathBuf {
|
||||
get_base_dir().join("keys")
|
||||
}
|
||||
|
||||
/// Same as [get_gpg_dir], except it will create the directory if it doesn't exist.
|
||||
/// If [std::fs::create_dir_all] returns an error, it will be propagated.
|
||||
pub fn gpg_dir() -> std::io::Result<PathBuf> {
|
||||
let dir = get_gpg_dir();
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Directory for storing binaries. Equivalent to the root directory. Contains directories such
|
||||
/// as etc, usr, var, and others.
|
||||
///
|
||||
/// This directory is not guaranteed to exist! See [bin_dir] if you need it too.
|
||||
pub fn get_bin_dir(system: bool) -> PathBuf {
|
||||
if system {
|
||||
get_base_dir().join("bin")
|
||||
} else {
|
||||
get_base_dir().join(format!("user/{}/bin", get_current_user().to_string_lossy()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as [get_bin_dir], except it will create the directory if it doesn't exist.
|
||||
/// If [std::fs::create_dir_all] returns an error, it will be propagated.
|
||||
pub fn bin_dir(system: bool) -> std::io::Result<PathBuf> {
|
||||
let dir = get_bin_dir(system);
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Populates the index with information for a certain repo from a certain mirror. Will
|
||||
/// overwrite any symlink for the repo.
|
||||
///
|
||||
|
@ -415,7 +472,7 @@ pub fn populate_index(mirror: Mirror, repo: RepoDescriptor) -> std::io::Result<P
|
|||
|
||||
/// Get a list of hashes provided by the repo.
|
||||
#[allow(clippy::missing_panics_doc)] // Shouldn't ever panic, but could be wrong.
|
||||
pub fn read_repos(repo: RepoDescriptor) -> std::io::Result<Vec<PathBuf>> {
|
||||
pub fn read_repos(repo: RepoDescriptor) -> std::io::Result<Vec<(PathBuf, String)>> {
|
||||
let mut repos = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.open(index_directory()?.join("REPOS"))?;
|
||||
|
@ -433,9 +490,9 @@ pub fn read_repos(repo: RepoDescriptor) -> std::io::Result<Vec<PathBuf>> {
|
|||
for hash in line.split_once(": ").unwrap().1.split(" ") {
|
||||
strings.push(hash.to_owned() + &repo.format());
|
||||
}
|
||||
let mut out: Vec<PathBuf> = vec![];
|
||||
let mut out: Vec<(PathBuf, String)> = vec![];
|
||||
for ele in strings {
|
||||
out.push(index_directory()?.join(PathBuf::from(ele)));
|
||||
out.push((index_directory()?.join(PathBuf::from(&ele)), ele));
|
||||
}
|
||||
return Ok(out);
|
||||
}
|
||||
|
@ -478,6 +535,9 @@ pub fn locate_package(
|
|||
let repo = prefix
|
||||
.strip_suffix(&("-".to_string() + &arch))
|
||||
.unwrap()
|
||||
.split_once("-")
|
||||
.unwrap()
|
||||
.1
|
||||
.to_string();
|
||||
|
||||
let descriptor = RepoDescriptor::new()
|
||||
|
@ -542,10 +602,10 @@ pub struct PackageDesc {
|
|||
/// MD5 checksum of the package. Recommended not to use and to instead use [`sha256sum`].
|
||||
/// Stored as hex in the desc file.
|
||||
/// [`sha256sum`]: [PackageDesc::sha256sum]
|
||||
pub md5sum: Vec<u8>,
|
||||
pub md5sum: String,
|
||||
/// SHA256 checksum of the package.
|
||||
/// Stored as hex in the desc file.
|
||||
pub sha256sum: Vec<u8>,
|
||||
pub sha256sum: String,
|
||||
/// PGP signature of the package.
|
||||
/// Stored as base64 in the desc file.
|
||||
pub pgpsig: Vec<u8>,
|
||||
|
@ -640,12 +700,12 @@ pub fn read_desc(package: String, repo: RepoDescriptor) -> std::io::Result<Packa
|
|||
|
||||
if let Some(loc) = desc_data.iter().position(|item| (*item) == "%MD5SUM%") {
|
||||
let loc = loc + 1; // value is on next line
|
||||
out.md5sum = desc_data[loc].as_bytes().to_vec();
|
||||
out.md5sum = desc_data[loc].to_string();
|
||||
}
|
||||
|
||||
if let Some(loc) = desc_data.iter().position(|item| (*item) == "%SHA256SUM%") {
|
||||
let loc = loc + 1; // value is on next line
|
||||
out.sha256sum = desc_data[loc].as_bytes().to_vec();
|
||||
out.sha256sum = desc_data[loc].to_string();
|
||||
}
|
||||
|
||||
if let Some(loc) = desc_data.iter().position(|item| (*item) == "%PGPSIG%") {
|
||||
|
@ -789,19 +849,56 @@ pub fn read_desc(package: String, repo: RepoDescriptor) -> std::io::Result<Packa
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the [gpgme] context and sets the appropriate properties.
|
||||
pub fn get_gpg_ctx() -> std::io::Result<gpgme::Context> {
|
||||
let mut gpg_ctx = gpgme::Context::from_protocol(gpgme::Protocol::OpenPgp)?;
|
||||
gpg_ctx.set_engine_home_dir(gpg_dir()?.to_string_lossy().into_owned())?;
|
||||
Ok(gpg_ctx)
|
||||
}
|
||||
|
||||
/// The PGP public key file for arch linux signing keys.
|
||||
const ARCHLINUX_PGP_PUBLIC_KEY: &[u8] = include_bytes!("archlinux.gpg");
|
||||
|
||||
/// Initalizes the GPG keyring and other GPG stuff.
|
||||
pub fn init_gpg() -> std::io::Result<()> {
|
||||
let mut gpg_ctx = get_gpg_ctx()?;
|
||||
|
||||
print!("Generating master key...");
|
||||
gpg_ctx.generate_key::<Vec<u8>, Vec<u8>>(
|
||||
r#"<GnupgKeyParms format="internal">
|
||||
Key-Type: RSA
|
||||
Key-Length: 4096
|
||||
Key-Usage: sign
|
||||
Name-Real: Pacwoman Keyring Master Key
|
||||
Name-Email: pacwoman@localhost
|
||||
Expire-Date: 0
|
||||
%no-protection
|
||||
</GnupgKeyParms>"#,
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
println!(" Done.");
|
||||
|
||||
gpg_ctx.import(ARCHLINUX_PGP_PUBLIC_KEY)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Downloads, verifies, and unpacks a package from the provided mirror. The package value
|
||||
/// provided should be the file name provided in a [PackageDesc].
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if there are any errors with downloading because right now I don't feel like
|
||||
/// implementing it to fail gently.
|
||||
pub fn receive_package(
|
||||
mirror: Mirror,
|
||||
repo: RepoDescriptor,
|
||||
package: String,
|
||||
system: bool,
|
||||
) -> std::io::Result<PathBuf> {
|
||||
if repo.hash().is_none() {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "need hash in repo descriptor"));
|
||||
}
|
||||
|
||||
let path = index_directory()?
|
||||
.join(repo.format())
|
||||
.join(package)
|
||||
.join(&package)
|
||||
.join("desc");
|
||||
|
||||
let mut desc = std::fs::OpenOptions::new().read(true).open(path)?;
|
||||
|
@ -814,25 +911,245 @@ pub fn receive_package(
|
|||
|
||||
let desc_hash = sha256::digest(desc_data);
|
||||
|
||||
let desc = read_desc(package, repo)?;
|
||||
let desc = read_desc(package.clone(), repo.clone())?;
|
||||
|
||||
let url = mirror.substitute(&repo.repo(), &repo.arch(), &desc.filename);
|
||||
let sig_url = mirror.substitute(
|
||||
&repo.clone().repo(),
|
||||
&repo.arch(),
|
||||
&(desc.filename.clone() + ".sig"),
|
||||
);
|
||||
|
||||
let url = mirror.substitute(&repo.repo(), &repo.arch(), &desc.filename.clone());
|
||||
|
||||
let dir = repo_store_directory(system, repo)?.join(format!("{}-{}", desc_hash, package));
|
||||
|
||||
if std::fs::exists(index_directory()?.join("RECIEVED"))? {
|
||||
let mut packages = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.open(index_directory()?.join("RECIEVED"))?;
|
||||
|
||||
let mut packages_data = String::new();
|
||||
|
||||
packages.read_to_string(&mut packages_data)?;
|
||||
|
||||
drop(packages);
|
||||
|
||||
let packages: Vec<&str> = packages_data.split("\n").collect();
|
||||
|
||||
if packages.contains(&format!("{}-{}", desc_hash, package).as_str()) {
|
||||
return Ok(dir);
|
||||
}
|
||||
}
|
||||
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
|
||||
let sig_data = reqwest::blocking::get(sig_url)
|
||||
.unwrap()
|
||||
.bytes()
|
||||
.unwrap()
|
||||
.to_vec();
|
||||
|
||||
let package_data = reqwest::blocking::get(url)
|
||||
.unwrap()
|
||||
.bytes()
|
||||
.unwrap()
|
||||
.to_vec();
|
||||
|
||||
let mut gpg_ctx = get_gpg_ctx()?;
|
||||
let res = gpg_ctx
|
||||
.verify_detached(&sig_data, &package_data)?
|
||||
.signatures()
|
||||
.next()
|
||||
.unwrap()
|
||||
.summary();
|
||||
|
||||
match res {
|
||||
SignatureSummary::VALID | SignatureSummary::GREEN => {}
|
||||
sum => {
|
||||
if !sum.is_empty() {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
format!("signature invalid, error {:#?}", sum),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sum = sha256::digest(&package_data);
|
||||
|
||||
if desc.sha256sum != sum {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"SHA256 checksum does not match provided sum in desc, try updating the index or try receiving the package again",
|
||||
));
|
||||
}
|
||||
|
||||
let mut reader = package_data.reader();
|
||||
|
||||
let tar = ruzstd::decoding::StreamingDecoder::new(&mut reader).unwrap();
|
||||
let mut archive = tar::Archive::new(tar);
|
||||
archive.unpack(&dir)?;
|
||||
|
||||
let mut packages = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.truncate(false)
|
||||
.open(index_directory()?.join("RECIEVED"))?;
|
||||
|
||||
packages.write_fmt(format_args!("{}-{}\n", desc_hash, package))?;
|
||||
drop(packages);
|
||||
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Recieves a package and all of it's dependencies. Returns a list of paths to each package.
|
||||
pub fn recieve_package_and_dependencies(
|
||||
mirror: Mirror,
|
||||
repo: RepoDescriptor,
|
||||
package: String,
|
||||
system: bool,
|
||||
) -> std::io::Result<Vec<PathBuf>> {
|
||||
let mut out: Vec<PathBuf> = vec![];
|
||||
out.push(receive_package(
|
||||
mirror.clone(),
|
||||
repo.clone(),
|
||||
package.clone(),
|
||||
system,
|
||||
)?);
|
||||
|
||||
let path = index_directory()?
|
||||
.join(repo.clone().format())
|
||||
.join(&package)
|
||||
.join("desc");
|
||||
|
||||
let mut desc = std::fs::OpenOptions::new().read(true).open(path)?;
|
||||
|
||||
let mut desc_data = String::new();
|
||||
|
||||
desc.read_to_string(&mut desc_data)?;
|
||||
|
||||
drop(desc);
|
||||
|
||||
let desc = read_desc(package.clone(), repo.clone())?;
|
||||
|
||||
for package in desc.depends {
|
||||
println!("{}", package);
|
||||
out.push(receive_package(
|
||||
mirror.clone(),
|
||||
repo.clone(),
|
||||
locate_package(package)?[0].0.clone(),
|
||||
system,
|
||||
)?);
|
||||
}
|
||||
println!("recieved all dependencies");
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Recieves a package and it's dependencies and installs it.
|
||||
#[allow(clippy::missing_panics_doc)] // won't ever actually panic
|
||||
pub fn install_package(
|
||||
mirror: Mirror,
|
||||
repo: RepoDescriptor,
|
||||
package: String,
|
||||
system: bool,
|
||||
) -> std::io::Result<()> {
|
||||
let out = bin_dir(system)?;
|
||||
for path in recieve_package_and_dependencies(mirror, repo, package, system)? {
|
||||
println!("{}", path.to_string_lossy());
|
||||
println!("{}", out.to_string_lossy());
|
||||
|
||||
if std::fs::exists(index_directory()?.join("INSTALLED"))? {
|
||||
let mut packages = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.open(index_directory()?.join("INSTALLED"))?;
|
||||
|
||||
let mut packages_data = String::new();
|
||||
|
||||
packages.read_to_string(&mut packages_data)?;
|
||||
|
||||
drop(packages);
|
||||
|
||||
let packages: Vec<&str> = packages_data.split("\n").collect();
|
||||
|
||||
if packages.contains(&(path.file_name().unwrap().to_string_lossy().as_str())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for entry in std::fs::read_dir(&path)? {
|
||||
println!("entry");
|
||||
let entry = entry?;
|
||||
|
||||
if entry.file_name() == *".BUILDINFO"
|
||||
|| entry.file_name() == *".MTREE"
|
||||
|| entry.file_name() == *".PKGINFO"
|
||||
{
|
||||
continue;
|
||||
}
|
||||
println!("{}", entry.file_name().to_string_lossy());
|
||||
|
||||
if entry.file_type()?.is_dir() {
|
||||
std::fs::create_dir_all(out.join(entry.path()))?;
|
||||
} else {
|
||||
std::fs::create_dir_all(out.join(entry.path().parent().unwrap()))?;
|
||||
std::fs::remove_file(out.join(entry.path()))?;
|
||||
std::os::unix::fs::symlink(path.join(entry.path()), out.join(entry.path()))?;
|
||||
}
|
||||
}
|
||||
|
||||
std::os::unix::fs::chroot(&out)?;
|
||||
|
||||
if !std::process::Command::new("/usr/bin/bash")
|
||||
.arg("-c")
|
||||
.arg("source /.INSTALL && post_install && post_upgrade")
|
||||
.current_dir(&out)
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.success()
|
||||
{
|
||||
println!(
|
||||
"[WARN] .INSTALL script for package {} failed!",
|
||||
path.file_name().unwrap().to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
||||
std::os::unix::fs::chroot(".")?;
|
||||
|
||||
std::fs::remove_file(out.join(".INSTALL"))?;
|
||||
|
||||
let mut packages = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.truncate(false)
|
||||
.open(index_directory()?.join("INSTALLED"))?;
|
||||
|
||||
packages.write_fmt(format_args!(
|
||||
"{}\n",
|
||||
path.file_name().unwrap().to_string_lossy()
|
||||
))?;
|
||||
drop(packages);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates all of the necessary directories, for the system if root or the pacwoman user, and
|
||||
/// for the current user if not. If [std::fs::create_dir_all] returns an error, it will be
|
||||
/// propagated.
|
||||
pub fn create_directories() -> Result<(), std::io::Error> {
|
||||
if users::get_effective_uid() == 0 || get_current_user() == "pacwoman" {
|
||||
store_directory(false)?;
|
||||
config_directory(false)?;
|
||||
index_directory()?;
|
||||
} else {
|
||||
if users::get_effective_uid() == 0
|
||||
|| get_current_user() == "pacwoman"
|
||||
|| get_current_user() == "arthur"
|
||||
{
|
||||
store_directory(true)?;
|
||||
config_directory(true)?;
|
||||
index_directory()?;
|
||||
gpg_dir()?;
|
||||
bin_dir(true)?;
|
||||
} else {
|
||||
store_directory(false)?;
|
||||
config_directory(false)?;
|
||||
bin_dir(false)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -5,7 +5,10 @@
|
|||
clippy::empty_docs
|
||||
)]
|
||||
|
||||
fn main() {
|
||||
fn main() -> std::io::Result<()> {
|
||||
pacwoman::create_directories()?;
|
||||
//pacwoman::init_gpg()?;
|
||||
|
||||
pacwoman::populate_index(
|
||||
pacwoman::Mirror::new(url::Url::parse(
|
||||
"https://geo.mirror.pkgbuild.com/$repo/os/$arch",
|
||||
|
@ -13,5 +16,14 @@ fn main() {
|
|||
pacwoman::RepoDescriptor::new()
|
||||
.set_repo("core".to_string())
|
||||
.set_arch("x86_64".to_string()).clone(),
|
||||
).unwrap();
|
||||
)?;
|
||||
|
||||
for package in pacwoman::locate_package("pacman".to_string())? {
|
||||
println!("found package");
|
||||
pacwoman::install_package(pacwoman::Mirror::new(url::Url::parse(
|
||||
"https://geo.mirror.pkgbuild.com/$repo/os/$arch",
|
||||
).unwrap()), package.1, package.0, true)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue