Skip to content

Commit

Permalink
Merge pull request #3428 from wasmerio/config
Browse files Browse the repository at this point in the history
Implement wasmer config
  • Loading branch information
fschutt authored Dec 22, 2022
2 parents d5adde8 + aa04d58 commit c1b8f20
Show file tree
Hide file tree
Showing 17 changed files with 681 additions and 165 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ wasmer-wasi-experimental-io-devices = { version = "=3.1.0", path = "../wasi-expe
wasmer-wast = { version = "=3.1.0", path = "../../tests/lib/wast", optional = true }
wasmer-cache = { version = "=3.1.0", path = "../cache", optional = true }
wasmer-types = { version = "=3.1.0", path = "../types" }
wasmer-registry = { version = "=3.1.0", path = "../registry" }
wasmer-registry = { version = "=4.0.0", path = "../registry" }
wasmer-object = { version = "=3.1.0", path = "../object", optional = true }
wasmer-vfs = { version = "=3.1.0", path = "../vfs", default-features = false, features = ["host-fs"] }
wasmer-wasm-interface = { version = "3.1.0", path = "../wasm-interface" }
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/src/commands/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::process::{Command, Stdio};

use anyhow::{Context, Error};
use clap::Parser;
use wasmer_registry::{Bindings, PartialWapmConfig, ProgrammingLanguage};
use wasmer_registry::{Bindings, ProgrammingLanguage, WasmerConfig};

/// Add a WAPM package's bindings to your application.
#[derive(Debug, Parser)]
Expand Down Expand Up @@ -77,8 +77,8 @@ impl Add {
Some(r) => Ok(r.clone()),
None => {
let wasmer_dir =
PartialWapmConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("{e}"))?;
let cfg = PartialWapmConfig::from_file(&wasmer_dir)
WasmerConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("{e}"))?;
let cfg = WasmerConfig::from_file(&wasmer_dir)
.map_err(Error::msg)
.context("Unable to load WAPM's config file")?;
Ok(cfg.registry.get_current_registry())
Expand Down
232 changes: 223 additions & 9 deletions lib/cli/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ use anyhow::{Context, Result};
use clap::Parser;
use std::env;
use std::path::PathBuf;
use std::str::ParseBoolError;
use wasmer_registry::WasmerConfig;

#[derive(Debug, Parser)]
/// The options for the `wasmer config` subcommand
/// The options for the `wasmer config` subcommand: `wasmer config get --OPTION` or `wasmer config set [FLAG]`
pub struct Config {
#[clap(flatten)]
flags: Flags,
/// Subcommand for `wasmer config get | set`
#[clap(subcommand)]
set: Option<GetOrSet>,
}

/// Normal configuration
#[derive(Debug, Parser)]
pub struct Flags {
/// Print the installation prefix.
#[clap(long, conflicts_with = "pkg-config")]
prefix: bool,
Expand All @@ -31,19 +43,131 @@ pub struct Config {
#[clap(long, conflicts_with = "pkg-config")]
cflags: bool,

/// It outputs the necessary details for compiling
/// Print the path to the wasmer configuration file where all settings are stored
#[clap(long, conflicts_with = "pkg-config")]
config_path: bool,

/// Outputs the necessary details for compiling
/// and linking a program to Wasmer, using the `pkg-config` format.
#[clap(long)]
pkg_config: bool,
}

/// Subcommand for `wasmer config set`
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub enum GetOrSet {
/// `wasmer config get $KEY`
#[clap(subcommand)]
Get(RetrievableConfigField),
/// `wasmer config set $KEY $VALUE`
#[clap(subcommand)]
Set(StorableConfigField),
}

/// Subcommand for `wasmer config get`
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub enum RetrievableConfigField {
/// Print the registry URL of the currently active registry
#[clap(name = "registry.url")]
RegistryUrl,
/// Print the token for the currently active registry or nothing if not logged in
#[clap(name = "registry.token")]
RegistryToken,
/// Print whether telemetry is currently enabled
#[clap(name = "telemetry.enabled")]
TelemetryEnabled,
/// Print whether update notifications are enabled
#[clap(name = "update-notifications.enabled")]
UpdateNotificationsEnabled,
/// Print the proxy URL
#[clap(name = "proxy.url")]
ProxyUrl,
}

/// Setting that can be stored in the wasmer config
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub enum StorableConfigField {
/// Set the registry URL of the currently active registry
#[clap(name = "registry.url")]
RegistryUrl(SetRegistryUrl),
/// Set the token for the currently active registry or nothing if not logged in
#[clap(name = "registry.token")]
RegistryToken(SetRegistryToken),
/// Set whether telemetry is currently enabled
#[clap(name = "telemetry.enabled")]
TelemetryEnabled(SetTelemetryEnabled),
/// Set whether update notifications are enabled
#[clap(name = "update-notifications.enabled")]
UpdateNotificationsEnabled(SetUpdateNotificationsEnabled),
/// Set the active proxy URL
#[clap(name = "proxy.url")]
ProxyUrl(SetProxyUrl),
}

/// Set the current active registry URL
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub struct SetRegistryUrl {
/// Url of the registry
#[clap(name = "URL")]
pub url: String,
}

/// Set or change the token for the current active registry
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub struct SetRegistryToken {
/// Token to set
#[clap(name = "TOKEN")]
pub token: String,
}

/// Set if update notifications are enabled
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub struct SetUpdateNotificationsEnabled {
/// Whether to enable update notifications
#[clap(name = "ENABLED", possible_values = ["true", "false"])]
pub enabled: BoolString,
}

/// "true" or "false" for handling input in the CLI
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BoolString(pub bool);

impl std::str::FromStr for BoolString {
type Err = ParseBoolError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(bool::from_str(s)?))
}
}

/// Set if telemetry is enabled
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub struct SetTelemetryEnabled {
/// Whether to enable telemetry
#[clap(name = "ENABLED", possible_values = ["true", "false"])]
pub enabled: BoolString,
}

/// Set if a proxy URL should be used
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Parser)]
pub struct SetProxyUrl {
/// Set if a proxy URL should be used (empty = unset proxy)
#[clap(name = "URL")]
pub url: String,
}

impl Config {
/// Runs logic for the `config` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute()
.context("failed to retrieve the wasmer config".to_string())
}
fn inner_execute(&self) -> Result<()> {
if let Some(s) = self.set.as_ref() {
return s.execute();
}

let flags = &self.flags;

let key = "WASMER_DIR";
let wasmer_dir = env::var(key)
.or_else(|e| {
Expand All @@ -65,7 +189,7 @@ impl Config {
let cflags = format!("-I{}", includedir);
let libs = format!("-L{} -lwasmer", libdir);

if self.pkg_config {
if flags.pkg_config {
println!("prefix={}", prefixdir);
println!("exec_prefix={}", bindir);
println!("includedir={}", includedir);
Expand All @@ -79,24 +203,114 @@ impl Config {
return Ok(());
}

if self.prefix {
if flags.prefix {
println!("{}", prefixdir);
}
if self.bindir {
if flags.bindir {
println!("{}", bindir);
}
if self.includedir {
if flags.includedir {
println!("{}", includedir);
}
if self.libdir {
if flags.libdir {
println!("{}", libdir);
}
if self.libs {
if flags.libs {
println!("{}", libs);
}
if self.cflags {
if flags.cflags {
println!("{}", cflags);
}

if flags.config_path {
let wasmer_dir = WasmerConfig::get_wasmer_dir()
.map_err(|e| anyhow::anyhow!("could not find wasmer dir: {e}"))?;
let path = WasmerConfig::get_file_location(&wasmer_dir);
println!("{}", path.display());
}

Ok(())
}
}

impl GetOrSet {
fn execute(&self) -> Result<()> {
let wasmer_dir = WasmerConfig::get_wasmer_dir()
.map_err(|e| anyhow::anyhow!("could not find wasmer dir: {e}"))?;
let config_file = WasmerConfig::get_file_location(&wasmer_dir);
let mut config = WasmerConfig::from_file(&wasmer_dir).map_err(|e| {
anyhow::anyhow!(
"could not find config file {e} at {}",
config_file.display()
)
})?;
match self {
GetOrSet::Get(g) => match g {
RetrievableConfigField::RegistryUrl => {
println!("{}", config.registry.get_current_registry());
}
RetrievableConfigField::RegistryToken => {
if let Some(s) = config
.registry
.get_login_token_for_registry(&config.registry.get_current_registry())
{
println!("{s}");
}
}
RetrievableConfigField::TelemetryEnabled => {
println!("{:?}", config.telemetry_enabled);
}
RetrievableConfigField::UpdateNotificationsEnabled => {
println!("{:?}", config.update_notifications_enabled);
}
RetrievableConfigField::ProxyUrl => {
if let Some(s) = config.proxy.url.as_ref() {
println!("{s}");
} else {
println!("none");
}
}
},
GetOrSet::Set(s) => {
match s {
StorableConfigField::RegistryUrl(s) => {
config.registry.set_current_registry(&s.url);
let current_registry = config.registry.get_current_registry();
if let Some(u) = wasmer_registry::utils::get_username(&current_registry)
.ok()
.and_then(|o| o)
{
println!(
"Successfully logged into registry {current_registry:?} as user {u:?}"
);
}
}
StorableConfigField::RegistryToken(t) => {
config.registry.set_login_token_for_registry(
&config.registry.get_current_registry(),
&t.token,
wasmer_registry::config::UpdateRegistry::LeaveAsIs,
);
}
StorableConfigField::TelemetryEnabled(t) => {
config.telemetry_enabled = t.enabled.0;
}
StorableConfigField::ProxyUrl(p) => {
if p.url == "none" || p.url.is_empty() {
config.proxy.url = None;
} else {
config.proxy.url = Some(p.url.clone());
}
}
StorableConfigField::UpdateNotificationsEnabled(u) => {
config.update_notifications_enabled = u.enabled.0;
}
}
config
.save(config_file)
.with_context(|| anyhow::anyhow!("could not save config file"))?;
}
}
Ok(())
}
}
4 changes: 2 additions & 2 deletions lib/cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use clap::Parser;
use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
use wasmer_registry::PartialWapmConfig;
use wasmer_registry::WasmerConfig;

static NOTE: &str =
"# See more keys and definitions at https://docs.wasmer.io/ecosystem/wapm/manifest";
Expand Down Expand Up @@ -365,7 +365,7 @@ fn construct_manifest(
.map(|p| &p.name)
.unwrap_or(fallback_package_name)
});
let wasmer_dir = PartialWapmConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("{e}"))?;
let wasmer_dir = WasmerConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("{e}"))?;
let namespace = namespace.or_else(|| {
wasmer_registry::whoami(&wasmer_dir, None, None)
.ok()
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/src/commands/list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clap::Parser;
use wasmer_registry::PartialWapmConfig;
use wasmer_registry::WasmerConfig;

/// Subcommand for listing packages
#[derive(Debug, Copy, Clone, Parser)]
Expand All @@ -9,8 +9,8 @@ impl List {
/// execute [List]
pub fn execute(&self) -> Result<(), anyhow::Error> {
use prettytable::{format, row, Table};
let wasmer_dir = PartialWapmConfig::get_wasmer_dir()
.map_err(|e| anyhow::anyhow!("no wasmer dir: {e}"))?;
let wasmer_dir =
WasmerConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("no wasmer dir: {e}"))?;
let rows = wasmer_registry::get_all_local_packages(&wasmer_dir)
.into_iter()
.filter_map(|pkg| {
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/src/commands/login.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clap::Parser;
#[cfg(not(test))]
use dialoguer::Input;
use wasmer_registry::PartialWapmConfig;
use wasmer_registry::WasmerConfig;

/// Subcommand for listing packages
#[derive(Debug, Clone, Parser)]
Expand Down Expand Up @@ -52,8 +52,8 @@ impl Login {
/// execute [List]
pub fn execute(&self) -> Result<(), anyhow::Error> {
let token = self.get_token_or_ask_user()?;
let wasmer_dir = PartialWapmConfig::get_wasmer_dir()
.map_err(|e| anyhow::anyhow!("no wasmer dir: {e}"))?;
let wasmer_dir =
WasmerConfig::get_wasmer_dir().map_err(|e| anyhow::anyhow!("no wasmer dir: {e}"))?;
match wasmer_registry::login::login_and_save_token(&wasmer_dir, &self.registry, &token)? {
Some(s) => println!("Login for WAPM user {:?} saved", s),
None => println!(
Expand Down
Loading

0 comments on commit c1b8f20

Please sign in to comment.