Skip to content
Snippets Groups Projects
Commit 7e59eb0a authored by Hugo Trentesaux's avatar Hugo Trentesaux Committed by Hugo Trentesaux
Browse files

add runtime events doc

parent bc11fb2c
No related branches found
No related tags found
1 merge request!202add runtime events doc
......@@ -359,7 +359,7 @@ ask to join the set of validators two sessions after
<details><summary><code>set_session_keys(keys)</code></summary>
```rust
keys: T::KeysWrapper
keys: T::Keys
```
</details>
......@@ -750,8 +750,11 @@ Link an account to an identity
</details>
claim pending membership to become actual memberhip
the requested membership must fullfill requirements
claim membership
a pending membership should exist
it must fullfill the requirements (certs, distance)
for main wot claim_membership is called automatically when validating identity
for smith wot, it means joining the authority members
#### renew_membership - 2
......@@ -844,10 +847,9 @@ Removes the status if `status` is `None`.
#### request_membership - 0
<details><summary><code>request_membership(metadata)</code></summary>
<details><summary><code>request_membership()</code></summary>
```rust
metadata: T::MetaData
```
</details>
......@@ -864,8 +866,11 @@ submit a membership request (must have a declared identity)
</details>
claim pending membership to become actual memberhip
the requested membership must fullfill requirements
claim membership
a pending membership should exist
it must fullfill the requirements (certs, distance)
for main wot claim_membership is called automatically when validating identity
for smith wot, it means joining the authority members
#### renew_membership - 2
......@@ -2003,10 +2008,9 @@ usually means being a stash account).
#### request_membership - 0
<details><summary><code>request_membership(metadata)</code></summary>
<details><summary><code>request_membership()</code></summary>
```rust
metadata: T::MetaData
```
</details>
......
This diff is collapsed.
# Runtime events
There are xxx calls from **{{ pallets | length }}** pallets.
{% for pallet in pallets -%}
### {{ pallet.name }} - {{ pallet.index }}
{% for event in pallet.events -%}
#### {{ event.name }} - {{ event.index }}
<details><summary><code>{{ event.name }}(
{%- for param in event.params -%}
{{ param.name }}{% if loop.last != true %}, {% endif %}
{%- endfor -%}
)</code></summary>
```rust
{% for param in event.params -%}
{{ param.name }}: {{ param.type_name }}
{% endfor -%}
```
</details>
{% endfor -%}
{% endfor -%}
......@@ -27,45 +27,79 @@ use tera::Tera;
// consts
const CALLS_DOC_FILEPATH: &str = "docs/api/runtime-calls.md";
const EVENTS_DOC_FILEPATH: &str = "docs/api/runtime-events.md";
const TEMPLATES_GLOB: &str = "xtask/res/templates/*.md";
// define structs and implementations
type RuntimeCalls = Vec<Pallet>;
type RuntimePallets = Vec<Pallet>;
#[derive(Clone, Serialize)]
struct Pallet {
index: u8,
name: String,
calls: Vec<Call>,
events: Vec<Event>,
}
#[derive(Clone, Serialize)]
struct Call {
documentation: String,
index: u8,
name: String,
params: Vec<CallParam>,
}
#[derive(Clone, Serialize)]
struct CallParam {
name: String,
type_name: String,
}
#[derive(Clone, Serialize)]
struct Event {
documentation: String,
index: u8,
name: String,
params: Vec<EventParam>,
}
#[derive(Clone, Serialize)]
struct EventParam {
name: String,
type_name: String,
}
impl Pallet {
fn new(
index: u8,
name: String,
scale_type_def: &scale_info::TypeDef<PortableForm>,
call_scale_type_def: &Option<scale_info::TypeDef<PortableForm>>,
event_scale_type_def: &Option<scale_info::TypeDef<PortableForm>>,
) -> Result<Self> {
if let scale_info::TypeDef::Variant(calls_enum) = scale_type_def {
let calls = if let Some(call_scale_type_def) = call_scale_type_def {
if let scale_info::TypeDef::Variant(calls_enum) = call_scale_type_def {
calls_enum.variants.iter().map(Into::into).collect()
} else {
bail!("Invalid metadata")
}
} else {
vec![]
};
let events = if let Some(event_scale_type_def) = event_scale_type_def {
if let scale_info::TypeDef::Variant(events_enum) = event_scale_type_def {
events_enum.variants.iter().map(Into::into).collect()
} else {
bail!("Invalid metadata")
}
} else {
vec![]
};
Ok(Self {
index,
name,
calls: calls_enum.variants.iter().map(Into::into).collect(),
calls,
events,
})
} else {
bail!("Invalid metadata")
}
}
}
#[derive(Clone, Serialize)]
struct Call {
documentation: String,
index: u8,
name: String,
params: Vec<CallParam>,
}
impl From<&scale_info::Variant<PortableForm>> for Call {
fn from(variant: &scale_info::Variant<PortableForm>) -> Self {
Self {
......@@ -83,13 +117,27 @@ impl From<&scale_info::Variant<PortableForm>> for Call {
}
}
#[derive(Clone, Serialize)]
struct CallParam {
name: String,
type_name: String,
impl From<&scale_info::Field<PortableForm>> for CallParam {
fn from(field: &scale_info::Field<PortableForm>) -> Self {
Self {
name: field.clone().name.unwrap_or_default(),
type_name: field.clone().type_name.unwrap_or_default(),
}
}
}
impl From<&scale_info::Field<PortableForm>> for CallParam {
impl From<&scale_info::Variant<PortableForm>> for Event {
fn from(variant: &scale_info::Variant<PortableForm>) -> Self {
Self {
documentation: variant.docs.iter().cloned().collect::<Vec<_>>().join("\n"),
index: variant.index,
name: variant.name.to_owned(),
params: variant.fields.iter().map(Into::into).collect(),
}
}
}
impl From<&scale_info::Field<PortableForm>> for EventParam {
fn from(field: &scale_info::Field<PortableForm>) -> Self {
Self {
name: field.clone().name.unwrap_or_default(),
......@@ -149,7 +197,7 @@ impl CallCategory {
}
/// generate runtime calls documentation
pub(super) fn gen_calls_doc() -> Result<()> {
pub(super) fn gen_doc() -> Result<()> {
// Read metadata
let mut file = std::fs::File::open("resources/metadata.scale")
.with_context(|| "Failed to open metadata file")?;
......@@ -163,49 +211,80 @@ pub(super) fn gen_calls_doc() -> Result<()> {
println!("Metadata successfully loaded!");
let runtime_calls = if let frame_metadata::RuntimeMetadata::V14(metadata_v14) = metadata.1 {
get_calls_from_metadata_v14(metadata_v14)?
let runtime = if let frame_metadata::RuntimeMetadata::V14(metadata_v14) = metadata.1 {
get_from_metadata_v14(metadata_v14)?
} else {
bail!("unsuported metadata version")
};
let output = print_runtime_calls(runtime_calls);
let (call_doc, event_doc) = print_runtime(runtime);
let mut file = File::create(CALLS_DOC_FILEPATH)
.with_context(|| format!("Failed to create file '{}'", CALLS_DOC_FILEPATH))?;
file.write_all(output.as_bytes())
file.write_all(call_doc.as_bytes())
.with_context(|| format!("Failed to write to file '{}'", CALLS_DOC_FILEPATH))?;
let mut file = File::create(EVENTS_DOC_FILEPATH)
.with_context(|| format!("Failed to create file '{}'", EVENTS_DOC_FILEPATH))?;
file.write_all(event_doc.as_bytes())
.with_context(|| format!("Failed to write to file '{}'", EVENTS_DOC_FILEPATH))?;
Ok(())
}
fn get_calls_from_metadata_v14(
fn get_from_metadata_v14(
metadata_v14: frame_metadata::v14::RuntimeMetadataV14,
) -> Result<RuntimeCalls> {
) -> Result<RuntimePallets> {
println!("Number of pallets: {}", metadata_v14.pallets.len());
let mut pallets = Vec::new();
for pallet in metadata_v14.pallets {
if let Some(calls) = pallet.calls {
if let Some(calls_type) = metadata_v14.types.resolve(calls.ty.id) {
let pallet = Pallet::new(pallet.index, pallet.name.clone(), &calls_type.type_def)?;
let calls_len = pallet.calls.len();
println!("{}: {} ({} calls)", pallet.index, pallet.name, calls_len);
pallets.push(pallet);
} else {
let calls_type_def = if let Some(calls) = pallet.calls {
let Some(calls_type) = metadata_v14.types.resolve(calls.ty.id) else {
bail!("Invalid metadata")
}
};
Some(calls_type.type_def.clone())
} else {
println!("{}: {} (0 calls)", pallet.index, pallet.name);
}
None
};
let events_type_def = if let Some(events) = pallet.event {
let Some(events_type) = metadata_v14.types.resolve(events.ty.id) else {
bail!("Invalid metadata")
};
Some(events_type.type_def.clone())
} else {
println!("{}: {} (0 events)", pallet.index, pallet.name);
None
};
let pallet = Pallet::new(
pallet.index,
pallet.name.clone(),
&calls_type_def,
&events_type_def,
)?;
println!(
"{}: {} ({} calls)",
pallet.index,
pallet.name,
pallet.calls.len()
);
println!(
"{}: {} ({} events)",
pallet.index,
pallet.name,
pallet.events.len()
);
pallets.push(pallet);
}
Ok(pallets)
}
/// use template to render markdown file with runtime calls documentation
fn print_runtime_calls(pallets: RuntimeCalls) -> String {
fn print_runtime(pallets: RuntimePallets) -> (String, String) {
// init variables
let mut user_calls_counter = 0;
let user_calls_pallets: RuntimeCalls = pallets
let user_calls_pallets: RuntimePallets = pallets
.iter()
.cloned()
.filter_map(|mut pallet| {
......@@ -222,7 +301,7 @@ fn print_runtime_calls(pallets: RuntimeCalls) -> String {
})
.collect();
let mut root_calls_counter = 0;
let root_calls_pallets: RuntimeCalls = pallets
let root_calls_pallets: RuntimePallets = pallets
.iter()
.cloned()
.filter_map(|mut pallet| {
......@@ -239,7 +318,7 @@ fn print_runtime_calls(pallets: RuntimeCalls) -> String {
})
.collect();
let mut disabled_calls_counter = 0;
let disabled_calls_pallets: RuntimeCalls = pallets
let disabled_calls_pallets: RuntimePallets = pallets
.iter()
.cloned()
.filter_map(|mut pallet| {
......@@ -265,7 +344,7 @@ fn print_runtime_calls(pallets: RuntimeCalls) -> String {
}
};
// fills tera context for rendering
// fills tera context for rendering calls
let mut context = tera::Context::new();
context.insert("user_calls_counter", &user_calls_counter);
context.insert("user_calls_pallets", &user_calls_pallets);
......@@ -274,6 +353,16 @@ fn print_runtime_calls(pallets: RuntimeCalls) -> String {
context.insert("disabled_calls_counter", &disabled_calls_counter);
context.insert("disabled_calls_pallets", &disabled_calls_pallets);
tera.render("runtime-calls.md", &context)
.expect("template error")
let call_doc = tera
.render("runtime-calls.md", &context)
.expect("template error");
// render events
context.insert("pallets", &pallets);
let event_doc = tera
.render("runtime-events.md", &context)
.expect("template error");
(call_doc, event_doc)
}
......@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
mod gen_calls_doc;
mod gen_doc;
mod release_runtime;
use anyhow::{Context, Result};
......@@ -38,8 +38,8 @@ enum DuniterXTaskCommand {
#[clap(long)]
production: bool,
},
/// Generate calls documentation
GenCallsDoc,
/// Generate documentation (calls and events)
GenDoc,
/// Inject runtime code in raw specs
InjectRuntimeCode {
#[clap(short, long)]
......@@ -82,7 +82,7 @@ async fn main() -> Result<()> {
match args.command {
DuniterXTaskCommand::Build { production } => build(production),
DuniterXTaskCommand::GenCallsDoc => gen_calls_doc::gen_calls_doc(),
DuniterXTaskCommand::GenDoc => gen_doc::gen_doc(),
DuniterXTaskCommand::InjectRuntimeCode { runtime, raw_spec } => {
inject_runtime_code(&raw_spec, &runtime)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment