Skip to content

Commit

Permalink
feat: candid-extractor supports --version (#485)
Browse files Browse the repository at this point in the history
* bump rust to v1.75.0 (same as sdk repo)

* bump wasmtime to 19 and cargo update

* add clap dependency

* submodule extract

* clap for --version and --help/-h

* add changelog and bump to 0.1.3

* clippy from recent rust has a false positive

* e2e test
  • Loading branch information
lwshang authored Apr 22, 2024
1 parent 2abc860 commit 8620c0e
Show file tree
Hide file tree
Showing 9 changed files with 729 additions and 570 deletions.
1,150 changes: 629 additions & 521 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = "https://github.com/dfinity/cdk-rs"
# MSRV
# Avoid updating this field unless we use new Rust features
# Sync with rust-toolchain.toml
rust-version = "1.70.0"
rust-version = "1.75.0"
license = "Apache-2.0"

[profile.canister-release]
Expand Down
11 changes: 11 additions & 0 deletions examples/print/tests/basic.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ teardown() {
run dfx canister call print print
assert_success
}

@test "candid-extractor supports version and help" {
run candid-extractor --version
assert_success
run candid-extractor -V
assert_success
run candid-extractor --help
assert_success
run candid-extractor -h
assert_success
}
1 change: 1 addition & 0 deletions library/ic-certified-map/src/rbtree/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ fn test_witness_value_range() {
}

#[test]
#[allow(clippy::map_identity)]
fn test_iter() {
let mut t = TreeOfBytes::new();
let mut v = vec![];
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.70.0" # sync with rust-version in root Cargo.toml
channel = "1.75.0" # sync with rust-version in root Cargo.toml
targets = ["wasm32-unknown-unknown"]
components = ["rustfmt", "clippy"]
30 changes: 30 additions & 0 deletions src/candid-extractor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [unreleased]

## [0.1.3] - 2024-04-22

### Added

- Use `clap` to support `-V`/`--version` and `-h`/`--help`. (#485)

## [0.1.1] - 2023-10-11

### Added

- Includes new system API `cycles_burn128`. (#434)
## [0.1.1] - 2023-09-19

### Added

- Release from the [CI workflow](../../.github/workflows/release-candid-extractor.yml). (#427)

## [0.1.0] - 2023-09-18

### Added

- The first release. (#424)
5 changes: 3 additions & 2 deletions src/candid-extractor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "candid-extractor"
version = "0.1.2"
version = "0.1.3"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand All @@ -14,7 +14,8 @@ include = ["src", "Cargo.toml", "LICENSE", "README.md", "ic_mock.wat"]

[dependencies]
anyhow = "1.0.72"
wasmtime = "12"
wasmtime = "19"
clap = { version = "4", features = ["derive"] }

[dev-dependencies]
quote.workspace = true
Expand Down
38 changes: 38 additions & 0 deletions src/candid-extractor/src/extract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use anyhow::Result;
use std::path::Path;
use wasmtime::*;

static IC0: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/ic_mock.wat"));

pub(crate) fn extract_candid<P>(wasm_path: P) -> Result<String>
where
P: AsRef<Path>,
{
let mut store: Store<()> = Store::<()>::default();

let mut linker = Linker::new(store.engine());
let ic0_module = Module::new(store.engine(), IC0)?;
let ic0 = linker.instantiate(&mut store, &ic0_module)?;
linker.instance(&mut store, "ic0", ic0)?;

let module = Module::from_file(store.engine(), wasm_path)?;
let canister = linker.instantiate(&mut store, &module)?;

let get_candid_pointer =
canister.get_typed_func::<(), i32>(&mut store, "get_candid_pointer")?;
let candid_pointer = get_candid_pointer.call(&mut store, ())?;

let memory = canister
.get_memory(&mut store, "memory")
.ok_or_else(|| anyhow::format_err!("failed to find `memory` export"))?;
let memory_buffer = memory.data(&store);

let mut i = candid_pointer as usize;
let mut str_vec = vec![];
while memory_buffer[i] != 0 {
str_vec.push(memory_buffer[i]);
i += 1;
}
let s = String::from_utf8(str_vec)?;
Ok(s)
}
60 changes: 15 additions & 45 deletions src/candid-extractor/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
use std::path::Path;

use anyhow::{bail, Result};
use wasmtime::*;

static IC0: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/ic_mock.wat"));

fn generate_candid<P>(wasm_path: P) -> Result<String>
where
P: AsRef<Path>,
{
let mut store: Store<()> = Store::<()>::default();

let mut linker = Linker::new(store.engine());
let ic0_module = Module::new(store.engine(), IC0)?;
let ic0 = linker.instantiate(&mut store, &ic0_module)?;
linker.instance(&mut store, "ic0", ic0)?;

let module = Module::from_file(store.engine(), wasm_path)?;
let canister = linker.instantiate(&mut store, &module)?;

let get_candid_pointer =
canister.get_typed_func::<(), i32>(&mut store, "get_candid_pointer")?;
let candid_pointer = get_candid_pointer.call(&mut store, ())?;

let memory = canister
.get_memory(&mut store, "memory")
.ok_or_else(|| anyhow::format_err!("failed to find `memory` export"))?;
let memory_buffer = memory.data(&store);

let mut i = candid_pointer as usize;
let mut str_vec = vec![];
while memory_buffer[i] != 0 {
str_vec.push(memory_buffer[i]);
i += 1;
}
let s = String::from_utf8(str_vec)?;
Ok(s)
use anyhow::Result;
use clap::Parser;
use std::path::PathBuf;

mod extract;

/// Extract the Candid interface from a Canister WASM file.
#[derive(Parser)]
#[command(version, about)]
struct Cli {
/// Path to the Canister WASM file.
path: PathBuf,
}

fn main() -> Result<()> {
let args: Vec<_> = std::env::args().collect();
if args.len() != 2 {
// The first arg will the name of current binary.
bail!("Expecting one argument: path to the canister WASM file");
}
let c = generate_candid(args.last().unwrap())?;
println!("{c}");
let cli = Cli::parse();
let candid = extract::extract_candid(cli.path)?;
println!("{candid}");
Ok(())
}

0 comments on commit 8620c0e

Please sign in to comment.