zinkc/
cli.rs

1//! Zink compiler command line interface.
2#![cfg(feature = "cli")]
3
4use crate::{Compiler, Config};
5use ccli::{clap, Parser};
6use std::{env, fs, path::PathBuf};
7
8/// Compile WASM to EVM bytecode.
9#[derive(Debug, Parser)]
10#[command(name = "zinkc")]
11pub struct Compile {
12    /// Write ABI to disk.
13    #[clap(short, long)]
14    abi: bool,
15    /// The path of the wasm file.
16    #[clap(value_name = "INPUT")]
17    input: PathBuf,
18    /// Write output to <filename>
19    #[clap(short, long)]
20    output: Option<PathBuf>,
21    /// If enable dispatcher.
22    #[clap(short, long)]
23    dispatcher: bool,
24}
25
26impl Compile {
27    /// Run compile.
28    pub fn run(&self) -> anyhow::Result<()> {
29        let output = if let Some(output) = self.output.as_ref() {
30            output.into()
31        } else {
32            env::current_dir()?.join(self.input.with_extension(""))
33        };
34
35        let compiler = Compiler::new(Config::default().dispatcher(self.dispatcher));
36        let artifact = compiler.compile(&fs::read(&self.input)?)?;
37
38        output.parent().map(fs::create_dir_all);
39        fs::write(&output, artifact.runtime_bytecode)?;
40
41        if !self.abi {
42            return Ok(());
43        }
44
45        let abi = output
46            .parent()
47            .ok_or_else(|| anyhow::anyhow!("invalid output path: {output:?}"))?
48            .join(
49                output
50                    .file_name()
51                    .ok_or_else(|| anyhow::anyhow!("invalid file name: {output:?}"))?,
52            )
53            .with_extension("abi.json");
54
55        fs::write(abi, serde_json::to_string_pretty(&artifact.abi)?)?;
56        Ok(())
57    }
58}