Skip to content

Commit

Permalink
Add features.
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Jan 24, 2024
1 parent 55d0072 commit 7f187f1
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 185 deletions.
4 changes: 4 additions & 0 deletions crates/download/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ moon_pdk = { workspace = true }
[dev-dependencies]
moon_pdk_test_utils = { workspace = true }
starbase_sandbox = { workspace = true }

[features]
default = ["wasm"]
wasm = []
68 changes: 68 additions & 0 deletions crates/download/src/download_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use extism_pdk::*;
use moon_extension_common::download::download_from_url;
use moon_pdk::{
anyhow, args::*, extension::*, host_log, plugin_err, virtual_path, HostLogInput, HostLogTarget,
VirtualPath,
};

#[host_fn]
extern "ExtismHost" {
fn host_log(input: Json<HostLogInput>);
fn to_virtual_path(path: String) -> String;
}

#[derive(Args)]
pub struct DownloadExtensionArgs {
#[arg(long, short = 'u', required = true)]
pub url: String,

#[arg(long, short = 'd')]
pub dest: Option<String>,

#[arg(long)]
pub name: Option<String>,
}

#[plugin_fn]
pub fn execute_extension(Json(input): Json<ExecuteExtensionInput>) -> FnResult<()> {
let args = parse_args::<DownloadExtensionArgs>(&input.args)?;

if !args.url.starts_with("http") {
return Err(plugin_err!("A valid URL is required for downloading."));
}

// Determine destination directory
debug!("Determining destination directory");

let dest_dir = virtual_path!(
buf,
input
.context
.get_absolute_path(args.dest.as_deref().unwrap_or_default())
);

if dest_dir.exists() && dest_dir.is_file() {
return Err(plugin_err!(
"Destination <path>{}</path> must be a directory, found a file.",
dest_dir.real_path().display(),
));
}

debug!(
"Destination <path>{}</path> will be used",
dest_dir.real_path().display(),
);

// Attempt to download the file
host_log!(stdout, "Downloading <url>{}</url>", args.url);

let dest_file = download_from_url(&args.url, &dest_dir, args.name.as_deref())?;

host_log!(
stdout,
"Downloaded to <path>{}</path>",
dest_file.real_path().display()
);

Ok(())
}
71 changes: 4 additions & 67 deletions crates/download/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,5 @@
use extism_pdk::*;
use moon_extension_common::download::download_from_url;
use moon_pdk::{
anyhow, args::*, extension::*, host_log, plugin_err, virtual_path, HostLogInput, HostLogTarget,
VirtualPath,
};
#[cfg(feature = "wasm")]
mod download_ext;

#[host_fn]
extern "ExtismHost" {
fn host_log(input: Json<HostLogInput>);
fn to_virtual_path(path: String) -> String;
}

#[derive(Args)]
pub struct DownloadExtensionArgs {
#[arg(long, short = 'u', required = true)]
pub url: String,

#[arg(long, short = 'd')]
pub dest: Option<String>,

#[arg(long)]
pub name: Option<String>,
}

#[plugin_fn]
pub fn execute_extension(Json(input): Json<ExecuteExtensionInput>) -> FnResult<()> {
let args = parse_args::<DownloadExtensionArgs>(&input.args)?;

if !args.url.starts_with("http") {
return Err(plugin_err!("A valid URL is required for downloading."));
}

// Determine destination directory
debug!("Determining destination directory");

let dest_dir = virtual_path!(
buf,
input
.context
.get_absolute_path(args.dest.as_deref().unwrap_or_default())
);

if dest_dir.exists() && dest_dir.is_file() {
return Err(plugin_err!(
"Destination <path>{}</path> must be a directory, found a file.",
dest_dir.real_path().display(),
));
}

debug!(
"Destination <path>{}</path> will be used",
dest_dir.real_path().display(),
);

// Attempt to download the file
host_log!(stdout, "Downloading <url>{}</url>", args.url);

let dest_file = download_from_url(&args.url, &dest_dir, args.name.as_deref())?;

host_log!(
stdout,
"Downloaded to <path>{}</path>",
dest_file.real_path().display()
);

Ok(())
}
#[cfg(feature = "wasm")]
pub use download_ext::*;
4 changes: 4 additions & 0 deletions crates/unpack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ starbase_archive = { version = "0.2.5", default-features = false, features = [
[dev-dependencies]
moon_pdk_test_utils = { workspace = true }
starbase_sandbox = { workspace = true }

[features]
default = ["wasm"]
wasm = []
122 changes: 4 additions & 118 deletions crates/unpack/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,119 +1,5 @@
use extism_pdk::*;
use moon_extension_common::download::download_from_url;
use moon_pdk::{
anyhow, args::*, extension::*, host_log, plugin_err, virtual_path, HostLogInput, HostLogTarget,
VirtualPath,
};
use starbase_archive::Archiver;
use std::fs;
#[cfg(feature = "wasm")]
mod unpack_ext;

#[host_fn]
extern "ExtismHost" {
fn host_log(input: Json<HostLogInput>);
fn to_virtual_path(path: String) -> String;
}

#[derive(Args)]
pub struct UnpackExtensionArgs {
#[arg(long, short = 's', required = true)]
pub src: String,

#[arg(long, short = 'd')]
pub dest: Option<String>,

#[arg(long)]
pub prefix: Option<String>,
}

#[plugin_fn]
pub fn execute_extension(Json(input): Json<ExecuteExtensionInput>) -> FnResult<()> {
let args = parse_args::<UnpackExtensionArgs>(&input.args)?;

// Determine the correct input. If the input is a URL, attempt to download
// the file, otherwise use the file directly (if within our whitelist).
let src_file = if args.src.starts_with("http") {
debug!("Received a URL as the input source");

download_from_url(&args.src, virtual_path!("/moon/temp"), None)?
} else {
debug!(
"Converting source <file>{}</file> to an absolute virtual path",
args.src
);

virtual_path!(buf, input.context.get_absolute_path(args.src))
};

if !src_file
.extension()
.is_some_and(|ext| ext == "tar" || ext == "tgz" || ext == "gz" || ext == "zip")
{
return Err(plugin_err!(
"Invalid source, only <file>.tar</file>, <file>.tar.gz</file>, and <file>.zip</file> archives are supported."
));
}

if !src_file.exists() || !src_file.is_file() {
return Err(plugin_err!(
"Source <path>{}</path> must be a valid file.",
src_file.real_path().display(),
));
}

host_log!(
stdout,
"Opening archive <path>{}</path>",
src_file.real_path().display()
);

// Convert the provided output into a virtual file path.
let dest_dir = virtual_path!(
buf,
input
.context
.get_absolute_path(args.dest.as_deref().unwrap_or_default())
);

if dest_dir.exists() && dest_dir.is_file() {
return Err(plugin_err!(
"Destination <path>{}</path> must be a directory, found a file.",
dest_dir.real_path().display(),
));
}

fs::create_dir_all(&dest_dir)?;

host_log!(
stdout,
"Unpacking archive to <path>{}</path>",
dest_dir.real_path().display()
);

// Attempt to unpack the archive!
let mut archive = Archiver::new(&dest_dir, &src_file);

// Diff against all files in the output dir
archive.add_source_glob("**/*");

// Remove the prefix from unpacked files
if let Some(prefix) = &args.prefix {
archive.set_prefix(prefix);
}

// Unpack the files
if let Err(error) = archive.unpack_from_ext() {
let mut message = error.to_string();

// Miette hides the real error
if let Some(source) = error.source() {
message.push(' ');
message.push_str(&source.to_string());
}

return Err(plugin_err!("{message}"));
};

host_log!(stdout, "Unpacked archive!");

Ok(())
}
#[cfg(feature = "wasm")]
pub use unpack_ext::*;
Loading

0 comments on commit 7f187f1

Please sign in to comment.