mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
feat(pack): add list subcommand to show installed packages
list_installed_roots() searches WEFT_APP_STORE, then ~/.local/share/weft/apps, then /usr/share/weft/apps (same priority order as weft-runtime and weft-appd). list_installed() deduplicates by app_id (first root wins), sorts alphabetically within each root, and prints id/name/version per line. Prints 'no packages installed' when the store is empty or absent.
This commit is contained in:
parent
826f144d9d
commit
cab3a4a956
1 changed files with 53 additions and 0 deletions
|
|
@ -51,12 +51,16 @@ fn main() -> anyhow::Result<()> {
|
||||||
let app_id = args.get(2).context("usage: weft-pack uninstall <app_id>")?;
|
let app_id = args.get(2).context("usage: weft-pack uninstall <app_id>")?;
|
||||||
uninstall_package(app_id)?;
|
uninstall_package(app_id)?;
|
||||||
}
|
}
|
||||||
|
Some("list") => {
|
||||||
|
list_installed();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("usage:");
|
eprintln!("usage:");
|
||||||
eprintln!(" weft-pack check <dir> validate a package directory");
|
eprintln!(" weft-pack check <dir> validate a package directory");
|
||||||
eprintln!(" weft-pack info <dir> print package metadata");
|
eprintln!(" weft-pack info <dir> print package metadata");
|
||||||
eprintln!(" weft-pack install <dir> install package to app store");
|
eprintln!(" weft-pack install <dir> install package to app store");
|
||||||
eprintln!(" weft-pack uninstall <app_id> remove installed package");
|
eprintln!(" weft-pack uninstall <app_id> remove installed package");
|
||||||
|
eprintln!(" weft-pack list list installed packages");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,6 +232,55 @@ fn uninstall_package_from(app_id: &str, store_root: &Path) -> anyhow::Result<()>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_installed_roots() -> Vec<PathBuf> {
|
||||||
|
if let Ok(explicit) = std::env::var("WEFT_APP_STORE") {
|
||||||
|
return vec![PathBuf::from(explicit)];
|
||||||
|
}
|
||||||
|
let mut roots = Vec::new();
|
||||||
|
if let Ok(home) = std::env::var("HOME") {
|
||||||
|
roots.push(
|
||||||
|
PathBuf::from(home)
|
||||||
|
.join(".local")
|
||||||
|
.join("share")
|
||||||
|
.join("weft")
|
||||||
|
.join("apps"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
roots.push(PathBuf::from("/usr/share/weft/apps"));
|
||||||
|
roots
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_installed() {
|
||||||
|
let mut seen = std::collections::HashSet::new();
|
||||||
|
let mut count = 0usize;
|
||||||
|
for root in list_installed_roots() {
|
||||||
|
let Ok(entries) = std::fs::read_dir(&root) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let mut pkgs: Vec<(String, String, String)> = Vec::new();
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let manifest_path = entry.path().join("wapp.toml");
|
||||||
|
let Ok(contents) = std::fs::read_to_string(&manifest_path) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Ok(m) = toml::from_str::<Manifest>(&contents) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if seen.insert(m.package.id.clone()) {
|
||||||
|
pkgs.push((m.package.id, m.package.name, m.package.version));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pkgs.sort_by(|a, b| a.0.cmp(&b.0));
|
||||||
|
for (id, name, version) in pkgs {
|
||||||
|
println!("{id} {name} {version}");
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
println!("no packages installed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_dir(src: &Path, dst: &Path) -> anyhow::Result<()> {
|
fn copy_dir(src: &Path, dst: &Path) -> anyhow::Result<()> {
|
||||||
std::fs::create_dir_all(dst)?;
|
std::fs::create_dir_all(dst)?;
|
||||||
for entry in std::fs::read_dir(src)? {
|
for entry in std::fs::read_dir(src)? {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue