Skip to content

Commit

Permalink
The info command can now be formatted as json
Browse files Browse the repository at this point in the history
  • Loading branch information
chevdor committed May 11, 2021
1 parent a6e6425 commit 2f558de
Show file tree
Hide file tree
Showing 19 changed files with 222 additions and 186 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

34 changes: 13 additions & 21 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,40 @@ use opts::*;
use subwasmlib::*;
use wasm_testbed::*;

/// Simple macro that only execute $statement if $opts don#t contain neither the quiet nor the json flag
macro_rules! noquiet {
( $q:expr, $x:expr ) => {{
if !$q {
$x
( $opts:ident, $statement:expr ) => {{
if !$opts.quiet && !$opts.json {
$statement
}
}};
}

/// Main entry point of the `subwasm` cli.
/// Main entry point of the `subwasm` cli
fn main() -> color_eyre::Result<()> {
let opts: Opts = Opts::parse();

match opts.subcmd {
SubCommand::Get(get_opts) => {
noquiet!(opts.quiet, println!("Running {} v{}", crate_name!(), crate_version!()));
noquiet!(opts, println!("Running {} v{}", crate_name!(), crate_version!()));
let chain_name = get_opts.chain.map(|some| some.name);
let url = &get_url(chain_name.as_deref(), &get_opts.url);

download_runtime(url, get_opts.block, get_opts.output)?;
}

SubCommand::Info(info_opts) => {
noquiet!(opts.quiet, println!("Running {} v{}", crate_name!(), crate_version!()));
noquiet!(opts, println!("Running {} v{}", crate_name!(), crate_version!()));

let chain_name = info_opts.chain.map(|some| some.name);
let source = get_source(chain_name.as_deref(), info_opts.source);

noquiet!(opts, println!("⏱️ Loading WASM from {:?}", &source));
let subwasm = Subwasm::new(&source);
// let infos = subwasm.get_infos(); // good for json...
// subwasm.print_infos();

match info_opts.details_level {
0 => {
// println!(
// "Version {:?} {} supported.",
// runtime.metadata_version(),
// if runtime.is_supported() { "is" } else { "is NOT" }
// );
// display_infos(runtime.runtime_metadata_prefixed())?;
subwasm.print_runtime_infos();
}
_ => {
subwasm.display_modules_list()?;
}
0 => subwasm.runtime_info().print(opts.json),
_ => subwasm.print_modules_list()?,
}
}

Expand All @@ -56,7 +48,7 @@ fn main() -> color_eyre::Result<()> {
}

SubCommand::Diff(diff_opts) => {
noquiet!(opts.quiet, println!("Running {} v{}", crate_name!(), crate_version!()));
noquiet!(opts, println!("Running {} v{}", crate_name!(), crate_version!()));

diff(diff_opts.a, diff_opts.b);
}
Expand Down
6 changes: 3 additions & 3 deletions cli/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use wasm_loader::{OnchainBlock, Source};
#[clap(version = crate_version!(), author = crate_authors!())]
#[clap(setting = AppSettings::ColoredHelp)]
pub struct Opts {
/// A level of verbosity, and can be used multiple times
#[clap(short, long, parse(from_occurrences))]
pub _verbose: i32,
/// Whether we output json or something for 'humans'
#[clap(short, long)]
pub json: bool,

/// Less output
#[clap(short, long)]
Expand Down
4 changes: 2 additions & 2 deletions doc/usage.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
subwasm 0.4.0
subwasm 0.5.0
chevdor <chevdor@gmail.com>:Wilfried Kopp <wilfried@parity.io
You can find all available commands below

Expand All @@ -7,8 +7,8 @@ USAGE:

FLAGS:
-h, --help Prints help information
-j, --json Whether we output json or something for 'humans'
-q, --quiet Less output
-v, --verbose A level of verbosity, and can be used multiple times
-V, --version Prints version information

SUBCOMMANDS:
Expand Down
12 changes: 6 additions & 6 deletions doc/usage_diff.adoc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
subwasm-diff 0.4.0
subwasm-diff 0.5.0
chevdor <chevdor@gmail.com>:Wilfried Kopp <wilfried@parity.io
Compare 2 runtimes

USAGE:
subwasm diff --a <a> --b <b>
subwasm diff <a> <b>

ARGS:
<a> The first source
<b> The second source

FLAGS:
-h, --help Prints help information
-V, --version Prints version information

OPTIONS:
-a, --a <a> The first source
-b, --b <b> The second source
10 changes: 6 additions & 4 deletions doc/usage_get.adoc
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
subwasm-get 0.4.0
subwasm-get 0.5.0
chevdor <chevdor@gmail.com>:Wilfried Kopp <wilfried@parity.io
Get/Download the runtime wasm from a running node through rpc

USAGE:
subwasm get [OPTIONS]
subwasm get [OPTIONS] [url]

ARGS:
<url> The node url. Example: ws://localhost:9944 or http://localhost:9933 [default:
http://localhost:9933]

FLAGS:
-h, --help Prints help information
Expand All @@ -22,5 +26,3 @@ OPTIONS:
on a counter: runtime_NNN.wasm where NNN is incrementing to make sure
you do not override previous runtime. If you specify an existing file
as output, it will be overwritten
-u, --url <url> The node url. Example: ws://localhost:9944 or http://localhost:9933
[default: http://localhost:9933]
18 changes: 10 additions & 8 deletions doc/usage_info.adoc
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
subwasm-info 0.4.0
subwasm-info 0.5.0
chevdor <chevdor@gmail.com>:Wilfried Kopp <wilfried@parity.io
The `info` command returns summarized information about a runtime

USAGE:
subwasm info [FLAGS] [OPTIONS]
subwasm info [FLAGS] [OPTIONS] [source]

ARGS:
<source> The wasm file to load. It can be a path on your local filesystem such as
/tmp/runtime.wasm or a node url such as http://localhost:9933 or
ws://localhost:9944 [default: runtime_000.wasm]

FLAGS:
-d, --details-level Shows the list of modules if you provide `-d`
-h, --help Prints help information
-V, --version Prints version information

OPTIONS:
--chain <chain> Provide the name of a chain and a random url amongst a list of known
nodes will be used. If you pass a valid --chain, --url will be ignored
--chain local = http://localhost:9933
-s, --source <source> The wasm file to load. It can be a path on your local filesystem such
as /tmp/runtime.wasm or a node url such as http://localhost:9933 or
ws://localhost:9944 [default: runtime_000.wasm]
--chain <chain> Provide the name of a chain and a random url amongst a list of known
nodes will be used. If you pass a valid --chain, --url will be ignored
--chain local = http://localhost:9933
14 changes: 7 additions & 7 deletions doc/usage_meta.adoc
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
subwasm-metadata 0.4.0
subwasm-metadata 0.5.0
chevdor <chevdor@gmail.com>:Wilfried Kopp <wilfried@parity.io
Returns the metadata as a json object. You may also use the "meta" alias

USAGE:
subwasm metadata [OPTIONS]
subwasm metadata [source]

ARGS:
<source> The wasm file to load. It can be a path on your local filesystem such as
/tmp/runtime.wasm or a node url such as http://localhost:9933 or
ws://localhost:9944 [default: runtime_000.wasm]

FLAGS:
-h, --help Prints help information
-V, --version Prints version information

OPTIONS:
-s, --source <source> The wasm file to load. It can be a path on your local filesystem such
as /tmp/runtime.wasm or a node url such as http://localhost:9933 or
ws://localhost:9944 [default: runtime_000.wasm]
Binary file removed doc/wa.png
Binary file not shown.
3 changes: 2 additions & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ color-eyre = "0.5.11"
frame-metadata = {package = "frame-metadata", git = "https://github.com/paritytech/frame-metadata", branch = "main"}
num-format = "0.4.0"
rand = "0.8.3"
serde_json = "1.0.61"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.64"
wasm-loader = {path = "../libs/wasm-loader"}
wasm-testbed = {path = "../libs/wasm-testbed"}
6 changes: 3 additions & 3 deletions lib/src/chain_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl ChainInfo {
pub fn get_random_url(&self, filter: Option<EndpointType>) -> Option<String> {
let endpoints = &self.endpoints;
let filtered = endpoints
.into_iter()
.iter()
.filter(|&ep| //true,
if let Some(endpoint_type) = &filter {
endpoint_type == ep
Expand Down Expand Up @@ -75,9 +75,9 @@ impl FromStr for ChainInfo {
.map(|s| s.into_iter().map(|s| NodeEndpoint::from_str(s).expect("Valid chain name")).collect());

if let Some(endpoints) = urls {
Ok(Self { name: name.to_string(), endpoints })
Ok(Self { name, endpoints })
} else {
Err(Error::ChainUsupported(name.to_string()))
Err(Error::ChainUsupported(name))
}
}
}
Expand Down
56 changes: 12 additions & 44 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use calm_io::stdoutln;
use color_eyre::eyre;
use frame_metadata::{v12, RuntimeMetadata, RuntimeMetadataPrefixed}; // TODO checkout v13
use num_format::{Locale, ToFormattedString};
use wasm_testbed::WasmTestBed;
// use rand::seq::SliceRandom;
use std::path::Path;
use std::{fs::File, path::PathBuf};
use std::{io::prelude::*, str::FromStr};
use wasm_loader::{BlockRef, NodeEndpoint, OnchainBlock, Source};
use wasm_testbed::WasmTestBed;

// use crate::error::Error;
mod chain_info;
mod error;
mod runtime_info;
mod subwasm;
pub use chain_info::*;
pub use runtime_info::*;
pub use subwasm::*;

/// Prints magic and version from a raw buffer
Expand Down Expand Up @@ -108,31 +108,8 @@ pub fn display_raw_metadata(metadata: &RuntimeMetadata) -> color_eyre::Result<()
Ok(())
}

// TODO: remove all of that and take it from ChainInfo
// fn get_chain_url(chain: &str) -> Result<String, Error> {
// let urls = match chain {
// "polkadot" => Some(vec![
// "wss://rpc.polkadot.io",
// "wss://polkadot.api.onfinality.io/public-ws",
// "wss://polkadot.elara.patract.io",
// ]),
// "kusama" => Some(vec!["wss://kusama-rpc.polkadot.io"]),
// "westend" => Some(vec!["wss://westend-rpc.polkadot.io"]),
// "rococo" => Some(vec!["wss://rococo-rpc.polkadot.io"]),
// "local" => Some(vec!["http://localhost:9933"]),
// _ => None,
// };

// if let Some(urls) = urls {
// let url = urls.choose(&mut rand::thread_rng()).ok_or(error::Error::Generic).unwrap();
// Ok(String::from(*url))
// } else {
// Err(error::Error::Generic)
// }
// }

/// Returns Some node url if possible, None otherwise.
pub fn get_node_url(chain: Option<&str>) -> Option<String> {
fn get_node_url(chain: Option<&str>) -> Option<String> {
if let Some(chain) = chain {
let chain_info = ChainInfo::from_str(chain).expect("Unknown chain");

Expand Down Expand Up @@ -181,7 +158,12 @@ pub fn download_runtime(url: &str, block_ref: Option<BlockRef>, output: Option<P
};

let reference = OnchainBlock { endpoint: url, block_ref };
let wasm = wasm_loader::WasmLoader::fetch_wasm(&reference).expect("Getting wasm from the node");
// let wasm = wasm_loader::WasmLoader::fetch_wasm(&reference).expect("Getting wasm from the node");

let loader =
wasm_loader::WasmLoader::load_from_source(&Source::Chain(reference)).expect("Getting wasm from the node");
let wasm = loader.bytes();

println!("Got the runtime, its size is {:?}", wasm.len());

let outfile = match output {
Expand Down Expand Up @@ -210,8 +192,6 @@ pub fn download_runtime(url: &str, block_ref: Option<BlockRef>, output: Option<P
Ok(())
}



/// Compare 2 runtimes. It compares their versions first
/// then their metata.
pub fn diff(src_a: Source, src_b: Source) {
Expand Down Expand Up @@ -253,8 +233,8 @@ pub fn diff(src_a: Source, src_b: Source) {

// CORE VERSIONS
println!("Checking core versions:");
let version_a = runtime_a.core_version().as_ref().expect("Some version");
let version_b = runtime_b.core_version().as_ref().expect("Some version");
let version_a = runtime_a.core_version().expect("Some version");
let version_b = runtime_b.core_version().expect("Some version");

if version_a == version_b {
print!(" ✅ The 2 core versions are identical: ");
Expand All @@ -278,15 +258,3 @@ pub fn diff(src_a: Source, src_b: Source) {
println!(" ❌ The metadata are different");
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_gets_chain_urls() {
assert!(get_chain_url("local").is_ok());
assert!(get_chain_url("polkadot").is_ok());
assert!(get_chain_url("foobar").is_err());
}
}
50 changes: 50 additions & 0 deletions lib/src/runtime_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::fmt::Display;

use num_format::{Locale, ToFormattedString};
use serde::Serialize;
use wasm_testbed::WasmTestBed;

#[derive(Debug, Serialize)]
pub struct RuntimeInfo {
size: usize,
metadata_version: u8,
core_version: String,
proposal_hash: String,
}

impl RuntimeInfo {
pub fn new(testbed: &WasmTestBed) -> Self {
let core_version = match testbed.core_version() {
Some(v) => v.to_string(),
None => String::from("n/a"),
};

Self {
size: testbed.size(),
metadata_version: *testbed.metadata_version(),
core_version,
proposal_hash: testbed.proposal_hash(),
}
}

/// Print the RuntimeInfo either using the Display impl
/// or serde as json.
pub fn print(&self, json: bool) {
if json {
let serialized = serde_json::to_string_pretty(self).unwrap();
println!("{}", serialized);
} else {
println!("{}", self);
}
}
}

impl Display for RuntimeInfo {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let size_mb: f64 = self.size as f64 / 1024.0 / 1024.0;
writeln!(fmt, "🏋️ Runtime Size:\t{:.3?} MB ({} bytes)", size_mb, self.size.to_formatted_string(&Locale::en))?;
writeln!(fmt, "🎁 Metadata version:\tV{:?}", self.metadata_version)?;
writeln!(fmt, "🔥 Core version:\t{}", self.core_version)?;
writeln!(fmt, "🗳️ Proposal hash:\t{}", self.proposal_hash)
}
}
Loading

0 comments on commit 2f558de

Please sign in to comment.