-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
203 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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::*; |
Oops, something went wrong.