Commit fe093478 authored by Andrew Jones's avatar Andrew Jones Committed by Hero Bird
Browse files

[cli] add generate-abi command (#209)

* [cli] add flag to `build` command to generate abi

* [cli] fix abi console output

* [cli] restore +nightly

* [cli] separate generate-abi command

* [cli] move nightly check to exec_cargo fn

* [cli] add test for generate_abi
parent c7411dac
Pipeline #56402 failed with stages
in 21 seconds
// Copyright 2018-2019 Parity Technologies (UK) Ltd.
// This file is part of ink!.
//
// ink! is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ink! is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ink!. If not, see <http://www.gnu.org/licenses/>.
use crate::cmd::{
Result,
};
use cargo_metadata::MetadataCommand;
use std::path::PathBuf;
/// Executes build of the smart-contract which produces a wasm binary that is ready for deploying.
///
/// It does so by invoking build by cargo and then post processing the final binary.
pub(crate) fn execute_generate_abi(dir: Option<&PathBuf>) -> Result<String> {
println!(" Generating abi");
super::exec_cargo("run", &[
"--package",
"abi-gen",
"--verbose",
], dir)?;
let metadata = MetadataCommand::new().exec()?;
let mut abi_path = metadata.target_directory.clone();
abi_path.push("abi.json");
Ok(format!(
"Your abi file is ready.\nYou can find it here:\n{}",
abi_path.display()
))
}
#[cfg(test)]
mod tests {
use crate::{
cmd::{
execute_new,
execute_generate_abi,
tests::with_tmp_dir,
},
AbstractionLayer,
};
#[test]
fn generate_abi() {
with_tmp_dir(|path| {
execute_new(AbstractionLayer::Lang, "new_project", Some(path))
.expect("new project creation failed");
let working_dir = path.join("new_project");
super::execute_generate_abi(Some(&working_dir)).expect("generate abi failed");
let mut abi_file = working_dir.clone();
abi_file.push("target");
abi_file.push("abi.json");
assert!(abi_file.exists())
});
}
}
......@@ -25,14 +25,7 @@ use parity_wasm::elements::{
Module,
Section,
};
use std::{
io::{
self,
Write,
},
path::PathBuf,
process::Command,
};
use std::path::PathBuf;
/// This is the maximum number of pages available for a contract to allocate.
const MAX_MEMORY_PAGES: u32 = 16;
......@@ -96,43 +89,12 @@ pub fn collect_crate_metadata(working_dir: Option<&PathBuf>) -> Result<CrateMeta
///
/// Currently it assumes that user wants to use `+nightly`.
fn build_cargo_project(working_dir: Option<&PathBuf>) -> Result<()> {
let mut cmd = Command::new("cargo");
let mut is_nightly_cmd = Command::new("cargo");
if let Some(dir) = working_dir {
cmd.current_dir(dir);
is_nightly_cmd.current_dir(dir);
}
let is_nightly_default = is_nightly_cmd
.arg("--version")
.output()
.map_err(|_| ())
.and_then(|o| String::from_utf8(o.stdout).map_err(|_| ()))
.unwrap_or_default()
.contains("-nightly");
if !is_nightly_default {
cmd.arg("+nightly");
}
let output = cmd
.args(&[
"build",
"--no-default-features",
"--release",
"--target=wasm32-unknown-unknown",
"--verbose",
])
.output()?;
if !output.status.success() {
// Dump the output streams produced by cargo into the stdout/stderr.
io::stdout().write_all(&output.stdout)?;
io::stderr().write_all(&output.stderr)?;
return Err(Error::BuildFailed)
}
Ok(())
super::exec_cargo("build", &[
"--no-default-features",
"--release",
"--target=wasm32-unknown-unknown",
"--verbose",
], working_dir)
}
/// Ensures the wasm memory import of a given module has the maximum number of pages.
......
......@@ -14,12 +14,23 @@
// You should have received a copy of the GNU General Public License
// along with ink!. If not, see <http://www.gnu.org/licenses/>.
use std::{
io::{
self,
Write,
},
path::PathBuf,
process::Command,
};
mod abi;
mod build;
mod deploy;
mod error;
mod new;
pub(crate) use self::{
abi::execute_generate_abi,
build::execute_build,
deploy::execute_deploy,
error::{
......@@ -29,6 +40,41 @@ pub(crate) use self::{
new::execute_new,
};
fn exec_cargo(command: &str, args: &[&'static str], working_dir: Option<&PathBuf>) -> Result<()> {
let mut cmd = Command::new("cargo");
let mut is_nightly_cmd = Command::new("cargo");
if let Some(dir) = working_dir {
cmd.current_dir(dir);
is_nightly_cmd.current_dir(dir);
}
let is_nightly_default = is_nightly_cmd
.arg("--version")
.output()
.map_err(|_| ())
.and_then(|o| String::from_utf8(o.stdout).map_err(|_| ()))
.unwrap_or_default()
.contains("-nightly");
if !is_nightly_default {
cmd.arg("+nightly");
}
let output = cmd
.arg(command)
.args(args)
.output()?;
if !output.status.success() {
// Dump the output streams produced by cargo into the stdout/stderr.
io::stdout().write_all(&output.stdout)?;
io::stderr().write_all(&output.stderr)?;
return Err(error::CommandError::BuildFailed)
}
Ok(())
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
......
......@@ -94,6 +94,9 @@ enum Command {
/// Builds the smart contract.
#[structopt(name = "build")]
Build {},
/// Generate abi artifacts
#[structopt(name = "generate-abi")]
GenerateAbi {},
/// Test the smart contract off-chain.
#[structopt(name = "test")]
Test {},
......@@ -142,6 +145,7 @@ fn exec(cmd: Command) -> cmd::Result<String> {
target_dir,
} => cmd::execute_new(*layer, name, target_dir.as_ref()),
Command::Build {} => cmd::execute_build(None),
Command::GenerateAbi {} => cmd::execute_generate_abi(None),
Command::Test {} => Err(CommandError::UnimplementedCommand),
Command::Deploy {
url,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment