+58
-6
@@ -1,7 +1,11 @@
|
||||
use crate::common::format_size;
|
||||
use anyhow::anyhow;
|
||||
use clap::Parser;
|
||||
use packie::{PackieBuilder, package::PkgSpec};
|
||||
use packie::{
|
||||
PackieBuilder,
|
||||
local::Installation,
|
||||
package::{PkgManifest, PkgSpec},
|
||||
};
|
||||
use rust_i18n::t;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -20,11 +24,59 @@ pub fn main(cli: Cli) -> anyhow::Result<()> {
|
||||
}
|
||||
let found = found.remove(0);
|
||||
|
||||
println!("Package name: {}", found.pkg_manifest.name);
|
||||
println!("Package version: {}", found.pkg_manifest.version);
|
||||
println!("Package architecture: {}", found.pkg_manifest.arch);
|
||||
println!("Install package spec: {}", found.install_pkgspec);
|
||||
println!("Installed size: {}", format_size(found.installed_size));
|
||||
print_pkgmanifest(&found.pkg_manifest);
|
||||
print_install_misc(&found);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_pkgmanifest(pkg_manifest: &PkgManifest) {
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_pkgmanifest.name"),
|
||||
pkg_manifest.name
|
||||
);
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_pkgmanifest.version"),
|
||||
pkg_manifest.version
|
||||
);
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_pkgmanifest.arch"),
|
||||
pkg_manifest.arch
|
||||
);
|
||||
if !pkg_manifest.description.is_empty() {
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_pkgmanifest.description"),
|
||||
pkg_manifest.arch
|
||||
);
|
||||
}
|
||||
println!("{}:", t!("info.print_pkgmanifest.dependencies"));
|
||||
for i in pkg_manifest.dependencies.iter() {
|
||||
println!(" - {i}");
|
||||
}
|
||||
println!("{}:", t!("info.print_pkgmanifest.recommendations"));
|
||||
for i in pkg_manifest.recommendations.iter() {
|
||||
println!(" - {i}");
|
||||
}
|
||||
}
|
||||
|
||||
fn print_install_misc(installation: &Installation) {
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_install_misc.install_pkgspec"),
|
||||
installation.install_pkgspec
|
||||
);
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_install_misc.install_date"),
|
||||
installation.install_date,
|
||||
);
|
||||
println!(
|
||||
"{}: {}",
|
||||
t!("info.print_install_misc.installed_size"),
|
||||
format_size(installation.installed_size),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,3 +41,6 @@ repo.RepoError.AllTriesFailed:
|
||||
repo.download.DownloadError.Checksum:
|
||||
en: "checksum failed"
|
||||
zh-CN: "文件完整性检查失败"
|
||||
BuildPackieError.Lock:
|
||||
en: "failed to lock packie database: %{error}"
|
||||
zh-CN: "无法锁定 Packie 数据库:%{error}"
|
||||
|
||||
@@ -23,6 +23,33 @@ info.no_package_found:
|
||||
info.pkgspec_not_unique:
|
||||
en: "The specified package spec was not unique."
|
||||
zh-CN: "指定的包规范匹配了多个包。"
|
||||
info.print_pkgmanifest.name:
|
||||
en: "Package name"
|
||||
zh-CN: "包名"
|
||||
info.print_pkgmanifest.version:
|
||||
en: "Package version"
|
||||
zh-CN: "版本"
|
||||
info.print_pkgmanifest.arch:
|
||||
en: "Package architecture"
|
||||
zh-CN: "架构"
|
||||
info.print_pkgmanifest.dependencies:
|
||||
en: "Dependencies"
|
||||
zh-CN: "依赖"
|
||||
info.print_pkgmanifest.recommendations:
|
||||
en: "Recommendations"
|
||||
zh-CN: "建议安装"
|
||||
info.print_pkgmanifest.description:
|
||||
en: "Description"
|
||||
zh-CN: "描述"
|
||||
info.print_install_misc.install_pkgspec:
|
||||
en: "Install package spec"
|
||||
zh-CN: "安装请求"
|
||||
info.print_install_misc.installed_size:
|
||||
en: "Installed size"
|
||||
zh-CN: "安装后大小"
|
||||
info.print_install_misc.install_date:
|
||||
en: "Install date"
|
||||
zh-CN: "安装日期"
|
||||
remove.package_not_found:
|
||||
en: "The specified package was not found."
|
||||
zh-CN: "找不到指定的包。"
|
||||
|
||||
@@ -160,3 +160,24 @@ pub struct CopyError {
|
||||
dst: PathBuf,
|
||||
error: std::io::Error,
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
#[derive(Debug)]
|
||||
pub struct LockGuard(Option<nix::fcntl::Flock<std::fs::File>>);
|
||||
#[cfg(target_family = "unix")]
|
||||
impl LockGuard {
|
||||
pub fn noop() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
|
||||
pub fn open(path: impl AsRef<Path>, nonblocking: bool) -> std::io::Result<Self> {
|
||||
let file = std::fs::File::options().create(true).open(path)?;
|
||||
let flags = if nonblocking {
|
||||
nix::fcntl::FlockArg::LockExclusiveNonblock
|
||||
} else {
|
||||
nix::fcntl::FlockArg::LockExclusive
|
||||
};
|
||||
let lock = nix::fcntl::Flock::lock(file, flags).map_err(|x| x.1)?;
|
||||
Ok(Self(Some(lock)))
|
||||
}
|
||||
}
|
||||
|
||||
+21
-1
@@ -9,9 +9,11 @@ pub mod remove;
|
||||
pub mod repo;
|
||||
pub mod version;
|
||||
|
||||
use common::fs::LockGuard;
|
||||
use config::AllConfig;
|
||||
use local::{Cache, DataDir, LocalDb};
|
||||
use profile::Profile;
|
||||
use rust_i18n::t;
|
||||
|
||||
rust_i18n::i18n!("locales/libpackie", fallback = "en");
|
||||
|
||||
@@ -23,6 +25,7 @@ pub struct Packie {
|
||||
config: AllConfig,
|
||||
local_data: DataDir,
|
||||
cache: Cache,
|
||||
_lock_guard: LockGuard,
|
||||
}
|
||||
impl Packie {
|
||||
/// Returns profile of the Packie instance.
|
||||
@@ -31,16 +34,18 @@ impl Packie {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PackieBuilder {
|
||||
profile: Profile,
|
||||
readonly: bool,
|
||||
nonblocking: bool,
|
||||
}
|
||||
impl PackieBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
profile: Profile::builtin(),
|
||||
readonly: false,
|
||||
nonblocking: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,17 +54,27 @@ impl PackieBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn nonblocking(mut self, val: bool) -> Self {
|
||||
self.nonblocking = val;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn profile(mut self, val: Profile) -> Self {
|
||||
self.profile = val;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Packie, BuildPackieError> {
|
||||
let mut _lock_guard = LockGuard::noop();
|
||||
if !self.readonly {
|
||||
_ = std::fs::create_dir_all(&self.profile.packie_data_dir);
|
||||
_ = std::fs::create_dir_all(&self.profile.packie_cache_dir);
|
||||
_ = std::fs::create_dir_all(&self.profile.packie_config_dir);
|
||||
_ = std::fs::create_dir_all(&self.profile.pkg_dir);
|
||||
|
||||
let lock_path = self.profile.packie_data_dir.join("packie.lock");
|
||||
_lock_guard =
|
||||
LockGuard::open(lock_path, self.nonblocking).map_err(BuildPackieError::Lock)?;
|
||||
}
|
||||
let local_db_path = self.profile.packie_data_dir.join(LocalDb::FILENAME);
|
||||
let open_local_db = if self.readonly {
|
||||
@@ -71,12 +86,14 @@ impl PackieBuilder {
|
||||
let config = AllConfig::open(&self.profile.packie_config_dir);
|
||||
let cache = Cache(self.profile.packie_cache_dir.clone());
|
||||
let local_data = DataDir(self.profile.packie_data_dir.clone());
|
||||
|
||||
Ok(Packie {
|
||||
profile: self.profile,
|
||||
local_db,
|
||||
config,
|
||||
cache,
|
||||
local_data,
|
||||
_lock_guard,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -85,4 +102,7 @@ impl PackieBuilder {
|
||||
pub enum BuildPackieError {
|
||||
#[error("{0}")]
|
||||
LocalDb(rusqlite::Error),
|
||||
|
||||
#[error("{}", t!("BuildPackieError.Lock", error = .0))]
|
||||
Lock(std::io::Error),
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@ pub struct PkgManifest {
|
||||
#[serde(default)]
|
||||
pub dependencies: Vec<PkgSpec>,
|
||||
|
||||
/// Package recommended (soft) dependencies.
|
||||
#[serde(default)]
|
||||
pub recommendations: Vec<PkgSpec>,
|
||||
|
||||
/// Provided abstract packages.
|
||||
#[serde(default)]
|
||||
pub provides: Vec<AbsPkgIdent>,
|
||||
|
||||
Reference in New Issue
Block a user