This commit is contained in:
parent
f51c5dc9d5
commit
f050daf035
12 changed files with 80 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct PKGR {}
|
pub struct PKGR {}
|
||||||
|
@ -8,4 +8,4 @@ impl Display for PKGR {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "")
|
write!(f, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::process::exit;
|
|
||||||
use crate::package::identifier::PackageIdentifier;
|
use crate::package::identifier::PackageIdentifier;
|
||||||
|
use crate::package::installer::{InstallType, PackageInstaller};
|
||||||
|
use crate::package::Package;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use manifest::Manifest;
|
use manifest::Manifest;
|
||||||
use crate::package::installer::{InstallType, PackageInstaller};
|
use std::process::exit;
|
||||||
use crate::package::Package;
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(name = "pkgr", version)]
|
#[clap(name = "pkgr", version)]
|
||||||
|
@ -86,9 +86,11 @@ impl Command {
|
||||||
|
|
||||||
info!("Install complete.");
|
info!("Install complete.");
|
||||||
info!("Install took {}ms.", duration.as_nanos() as f64 / 1000000.0);
|
info!("Install took {}ms.", duration.as_nanos() as f64 / 1000000.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
Command::Remove { package_identifier, index } => {
|
Command::Remove {
|
||||||
|
package_identifier,
|
||||||
|
index,
|
||||||
|
} => {
|
||||||
if let PackageIdentifier::URI(_) = package_identifier {
|
if let PackageIdentifier::URI(_) = package_identifier {
|
||||||
error!("URI is unsupported when removing applications.");
|
error!("URI is unsupported when removing applications.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -113,7 +115,10 @@ impl Command {
|
||||||
info!("PKGR AUTHORS: {}", env!("CARGO_PKG_AUTHORS"));
|
info!("PKGR AUTHORS: {}", env!("CARGO_PKG_AUTHORS"));
|
||||||
info!("PKGR DESCRIPTION: {}", env!("CARGO_PKG_DESCRIPTION"));
|
info!("PKGR DESCRIPTION: {}", env!("CARGO_PKG_DESCRIPTION"));
|
||||||
info!("");
|
info!("");
|
||||||
info!("PKGR_LOG_LEVEL: {}", std::env::var("PKGR_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()));
|
info!(
|
||||||
|
"PKGR_LOG_LEVEL: {}",
|
||||||
|
std::env::var("PKGR_LOG_LEVEL").unwrap_or_else(|_| "info".to_string())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Command::None => {
|
Command::None => {
|
||||||
error!("No command was specified.");
|
error!("No command was specified.");
|
||||||
|
|
|
@ -1,26 +1,18 @@
|
||||||
use log::SetLoggerError;
|
|
||||||
use fern::Dispatch;
|
|
||||||
use std::env;
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
use fern::Dispatch;
|
||||||
|
use log::SetLoggerError;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
pub fn setup_logger() -> Result<(), SetLoggerError> {
|
pub fn setup_logger() -> Result<(), SetLoggerError> {
|
||||||
Dispatch::new()
|
Dispatch::new()
|
||||||
.format(|out, message, record| {
|
.format(|out, message, record| {
|
||||||
match record.metadata().target() {
|
match record.metadata().target() {
|
||||||
"command:stdout" => {
|
"command:stdout" => {
|
||||||
out.finish(format_args!(
|
out.finish(format_args!("{} {}", "::".cyan(), message.to_string()));
|
||||||
"{} {}",
|
|
||||||
"::".cyan(),
|
|
||||||
message.to_string()
|
|
||||||
));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
"command:stderr" => {
|
"command:stderr" => {
|
||||||
out.finish(format_args!(
|
out.finish(format_args!("{} {}", "!!".red(), message.to_string()));
|
||||||
"{} {}",
|
|
||||||
"!!".red(),
|
|
||||||
message.to_string()
|
|
||||||
));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -28,30 +20,29 @@ pub fn setup_logger() -> Result<(), SetLoggerError> {
|
||||||
"{} {}",
|
"{} {}",
|
||||||
// Some logic so messages look nice
|
// Some logic so messages look nice
|
||||||
if message.to_string().len() > 0 {
|
if message.to_string().len() > 0 {
|
||||||
match record
|
match record.level().to_string().chars().nth(0).unwrap_or('T') {
|
||||||
.level()
|
|
||||||
.to_string()
|
|
||||||
.chars()
|
|
||||||
.nth(0)
|
|
||||||
.unwrap_or('T')
|
|
||||||
{
|
|
||||||
'T' => "[TRACE]".bright_blue(),
|
'T' => "[TRACE]".bright_blue(),
|
||||||
'D' => "??".green(),
|
'D' => "??".green(),
|
||||||
'I' => "=>".blue(),
|
'I' => "=>".blue(),
|
||||||
'W' => "##".yellow(),
|
'W' => "##".yellow(),
|
||||||
'E' => "!!".red(),
|
'E' => "!!".red(),
|
||||||
_ => "**".blue(),
|
_ => "**".blue(),
|
||||||
}.to_string()
|
}
|
||||||
} else { "".to_string() },
|
.to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
message.to_string().bright_white()
|
message.to_string().bright_white()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.level(env::var("PKGR_LOG_LEVEL")
|
.level(
|
||||||
.unwrap_or_else(|_| "info".to_string())
|
env::var("PKGR_LOG_LEVEL")
|
||||||
.parse()
|
.unwrap_or_else(|_| "info".to_string())
|
||||||
.unwrap_or(log::LevelFilter::Info))
|
.parse()
|
||||||
|
.unwrap_or(log::LevelFilter::Info),
|
||||||
|
)
|
||||||
.chain(std::io::stdout())
|
.chain(std::io::stdout())
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use std::process::Command;
|
use crate::commands::Cli;
|
||||||
|
use crate::process::Process;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use crate::commands::Cli;
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use crate::process::Process;
|
use std::process::Command;
|
||||||
|
|
||||||
mod process;
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod package;
|
|
||||||
mod tmpfs;
|
|
||||||
mod logging;
|
mod logging;
|
||||||
|
mod package;
|
||||||
|
mod process;
|
||||||
|
mod tmpfs;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
logging::setup_logger().expect("Unable to setup logger.");
|
logging::setup_logger().expect("Unable to setup logger.");
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
use crate::package::identifier::PackageLocator;
|
||||||
|
use pkgfile::PKGFile;
|
||||||
|
use reqwest::blocking::get;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use pkgfile::PKGFile;
|
|
||||||
use reqwest::blocking::get;
|
|
||||||
use crate::package::identifier::PackageLocator;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FetchError {
|
pub enum FetchError {
|
||||||
|
@ -26,9 +26,8 @@ impl Error for FetchError {}
|
||||||
|
|
||||||
pub fn fetch_by_path<S: Into<String>>(path: S) -> Result<PKGFile, FetchError> {
|
pub fn fetch_by_path<S: Into<String>>(path: S) -> Result<PKGFile, FetchError> {
|
||||||
std::fs::read(path.into())
|
std::fs::read(path.into())
|
||||||
.map_err(|e| FetchError::IOError(e)).and_then(|bytes| {
|
.map_err(|e| FetchError::IOError(e))
|
||||||
PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError)
|
.and_then(|bytes| PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_by_uri<S: Into<String>>(uri: S) -> Result<PKGFile, FetchError> {
|
pub fn fetch_by_uri<S: Into<String>>(uri: S) -> Result<PKGFile, FetchError> {
|
||||||
|
|
|
@ -88,7 +88,7 @@ impl FromStr for PackageLocator {
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[allow(unused_assignments)] // false positive
|
#[allow(unused_assignments)] // false positive
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
let mut version = None;
|
let mut version = None;
|
||||||
let mut tags = None;
|
let mut tags = None;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ impl Display for BinError {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BuildError {
|
pub enum BuildError {
|
||||||
InvalidManifest
|
InvalidManifest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for BuildError {
|
impl Display for BuildError {
|
||||||
|
@ -30,7 +30,7 @@ impl Display for BuildError {
|
||||||
pub enum InstallError {
|
pub enum InstallError {
|
||||||
BuildError(BuildError),
|
BuildError(BuildError),
|
||||||
BinError(BinError),
|
BinError(BinError),
|
||||||
Generic
|
Generic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for InstallError {
|
impl ToString for InstallError {
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
use std::fmt::Display;
|
use crate::tmpfs::TempDir;
|
||||||
use log::{debug, trace};
|
|
||||||
use errors::{BinError, BuildError, InstallError};
|
use errors::{BinError, BuildError, InstallError};
|
||||||
|
use log::{debug, trace};
|
||||||
use manifest::Manifest;
|
use manifest::Manifest;
|
||||||
use pkgfile::PKGFile;
|
use pkgfile::PKGFile;
|
||||||
use crate::tmpfs::TempDir;
|
use std::fmt::Display;
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InstallType {
|
pub enum InstallType {
|
||||||
Build,
|
Build,
|
||||||
Bin
|
Bin,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PackageInstaller {
|
pub struct PackageInstaller {
|
||||||
manifest: Manifest,
|
manifest: Manifest,
|
||||||
pkgfile: PKGFile,
|
pkgfile: PKGFile,
|
||||||
install_type: InstallType
|
install_type: InstallType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PackageInstaller {
|
impl PackageInstaller {
|
||||||
|
@ -25,7 +25,7 @@ impl PackageInstaller {
|
||||||
PackageInstaller {
|
PackageInstaller {
|
||||||
manifest: m,
|
manifest: m,
|
||||||
pkgfile: p,
|
pkgfile: p,
|
||||||
install_type: i
|
install_type: i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ impl PackageInstaller {
|
||||||
tmpdir.push(&self.manifest.package.name);
|
tmpdir.push(&self.manifest.package.name);
|
||||||
trace!("extracting package into: {}", tmpdir.to_string());
|
trace!("extracting package into: {}", tmpdir.to_string());
|
||||||
match self.extract_to(tmpdir.to_string()) {
|
match self.extract_to(tmpdir.to_string()) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
debug!("extracted package in: {}", tmpdir.to_string());
|
debug!("extracted package in: {}", tmpdir.to_string());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -60,14 +60,13 @@ impl PackageInstaller {
|
||||||
let build_manifest = self.manifest.build.clone().unwrap();
|
let build_manifest = self.manifest.build.clone().unwrap();
|
||||||
// TODO: Check dependencies
|
// TODO: Check dependencies
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install(&self) -> Result<(), InstallError> {
|
pub fn install(&self) -> Result<(), InstallError> {
|
||||||
match self.install_type {
|
match self.install_type {
|
||||||
InstallType::Bin => self.bin().map_err(|e| InstallError::BinError(e)),
|
InstallType::Bin => self.bin().map_err(|e| InstallError::BinError(e)),
|
||||||
InstallType::Build => self.build().map_err(|e| InstallError::BuildError(e))
|
InstallType::Build => self.build().map_err(|e| InstallError::BuildError(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
|
pub mod fetch;
|
||||||
pub mod identifier;
|
pub mod identifier;
|
||||||
pub mod installer;
|
pub mod installer;
|
||||||
pub mod fetch;
|
|
||||||
|
|
||||||
pub struct Package {
|
pub struct Package {
|
||||||
pub identifier: identifier::PackageIdentifier,
|
pub identifier: identifier::PackageIdentifier,
|
||||||
|
@ -23,43 +23,47 @@ impl Package {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch a package from a package identifier.
|
/// Fetch a package from a package identifier.
|
||||||
pub fn fetch(package_identifier: identifier::PackageIdentifier) -> Result<Package, fetch::FetchError> {
|
pub fn fetch(
|
||||||
|
package_identifier: identifier::PackageIdentifier,
|
||||||
|
) -> Result<Package, fetch::FetchError> {
|
||||||
match &package_identifier {
|
match &package_identifier {
|
||||||
identifier::PackageIdentifier::Path(path) => {
|
identifier::PackageIdentifier::Path(path) => {
|
||||||
trace!("fetching package from path: {}", path);
|
trace!("fetching package from path: {}", path);
|
||||||
let pkgfile = fetch::fetch_by_path(path).unwrap();
|
let pkgfile = fetch::fetch_by_path(path).unwrap();
|
||||||
Ok(Package::new(package_identifier, pkgfile))
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
},
|
}
|
||||||
identifier::PackageIdentifier::URI(url) => {
|
identifier::PackageIdentifier::URI(url) => {
|
||||||
trace!("fetching package from uri: {}", url);
|
trace!("fetching package from uri: {}", url);
|
||||||
let pkgfile = fetch::fetch_by_uri(url).unwrap();
|
let pkgfile = fetch::fetch_by_uri(url).unwrap();
|
||||||
Ok(Package::new(package_identifier, pkgfile))
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
},
|
}
|
||||||
identifier::PackageIdentifier::PackageLocator(locator) => {
|
identifier::PackageIdentifier::PackageLocator(locator) => {
|
||||||
trace!("fetching package from locator: {}", locator);
|
trace!("fetching package from locator: {}", locator);
|
||||||
let pkgfile = fetch::fetch_by_package_locator(locator.clone()).unwrap();
|
let pkgfile = fetch::fetch_by_package_locator(locator.clone()).unwrap();
|
||||||
Ok(Package::new(package_identifier, pkgfile))
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the package manifest.
|
/// Get the package manifest.
|
||||||
pub fn manifest(&self) -> manifest::Manifest {
|
pub fn manifest(&self) -> manifest::Manifest {
|
||||||
manifest::Manifest::try_from(self.pkgfile.manifest.clone())
|
manifest::Manifest::try_from(self.pkgfile.manifest.clone()).unwrap()
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Install the package.
|
/// Install the package.
|
||||||
pub fn install(&mut self) -> Result<(), installer::errors::InstallError> {
|
pub fn install(&mut self) -> Result<(), installer::errors::InstallError> {
|
||||||
let manifest = self.manifest();
|
let manifest = self.manifest();
|
||||||
let installer = installer::PackageInstaller::new(manifest.clone(), self.pkgfile.clone(), installer::InstallType::Bin);
|
let installer = installer::PackageInstaller::new(
|
||||||
|
manifest.clone(),
|
||||||
|
self.pkgfile.clone(),
|
||||||
|
installer::InstallType::Bin,
|
||||||
|
);
|
||||||
match installer.install() {
|
match installer.install() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.is_installed = true;
|
self.is_installed = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,4 +81,4 @@ impl Package {
|
||||||
pub fn remove(&mut self) -> Result<(), ()> {
|
pub fn remove(&mut self) -> Result<(), ()> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@ pub struct Process {
|
||||||
|
|
||||||
impl Process {
|
impl Process {
|
||||||
pub fn new(command: Vec<String>, cwd: Option<String>, env: Vec<String>) -> Process {
|
pub fn new(command: Vec<String>, cwd: Option<String>, env: Vec<String>) -> Process {
|
||||||
Process {
|
Process { command, cwd, env }
|
||||||
command,
|
|
||||||
cwd,
|
|
||||||
env,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command<S: Into<String>>(cmd: Vec<S>) -> Process {
|
pub fn command<S: Into<String>>(cmd: Vec<S>) -> Process {
|
||||||
|
@ -27,7 +23,10 @@ impl Process {
|
||||||
.current_dir(self.cwd.clone().unwrap_or(".".to_string()))
|
.current_dir(self.cwd.clone().unwrap_or(".".to_string()))
|
||||||
.envs(self.env.iter().map(|v| {
|
.envs(self.env.iter().map(|v| {
|
||||||
let mut split = v.split('=');
|
let mut split = v.split('=');
|
||||||
(split.next().unwrap().to_string(), split.next().unwrap().to_string())
|
(
|
||||||
|
split.next().unwrap().to_string(),
|
||||||
|
split.next().unwrap().to_string(),
|
||||||
|
)
|
||||||
}))
|
}))
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
|
@ -41,4 +40,4 @@ impl Default for Process {
|
||||||
fn default() -> Process {
|
fn default() -> Process {
|
||||||
Process::new(vec![], None, vec![])
|
Process::new(vec![], None, vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// create functions that spawn threads for Stdout and Stderr
|
// create functions that spawn threads for Stdout and Stderr
|
||||||
// that print the output to info!(target: "command:stdout", ...) and info!(target: "command:stderr", ...) respectively
|
// that print the output to info!(target: "command:stdout", ...) and info!(target: "command:stderr", ...) respectively
|
||||||
|
|
||||||
use std::process::Child;
|
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
|
use std::process::Child;
|
||||||
|
|
||||||
use log::{info, error};
|
use log::{error, info};
|
||||||
|
|
||||||
pub fn spawn_output_handlers(child: &mut Child) {
|
pub fn spawn_output_handlers(child: &mut Child) {
|
||||||
let stdout = child.stdout.take().unwrap();
|
let stdout = child.stdout.take().unwrap();
|
||||||
|
@ -23,4 +23,4 @@ pub fn spawn_output_handlers(child: &mut Child) {
|
||||||
error!(target: "command:stderr", "{}", line.unwrap());
|
error!(target: "command:stderr", "{}", line.unwrap());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ impl TempDir {
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
std::fs::create_dir_all(&path).unwrap();
|
std::fs::create_dir_all(&path).unwrap();
|
||||||
}
|
}
|
||||||
TempDir {
|
TempDir { path }
|
||||||
path
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push<S: Into<String>>(&mut self, path: S) {
|
pub fn push<S: Into<String>>(&mut self, path: S) {
|
||||||
|
@ -45,4 +43,4 @@ impl ToString for TempDir {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
self.path.to_str().unwrap().to_string()
|
self.path.to_str().unwrap().to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue