cargo fmt

This commit is contained in:
Felix Schütt
2022-10-06 12:00:21 +02:00
parent 374494ef3c
commit efdb1f4e76
2 changed files with 217 additions and 184 deletions

View File

@@ -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(());

View File

@@ -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(&registry) { let root_dir = match get_global_install_dir(&registry) {
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));