mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 12:48:20 +00:00
cargo fmt
This commit is contained in:
@@ -199,21 +199,28 @@ fn parse_cli_args() -> Result<(), anyhow::Error> {
|
|||||||
#[cfg(feature = "binfmt")]
|
#[cfg(feature = "binfmt")]
|
||||||
(Some("binfmt"), _) => Binfmt::try_parse_from(args_without_first_arg.iter())?.execute(),
|
(Some("binfmt"), _) => Binfmt::try_parse_from(args_without_first_arg.iter())?.execute(),
|
||||||
(Some("list"), Some("--installed")) => {
|
(Some("list"), Some("--installed")) => {
|
||||||
use prettytable::{format, Table, row};
|
use prettytable::{format, row, Table};
|
||||||
|
|
||||||
let rows = get_all_local_packages()
|
let rows = get_all_local_packages()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pkg| {
|
.map(|pkg| {
|
||||||
|
let commands = pkg
|
||||||
|
.manifest
|
||||||
|
.command
|
||||||
|
.unwrap_or_default()
|
||||||
|
.iter()
|
||||||
|
.map(|c| c.get_name())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" \r\n");
|
||||||
|
|
||||||
let commands = pkg.manifest.command
|
row![
|
||||||
.unwrap_or_default()
|
pkg.registry.clone(),
|
||||||
.iter()
|
pkg.name.clone(),
|
||||||
.map(|c| c.get_name())
|
pkg.version.clone(),
|
||||||
.collect::<Vec<_>>()
|
commands
|
||||||
.join(" \r\n");
|
]
|
||||||
|
})
|
||||||
row![pkg.registry.clone(), pkg.name.clone(), pkg.version.clone(), commands]
|
.collect::<Vec<_>>();
|
||||||
}).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut table = Table::init(rows);
|
let mut table = Table::init(rows);
|
||||||
table.set_titles(row!["Registry", "Package", "Version", "Commands"]);
|
table.set_titles(row!["Registry", "Package", "Version", "Commands"]);
|
||||||
@@ -251,13 +258,12 @@ fn parse_cli_args() -> Result<(), anyhow::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// else: local package not found
|
// else: local package not found
|
||||||
let sp =
|
let sp = spinner::SpinnerBuilder::new(format!("Installing package {package} ..."))
|
||||||
spinner::SpinnerBuilder::new(format!("Installing package {package} ..."))
|
.spinner(vec![
|
||||||
.spinner(vec![
|
"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷", " ", "⠁", "⠂", "⠄", "⡀", "⢀", "⠠",
|
||||||
"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷", " ", "⠁", "⠂", "⠄", "⡀",
|
"⠐", "⠈",
|
||||||
"⢀", "⠠", "⠐", "⠈",
|
])
|
||||||
])
|
.start();
|
||||||
.start();
|
|
||||||
|
|
||||||
let v = version.as_ref().map(|s| s.as_str());
|
let v = version.as_ref().map(|s| s.as_str());
|
||||||
let result = wasmer_registry::install_package(&package, v);
|
let result = wasmer_registry::install_package(&package, v);
|
||||||
@@ -271,7 +277,7 @@ fn parse_cli_args() -> Result<(), anyhow::Error> {
|
|||||||
return RunWithoutFile::try_parse_from(args_without_package.iter())?
|
return RunWithoutFile::try_parse_from(args_without_package.iter())?
|
||||||
.into_run_args(o)
|
.into_run_args(o)
|
||||||
.execute();
|
.execute();
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("{e}");
|
println!("{e}");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::env;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::env;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
pub mod graphql {
|
pub mod graphql {
|
||||||
|
|
||||||
|
use core::time;
|
||||||
use graphql_client::*;
|
use graphql_client::*;
|
||||||
#[cfg(not(target_os = "wasi"))]
|
#[cfg(not(target_os = "wasi"))]
|
||||||
use reqwest::{
|
use reqwest::{
|
||||||
blocking::{multipart::Form, Client},
|
blocking::{multipart::Form, Client},
|
||||||
header::USER_AGENT,
|
header::USER_AGENT,
|
||||||
};
|
};
|
||||||
use core::time;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
#[cfg(target_os = "wasi")]
|
#[cfg(target_os = "wasi")]
|
||||||
@@ -253,13 +253,7 @@ pub mod graphql {
|
|||||||
for<'de> R: serde::Deserialize<'de>,
|
for<'de> R: serde::Deserialize<'de>,
|
||||||
V: serde::Serialize,
|
V: serde::Serialize,
|
||||||
{
|
{
|
||||||
execute_query_modifier_inner(
|
execute_query_modifier_inner(registry_url, login_token, query, Some(timeout), |f| f)
|
||||||
registry_url,
|
|
||||||
login_token,
|
|
||||||
query,
|
|
||||||
Some(timeout),
|
|
||||||
|f| f
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,14 +350,12 @@ fn format_graphql(registry: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialWapmConfig {
|
impl PartialWapmConfig {
|
||||||
|
|
||||||
pub fn from_file() -> Result<Self, String> {
|
pub fn from_file() -> Result<Self, String> {
|
||||||
let path = Self::get_file_location()?;
|
let path = Self::get_file_location()?;
|
||||||
|
|
||||||
match std::fs::read_to_string(&path) {
|
match std::fs::read_to_string(&path) {
|
||||||
Ok(config_toml) => {
|
Ok(config_toml) => {
|
||||||
toml::from_str(&config_toml)
|
toml::from_str(&config_toml).map_err(|e| format!("could not parse {path:?}: {e}"))
|
||||||
.map_err(|e| format!("could not parse {path:?}: {e}"))
|
|
||||||
}
|
}
|
||||||
Err(_e) => Ok(Self::default()),
|
Err(_e) => Ok(Self::default()),
|
||||||
}
|
}
|
||||||
@@ -379,10 +371,7 @@ impl PartialWapmConfig {
|
|||||||
|
|
||||||
pub fn get_folder() -> Result<PathBuf, String> {
|
pub fn get_folder() -> Result<PathBuf, String> {
|
||||||
Ok(
|
Ok(
|
||||||
if let Some(folder_str) = env::var("WASMER_DIR")
|
if let Some(folder_str) = env::var("WASMER_DIR").ok().filter(|s| !s.is_empty()) {
|
||||||
.ok()
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
{
|
|
||||||
let folder = PathBuf::from(folder_str);
|
let folder = PathBuf::from(folder_str);
|
||||||
std::fs::create_dir_all(folder.clone())
|
std::fs::create_dir_all(folder.clone())
|
||||||
.map_err(|e| format!("cannot create config directory: {e}"))?;
|
.map_err(|e| format!("cannot create config directory: {e}"))?;
|
||||||
@@ -426,13 +415,26 @@ pub fn get_command_local(name: &str) -> Result<PathBuf, String> {
|
|||||||
Err(format!("unimplemented"))
|
Err(format!("unimplemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_local_dir(registry_host: &str, name: &str, version: &str) -> Result<PathBuf, String> {
|
pub fn get_package_local_dir(
|
||||||
|
registry_host: &str,
|
||||||
|
name: &str,
|
||||||
|
version: &str,
|
||||||
|
) -> Result<PathBuf, String> {
|
||||||
if !name.contains("/") {
|
if !name.contains("/") {
|
||||||
return Err(format!("package name has to be in the format namespace/package: {name:?}"));
|
return Err(format!(
|
||||||
|
"package name has to be in the format namespace/package: {name:?}"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let namespace = name.split("/").nth(0).ok_or(format!("missing namespace for {name:?}"))?;
|
let namespace = name
|
||||||
let name = name.split("/").nth(1).ok_or(format!("missing name for {name:?}"))?;
|
.split("/")
|
||||||
let install_dir = get_global_install_dir(registry_host).ok_or(format!("no install dir for {name:?}"))?;
|
.nth(0)
|
||||||
|
.ok_or(format!("missing namespace for {name:?}"))?;
|
||||||
|
let name = name
|
||||||
|
.split("/")
|
||||||
|
.nth(1)
|
||||||
|
.ok_or(format!("missing name for {name:?}"))?;
|
||||||
|
let install_dir =
|
||||||
|
get_global_install_dir(registry_host).ok_or(format!("no install dir for {name:?}"))?;
|
||||||
Ok(install_dir.join(namespace).join(name).join(version))
|
Ok(install_dir.join(namespace).join(name).join(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,8 +448,9 @@ pub struct LocalPackage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_names_in_dir(dir: &PathBuf) -> Vec<(PathBuf, String)> {
|
fn get_all_names_in_dir(dir: &PathBuf) -> Vec<(PathBuf, String)> {
|
||||||
|
if !dir.is_dir() {
|
||||||
if !dir.is_dir() { return Vec::new(); }
|
return Vec::new();
|
||||||
|
}
|
||||||
|
|
||||||
let read_dir = match std::fs::read_dir(dir) {
|
let read_dir = match std::fs::read_dir(dir) {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
@@ -455,8 +458,8 @@ fn get_all_names_in_dir(dir: &PathBuf) -> Vec<(PathBuf, String)> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let entries = read_dir
|
let entries = read_dir
|
||||||
.map(|res| res.map(|e| e.path()))
|
.map(|res| res.map(|e| e.path()))
|
||||||
.collect::<Result<Vec<_>, std::io::Error>>();
|
.collect::<Result<Vec<_>, std::io::Error>>();
|
||||||
|
|
||||||
let registry_entries = match entries {
|
let registry_entries = match entries {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
@@ -464,20 +467,16 @@ fn get_all_names_in_dir(dir: &PathBuf) -> Vec<(PathBuf, String)> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
registry_entries
|
registry_entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|re| {
|
.filter_map(|re| Some((re.clone(), re.file_name()?.to_str()?.to_string())))
|
||||||
Some((re.clone(), re.file_name()?.to_str()?.to_string()))
|
.collect()
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all locally installed packages
|
/// Returns a list of all locally installed packages
|
||||||
pub fn get_all_local_packages() -> Vec<LocalPackage> {
|
pub fn get_all_local_packages() -> Vec<LocalPackage> {
|
||||||
|
|
||||||
let mut packages = Vec::new();
|
let mut packages = Vec::new();
|
||||||
|
|
||||||
'outer: for registry in get_all_available_registries().unwrap_or_default() {
|
'outer: for registry in get_all_available_registries().unwrap_or_default() {
|
||||||
|
|
||||||
let root_dir = match get_global_install_dir(®istry) {
|
let root_dir = match get_global_install_dir(®istry) {
|
||||||
Some(o) => o,
|
Some(o) => o,
|
||||||
None => continue 'outer,
|
None => continue 'outer,
|
||||||
@@ -511,20 +510,27 @@ pub fn get_all_local_packages() -> Vec<LocalPackage> {
|
|||||||
|
|
||||||
pub fn get_local_package(name: &str, version: Option<&str>) -> Option<LocalPackage> {
|
pub fn get_local_package(name: &str, version: Option<&str>) -> Option<LocalPackage> {
|
||||||
get_all_local_packages()
|
get_all_local_packages()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| {
|
.filter(|p| {
|
||||||
if p.name != name { return false; }
|
if p.name != name {
|
||||||
if let Some(v) = version {
|
return false;
|
||||||
if p.version != v { return false; }
|
}
|
||||||
}
|
if let Some(v) = version {
|
||||||
true
|
if p.version != v {
|
||||||
})
|
return false;
|
||||||
.cloned()
|
}
|
||||||
.next()
|
}
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_local_wasm_file(registry_host: &str, name: &str, version: &str) -> Result<PathBuf, String> {
|
pub fn get_package_local_wasm_file(
|
||||||
|
registry_host: &str,
|
||||||
|
name: &str,
|
||||||
|
version: &str,
|
||||||
|
) -> Result<PathBuf, String> {
|
||||||
let dir = get_package_local_dir(registry_host, name, version)?;
|
let dir = get_package_local_dir(registry_host, name, version)?;
|
||||||
let wapm_toml_path = dir.join("wapm.toml");
|
let wapm_toml_path = dir.join("wapm.toml");
|
||||||
let wapm_toml_str = std::fs::read_to_string(&wapm_toml_path)
|
let wapm_toml_str = std::fs::read_to_string(&wapm_toml_path)
|
||||||
@@ -533,11 +539,14 @@ pub fn get_package_local_wasm_file(registry_host: &str, name: &str, version: &st
|
|||||||
.map_err(|e| format!("cannot parse wapm.toml for {name}@{version}"))?;
|
.map_err(|e| format!("cannot parse wapm.toml for {name}@{version}"))?;
|
||||||
|
|
||||||
// TODO: this will just return the path for the first command, so this might not be correct
|
// TODO: this will just return the path for the first command, so this might not be correct
|
||||||
let command_name = wapm.command
|
let command_name = wapm
|
||||||
|
.command
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.first()
|
.first()
|
||||||
.map(|m| m.get_module())
|
.map(|m| m.get_module())
|
||||||
.ok_or(format!("cannot get entrypoint for {name}@{version}: package has no commands"))?;
|
.ok_or(format!(
|
||||||
|
"cannot get entrypoint for {name}@{version}: package has no commands"
|
||||||
|
))?;
|
||||||
|
|
||||||
Ok(dir.join(command_name))
|
Ok(dir.join(command_name))
|
||||||
}
|
}
|
||||||
@@ -553,11 +562,7 @@ pub fn query_package_from_registry(
|
|||||||
name: &str,
|
name: &str,
|
||||||
version: Option<&str>,
|
version: Option<&str>,
|
||||||
) -> Result<PackageDownloadInfo, (Vec<PackageDownloadInfo>, String)> {
|
) -> Result<PackageDownloadInfo, (Vec<PackageDownloadInfo>, String)> {
|
||||||
|
use crate::graphql::{execute_query, get_packages_query, GetPackagesQuery};
|
||||||
use crate::graphql::{
|
|
||||||
GetPackagesQuery, get_packages_query,
|
|
||||||
execute_query
|
|
||||||
};
|
|
||||||
use graphql_client::GraphQLQuery;
|
use graphql_client::GraphQLQuery;
|
||||||
|
|
||||||
let q = if name.contains("/") {
|
let q = if name.contains("/") {
|
||||||
@@ -572,61 +577,72 @@ pub fn query_package_from_registry(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let response: get_packages_query::ResponseData = execute_query(registry_url, "", &q)
|
let response: get_packages_query::ResponseData = execute_query(registry_url, "", &q)
|
||||||
.map_err(|e| (Vec::new(), format!("Error sending GetPackagesQuery: {e}")))?;
|
.map_err(|e| (Vec::new(), format!("Error sending GetPackagesQuery: {e}")))?;
|
||||||
|
|
||||||
let available_packages = response.package
|
let available_packages = response
|
||||||
.iter()
|
.package
|
||||||
.filter_map(|p| {
|
.iter()
|
||||||
|
.filter_map(|p| {
|
||||||
|
let p = p.as_ref()?;
|
||||||
|
let mut versions = Vec::new();
|
||||||
|
|
||||||
let p = p.as_ref()?;
|
for v in p.versions.iter() {
|
||||||
let mut versions = Vec::new();
|
for v in v.iter() {
|
||||||
|
let v = match v.as_ref() {
|
||||||
|
Some(s) => s,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
for v in p.versions.iter() {
|
versions.push(PackageDownloadInfo {
|
||||||
for v in v.iter() {
|
registry: registry_url.to_string(),
|
||||||
let v = match v.as_ref() {
|
package: p.name.clone(),
|
||||||
Some(s) => s,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
versions.push(PackageDownloadInfo {
|
version: v.version.clone(),
|
||||||
registry: registry_url.to_string(),
|
|
||||||
package: p.name.clone(),
|
|
||||||
|
|
||||||
version: v.version.clone(),
|
commands: toml::from_str::<wapm_toml::Manifest>(&v.manifest)
|
||||||
|
.ok()?
|
||||||
|
.command
|
||||||
|
.unwrap_or_default()
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.get_name())
|
||||||
|
.collect(),
|
||||||
|
|
||||||
commands: toml::from_str::<wapm_toml::Manifest>(
|
url: v.distribution.download_url.clone(),
|
||||||
&v.manifest
|
});
|
||||||
).ok()?
|
}
|
||||||
.command.unwrap_or_default()
|
|
||||||
.iter().map(|s| s.get_name()).collect(),
|
|
||||||
|
|
||||||
url: v.distribution.download_url.clone(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Some(versions)
|
Some(versions)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|v| v.into_iter())
|
.flat_map(|v| v.into_iter())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let queried_package = available_packages.iter()
|
let queried_package = available_packages
|
||||||
.filter_map(|v| {
|
.iter()
|
||||||
if name.contains("/") && v.package != name {
|
.filter_map(|v| {
|
||||||
return None;
|
if name.contains("/") && v.package != name {
|
||||||
}
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
if version.is_some() && v.version != version.clone().unwrap() {
|
if version.is_some() && v.version != version.clone().unwrap() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(v)
|
Some(v)
|
||||||
}).next().cloned();
|
})
|
||||||
|
.next()
|
||||||
|
.cloned();
|
||||||
|
|
||||||
match queried_package {
|
match queried_package {
|
||||||
None => Err((available_packages, format!("No package found for {name}@{}", version.unwrap_or("latest")))),
|
None => Err((
|
||||||
|
available_packages,
|
||||||
|
format!(
|
||||||
|
"No package found for {name}@{}",
|
||||||
|
version.unwrap_or("latest")
|
||||||
|
),
|
||||||
|
)),
|
||||||
Some(s) => Ok(s),
|
Some(s) => Ok(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -634,18 +650,18 @@ pub fn query_package_from_registry(
|
|||||||
/// Returs the path to the directory where all packages on this computer are being stored
|
/// Returs the path to the directory where all packages on this computer are being stored
|
||||||
pub fn get_global_install_dir(registry_host: &str) -> Option<PathBuf> {
|
pub fn get_global_install_dir(registry_host: &str) -> Option<PathBuf> {
|
||||||
Some(
|
Some(
|
||||||
PartialWapmConfig::get_folder().ok()?
|
PartialWapmConfig::get_folder()
|
||||||
|
.ok()?
|
||||||
.join("checkouts")
|
.join("checkouts")
|
||||||
.join(registry_host),
|
.join(registry_host),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn download_and_unpack_targz(url: &str, target_path: &Path) -> Result<PathBuf, String> {
|
pub fn download_and_unpack_targz(url: &str, target_path: &Path) -> Result<PathBuf, String> {
|
||||||
|
|
||||||
let target_targz_path = target_path.to_path_buf().join("package.tar.gz");
|
let target_targz_path = target_path.to_path_buf().join("package.tar.gz");
|
||||||
|
|
||||||
let mut resp = reqwest::blocking::get(url)
|
let mut resp =
|
||||||
.map_err(|e| format!("failed to download {url}: {e}"))?;
|
reqwest::blocking::get(url).map_err(|e| format!("failed to download {url}: {e}"))?;
|
||||||
|
|
||||||
if !target_targz_path.exists() {
|
if !target_targz_path.exists() {
|
||||||
// create all the parent paths, only remove the created directory, not the parent dirs
|
// create all the parent paths, only remove the created directory, not the parent dirs
|
||||||
@@ -654,22 +670,29 @@ pub fn download_and_unpack_targz(url: &str, target_path: &Path) -> Result<PathBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut file = std::fs::File::create(&target_targz_path)
|
let mut file = std::fs::File::create(&target_targz_path).map_err(|e| {
|
||||||
.map_err(|e| format!("failed to download {url} into {}: {e}", target_targz_path.display()))?;
|
format!(
|
||||||
|
"failed to download {url} into {}: {e}",
|
||||||
|
target_targz_path.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
reqwest::blocking::get(url)
|
reqwest::blocking::get(url).map_err(|e| format!("{e}"))?;
|
||||||
.map_err(|e| format!("{e}"))?;
|
|
||||||
|
|
||||||
resp.copy_to(&mut file).map_err(|e| format!("{e}"))?;
|
resp.copy_to(&mut file).map_err(|e| format!("{e}"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let file = std::fs::File::open(&target_targz_path)
|
let file = std::fs::File::open(&target_targz_path).map_err(|e| {
|
||||||
.map_err(|e| format!("failed to download {url} into {}: {e}", target_targz_path.display()))?;
|
format!(
|
||||||
|
"failed to download {url} into {}: {e}",
|
||||||
|
target_targz_path.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let gz_decoded = flate2::read::GzDecoder::new(file);
|
let gz_decoded = flate2::read::GzDecoder::new(file);
|
||||||
let mut ar = tar::Archive::new(gz_decoded);
|
let mut ar = tar::Archive::new(gz_decoded);
|
||||||
ar.unpack(target_path)
|
ar.unpack(target_path)
|
||||||
.map_err(|e| format!("failed to unpack {}: {e}", target_targz_path.display()))?;
|
.map_err(|e| format!("failed to unpack {}: {e}", target_targz_path.display()))?;
|
||||||
|
|
||||||
let _ = std::fs::remove_file(target_targz_path);
|
let _ = std::fs::remove_file(target_targz_path);
|
||||||
|
|
||||||
@@ -677,7 +700,6 @@ pub fn download_and_unpack_targz(url: &str, target_path: &Path) -> Result<PathBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn install_package(name: &str, version: Option<&str>) -> Result<PathBuf, String> {
|
pub fn install_package(name: &str, version: Option<&str>) -> Result<PathBuf, String> {
|
||||||
|
|
||||||
let registries = get_all_available_registries()?;
|
let registries = get_all_available_registries()?;
|
||||||
let mut url_of_package = None;
|
let mut url_of_package = None;
|
||||||
let mut error_packages = Vec::new();
|
let mut error_packages = Vec::new();
|
||||||
@@ -691,10 +713,10 @@ pub fn install_package(name: &str, version: Option<&str>) -> Result<PathBuf, Str
|
|||||||
Ok(o) => {
|
Ok(o) => {
|
||||||
url_of_package = Some((r, o));
|
url_of_package = Some((r, o));
|
||||||
break;
|
break;
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error_packages.push(e);
|
error_packages.push(e);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,61 +731,65 @@ pub fn install_package(name: &str, version: Option<&str>) -> Result<PathBuf, Str
|
|||||||
.filter_map(|s| Some(format!("{}", s.host_str()?)))
|
.filter_map(|s| Some(format!("{}", s.host_str()?)))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let did_you_mean = error_packages.iter()
|
let did_you_mean = error_packages
|
||||||
.flat_map(|(packages, _)| {
|
.iter()
|
||||||
packages.iter().filter_map(|f| {
|
.flat_map(|(packages, _)| {
|
||||||
let from = url::Url::parse(&f.registry).ok()?.host_str()?.to_string();
|
packages.iter().filter_map(|f| {
|
||||||
Some(format!(" {}@{} (from {from})", f.package, f.version))
|
let from = url::Url::parse(&f.registry).ok()?.host_str()?.to_string();
|
||||||
|
Some(format!(" {}@{} (from {from})", f.package, f.version))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}).collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\r\n");
|
.join("\r\n");
|
||||||
|
|
||||||
let (_, package_info) = url_of_package
|
let (_, package_info) = url_of_package
|
||||||
.ok_or(format!("Package {version_str} not found in registries: {registries_searched:?}.\r\n\r\nDid you mean:\r\n{did_you_mean}\r\n"))?;
|
.ok_or(format!("Package {version_str} not found in registries: {registries_searched:?}.\r\n\r\nDid you mean:\r\n{did_you_mean}\r\n"))?;
|
||||||
|
|
||||||
let host = url::Url::parse(&package_info.url)
|
let host = url::Url::parse(&package_info.url)
|
||||||
.map_err(|e| format!("invalid url: {}: {e}", package_info.url))?
|
.map_err(|e| format!("invalid url: {}: {e}", package_info.url))?
|
||||||
.host_str()
|
.host_str()
|
||||||
.ok_or(format!("invalid url: {}", package_info.url))?
|
.ok_or(format!("invalid url: {}", package_info.url))?
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let dir = get_package_local_dir(
|
let dir = get_package_local_dir(&host, &package_info.package, &package_info.version)?;
|
||||||
&host,
|
|
||||||
&package_info.package,
|
|
||||||
&package_info.version
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let version = package_info.version;
|
let version = package_info.version;
|
||||||
let name = package_info.package;
|
let name = package_info.package;
|
||||||
|
|
||||||
let target_path = download_and_unpack_targz(&package_info.url, &dir)?;
|
let target_path = download_and_unpack_targz(&package_info.url, &dir)?;
|
||||||
|
|
||||||
let wapm_toml = std::fs::read_to_string(target_path.join("wapm.toml"))
|
let wapm_toml = std::fs::read_to_string(target_path.join("wapm.toml")).map_err(|_| {
|
||||||
.map_err(|_| format!("Package {name}@{version} has no wapm.toml (path: {})", target_path.display()))?;
|
format!(
|
||||||
|
"Package {name}@{version} has no wapm.toml (path: {})",
|
||||||
|
target_path.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let wapm_toml = toml::from_str::<wapm_toml::Manifest>(&wapm_toml)
|
let wapm_toml = toml::from_str::<wapm_toml::Manifest>(&wapm_toml)
|
||||||
.map_err(|e| format!("Could not parse toml for {name}@{version}: {e}"))?;
|
.map_err(|e| format!("Could not parse toml for {name}@{version}: {e}"))?;
|
||||||
|
|
||||||
let commands = wapm_toml.command.unwrap_or_default();
|
let commands = wapm_toml.command.unwrap_or_default();
|
||||||
let entrypoint_module = commands.first()
|
let entrypoint_module = commands.first().ok_or(format!(
|
||||||
.ok_or(format!("Cannot run {name}@{version}: package has no commands"))?;
|
"Cannot run {name}@{version}: package has no commands"
|
||||||
|
))?;
|
||||||
|
|
||||||
let module_name = entrypoint_module.get_module();
|
let module_name = entrypoint_module.get_module();
|
||||||
let modules = wapm_toml.module.unwrap_or_default();
|
let modules = wapm_toml.module.unwrap_or_default();
|
||||||
let entrypoint_module = modules
|
let entrypoint_module = modules
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|m| m.name == module_name)
|
.filter(|m| m.name == module_name)
|
||||||
.next()
|
.next()
|
||||||
.ok_or(format!("Cannot run {name}@{version}: module {module_name} not found in wapm.toml"))?;
|
.ok_or(format!(
|
||||||
|
"Cannot run {name}@{version}: module {module_name} not found in wapm.toml"
|
||||||
|
))?;
|
||||||
|
|
||||||
Ok(target_path.join(&entrypoint_module.source))
|
Ok(target_path.join(&entrypoint_module.source))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_if_registry_present(registry: &str) -> Result<bool, String> {
|
pub fn test_if_registry_present(registry: &str) -> Result<bool, String> {
|
||||||
|
use crate::graphql::{test_if_registry_present, TestIfRegistryPresent};
|
||||||
use graphql_client::GraphQLQuery;
|
use graphql_client::GraphQLQuery;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use crate::graphql::{TestIfRegistryPresent, test_if_registry_present};
|
|
||||||
|
|
||||||
let q = TestIfRegistryPresent::build_query(test_if_registry_present::Variables {});
|
let q = TestIfRegistryPresent::build_query(test_if_registry_present::Variables {});
|
||||||
let _ = crate::graphql::execute_query_modifier_inner_check_json(
|
let _ = crate::graphql::execute_query_modifier_inner_check_json(
|
||||||
@@ -771,8 +797,9 @@ pub fn test_if_registry_present(registry: &str) -> Result<bool, String> {
|
|||||||
"",
|
"",
|
||||||
&q,
|
&q,
|
||||||
Some(Duration::from_secs(1)),
|
Some(Duration::from_secs(1)),
|
||||||
|f| f
|
|f| f,
|
||||||
).map_err(|e| format!("{e}"))?;
|
)
|
||||||
|
.map_err(|e| format!("{e}"))?;
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@@ -783,7 +810,7 @@ pub fn get_all_available_registries() -> Result<Vec<String>, String> {
|
|||||||
match config.registry {
|
match config.registry {
|
||||||
Registries::Single(s) => {
|
Registries::Single(s) => {
|
||||||
registries.push(format_graphql(&s.url));
|
registries.push(format_graphql(&s.url));
|
||||||
},
|
}
|
||||||
Registries::Multi(m) => {
|
Registries::Multi(m) => {
|
||||||
for key in m.tokens.keys() {
|
for key in m.tokens.keys() {
|
||||||
registries.push(format_graphql(&key));
|
registries.push(format_graphql(&key));
|
||||||
|
|||||||
Reference in New Issue
Block a user