mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
feat(pack): add install subcommand; clean up servo-shell stub comment
weft-pack: - install <dir>: validates the package (runs check), resolves the user app store root (WEFT_APP_STORE > ~/.local/share/weft/apps), copies the package directory to <root>/<app_id>/. Fails if the destination already exists. - resolve_install_root(): replaces the unused _resolve_store_roots; returns a single writable root rather than a search list. - copy_dir(): recursive directory copy using std::fs only; no new deps. - Updated usage text to include all three subcommands. weft-servo-shell: removed stale implementation-note comment from embed_servo stub.
This commit is contained in:
parent
ab38b96a7f
commit
265868bf67
2 changed files with 53 additions and 30 deletions
|
|
@ -43,10 +43,15 @@ fn main() -> anyhow::Result<()> {
|
||||||
let manifest = load_manifest(Path::new(dir))?;
|
let manifest = load_manifest(Path::new(dir))?;
|
||||||
print_info(&manifest);
|
print_info(&manifest);
|
||||||
}
|
}
|
||||||
|
Some("install") => {
|
||||||
|
let dir = args.get(2).context("usage: weft-pack install <dir>")?;
|
||||||
|
install_package(Path::new(dir))?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
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");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,22 +145,57 @@ fn is_valid_app_id(id: &str) -> bool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _resolve_store_roots() -> Vec<PathBuf> {
|
fn resolve_install_root() -> anyhow::Result<PathBuf> {
|
||||||
if let Ok(explicit) = std::env::var("WEFT_APP_STORE") {
|
if let Ok(explicit) = std::env::var("WEFT_APP_STORE") {
|
||||||
return vec![PathBuf::from(explicit)];
|
return Ok(PathBuf::from(explicit));
|
||||||
}
|
}
|
||||||
let mut roots = Vec::new();
|
|
||||||
if let Ok(home) = std::env::var("HOME") {
|
if let Ok(home) = std::env::var("HOME") {
|
||||||
roots.push(
|
return Ok(PathBuf::from(home)
|
||||||
PathBuf::from(home)
|
.join(".local")
|
||||||
.join(".local")
|
.join("share")
|
||||||
.join("share")
|
.join("weft")
|
||||||
.join("weft")
|
.join("apps"));
|
||||||
.join("apps"),
|
}
|
||||||
|
anyhow::bail!("cannot determine install root: HOME and WEFT_APP_STORE are both unset")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_package(dir: &Path) -> anyhow::Result<()> {
|
||||||
|
check_package(dir)?;
|
||||||
|
let manifest = load_manifest(dir)?;
|
||||||
|
let app_id = &manifest.package.id;
|
||||||
|
|
||||||
|
let store_root = resolve_install_root()?;
|
||||||
|
let dest = store_root.join(app_id);
|
||||||
|
|
||||||
|
if dest.exists() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"package '{}' is already installed at {}; remove it first",
|
||||||
|
app_id,
|
||||||
|
dest.display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
roots.push(PathBuf::from("/usr/share/weft/apps"));
|
|
||||||
roots
|
copy_dir(dir, &dest)
|
||||||
|
.with_context(|| format!("copy {} -> {}", dir.display(), dest.display()))?;
|
||||||
|
|
||||||
|
println!("installed {} -> {}", app_id, dest.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_dir(src: &Path, dst: &Path) -> anyhow::Result<()> {
|
||||||
|
std::fs::create_dir_all(dst)?;
|
||||||
|
for entry in std::fs::read_dir(src)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let src_path = entry.path();
|
||||||
|
let dst_path = dst.join(entry.file_name());
|
||||||
|
if src_path.is_dir() {
|
||||||
|
copy_dir(&src_path, &dst_path)?;
|
||||||
|
} else {
|
||||||
|
std::fs::copy(&src_path, &dst_path)
|
||||||
|
.with_context(|| format!("copy {}", src_path.display()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -43,23 +43,6 @@ fn system_ui_html_path() -> anyhow::Result<PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn embed_servo(_wayland_display: &str, _html_path: &std::path::Path) -> anyhow::Result<()> {
|
fn embed_servo(_wayland_display: &str, _html_path: &std::path::Path) -> anyhow::Result<()> {
|
||||||
// Wave 4 skeleton entry point.
|
|
||||||
//
|
|
||||||
// Full implementation requires completion of the items in
|
|
||||||
// docs/architecture/winit-wayland-audit.md before production readiness,
|
|
||||||
// and the following integration work:
|
|
||||||
//
|
|
||||||
// 1. Add servo git dependency (not on crates.io; requires building Servo)
|
|
||||||
// 2. Implement servo::EmbedderMethods and servo::WindowMethods for the
|
|
||||||
// WEFT Wayland surface (winit + EGL, or smithay-client-toolkit directly)
|
|
||||||
// 3. Call servo::Servo::new() with the window and embedder
|
|
||||||
// 4. Load the system UI via servo::ServoUrl::parse(html_path)
|
|
||||||
// 5. Run the Servo event loop, forwarding Wayland events from winit
|
|
||||||
//
|
|
||||||
// The Servo dependency is intentionally absent from Cargo.toml at this stage.
|
|
||||||
// It requires a git dependency on github.com/servo/servo which embeds
|
|
||||||
// SpiderMonkey (GeckoMedia) and has a multi-minute build time. It is added
|
|
||||||
// when the embedder contract is ready.
|
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"Servo embedding not yet implemented; \
|
"Servo embedding not yet implemented; \
|
||||||
see docs/architecture/winit-wayland-audit.md for gap assessment"
|
see docs/architecture/winit-wayland-audit.md for gap assessment"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue