From 6ea84057c3ee07b44b884528d7bd0a717204cbdf Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 10 Mar 2021 17:36:51 +0000 Subject: [PATCH 1/9] Refactoring build, phase 1 --- src/cmd/build.rs | 155 ++++++++++--------- src/cmd/metadata.rs | 362 ++++++++++++++++++-------------------------- src/main.rs | 2 + 3 files changed, 226 insertions(+), 293 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index b5fe972b..9a0f1b79 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -112,7 +112,8 @@ impl CheckCommand { } } -/// Builds the project in the specified directory, defaults to the current directory. +/// Executes the supplied cargo command on the project in the specified directory, defaults to the +/// current directory. /// /// Uses the unstable cargo feature [`build-std`](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) /// to build the standard library with [`panic_immediate_abort`](https://github.com/johnthagen/min-sized-rust#remove-panic-string-formatting-with-panic_immediate_abort) @@ -127,11 +128,11 @@ impl CheckCommand { /// user-defined settings will be preserved. /// /// To disable this and use the original `Cargo.toml` as is then pass the `-Z original_manifest` flag. -fn build_cargo_project( +fn exec_cargo_for_wasm_target( crate_metadata: &CrateMetadata, - build_artifact: BuildArtifacts, + command: &str, verbosity: Verbosity, - unstable_flags: UnstableFlags, + unstable_flags: &UnstableFlags, ) -> Result<()> { util::assert_channel()?; @@ -152,11 +153,7 @@ fn build_cargo_project( "--release", &format!("--target-dir={}", target_dir.to_string_lossy()), ]; - if build_artifact == BuildArtifacts::CheckOnly { - util::invoke_cargo("check", &args, manifest_path.directory(), verbosity)?; - } else { - util::invoke_cargo("build", &args, manifest_path.directory(), verbosity)?; - } + util::invoke_cargo(command, &args, manifest_path.directory(), verbosity)?; Ok(()) }; @@ -284,6 +281,7 @@ fn optimize_wasm(crate_metadata: &CrateMetadata) -> Result { // overwrite existing destination wasm file with the optimised version std::fs::rename(&dest_optimized, &crate_metadata.dest_wasm)?; Ok(OptimizationResult { + dest_wasm: crate_metadata.dest_wasm.clone(), original_size, optimized_size, }) @@ -382,78 +380,77 @@ fn execute( build_artifact: BuildArtifacts, unstable_flags: UnstableFlags, ) -> Result { - if build_artifact == BuildArtifacts::CodeOnly || build_artifact == BuildArtifacts::CheckOnly { - let crate_metadata = CrateMetadata::collect(manifest_path)?; - let (maybe_dest_wasm, maybe_optimization_result) = execute_with_crate_metadata( - &crate_metadata, - verbosity, - optimize_contract, - build_artifact, - unstable_flags, - )?; - let res = BuildResult { - dest_wasm: maybe_dest_wasm, - dest_metadata: None, - dest_bundle: None, - target_directory: crate_metadata.target_directory, - optimization_result: maybe_optimization_result, - build_artifact, - verbosity, + let crate_metadata = CrateMetadata::collect(manifest_path)?; + + let (dest_wasm, opt_result, dest_metadata, dest_bundle) = + match build_artifact { + BuildArtifacts::CodeOnly => { + maybe_println!( + verbosity, + " {} {}", + format!("[1/{}]", build_artifact.steps()).bold(), + "Building cargo project".bright_green().bold() + ); + exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; + + maybe_println!( + verbosity, + " {} {}", + format!("[2/{}]", build_artifact.steps()).bold(), + "Post processing wasm file".bright_green().bold() + ); + post_process_wasm(&crate_metadata)?; + + let (optimization_result, dest_wasm) = + if optimize_contract { + maybe_println!( + verbosity, + " {} {}", + format!("[3/{}]", build_artifact.steps()).bold(), + "Optimizing wasm file".bright_green().bold() + ); + let optimization_result = optimize_wasm(&crate_metadata)?; + let dest_wasm = optimization_result.dest_wasm.clone(); + (Some(optimization_result), dest_wasm) + } else { + (None, crate_metadata.dest_wasm.clone()) + }; + + (Some(dest_wasm), optimization_result, None, None) + } + BuildArtifacts::CheckOnly => { + exec_cargo_for_wasm_target(&crate_metadata, "check", verbosity, &unstable_flags)?; + (None, None, None, None) + } + BuildArtifacts::All => { + exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; + maybe_println!( + verbosity, + " {} {}", + format!("[2/{}]", build_artifact.steps()).bold(), + "Post processing wasm file".bright_green().bold() + ); + post_process_wasm(&crate_metadata)?; + maybe_println!( + verbosity, + " {} {}", + format!("[3/{}]", build_artifact.steps()).bold(), + "Optimizing wasm file".bright_green().bold() + ); + let optimization_result = optimize_wasm(&crate_metadata)?; + let (dest_metadata, dest_bundle) = super::metadata::execute(&crate_metadata, optimization_result.dest_wasm.as_path(), verbosity, &unstable_flags)?; + (Some(optimization_result.dest_wasm.clone()), Some(optimization_result), Some(dest_metadata), Some(dest_bundle)) + } }; - return Ok(res); - } - - let res = super::metadata::execute(&manifest_path, verbosity, build_artifact, unstable_flags)?; - Ok(res) -} - -/// Executes build of the smart-contract which produces a Wasm binary that is ready for deploying. -/// -/// It does so by invoking `cargo build` and then post processing the final binary. -/// -/// # Note -/// -/// Uses the supplied `CrateMetadata`. If an instance is not available use [`execute_build`] -/// -/// Returns a tuple of `(maybe_optimized_wasm_path, maybe_optimization_result)`. -pub(crate) fn execute_with_crate_metadata( - crate_metadata: &CrateMetadata, - verbosity: Verbosity, - optimize_contract: bool, - build_artifact: BuildArtifacts, - unstable_flags: UnstableFlags, -) -> Result<(Option, Option)> { - maybe_println!( - verbosity, - " {} {}", - format!("[1/{}]", build_artifact.steps()).bold(), - "Building cargo project".bright_green().bold() - ); - build_cargo_project(&crate_metadata, build_artifact, verbosity, unstable_flags)?; - if build_artifact == BuildArtifacts::CheckOnly { - return Ok((None, None)); - } - maybe_println!( + Ok(BuildResult { + dest_wasm, + dest_metadata, + dest_bundle, + target_directory: crate_metadata.target_directory, + optimization_result: opt_result, + build_artifact, verbosity, - " {} {}", - format!("[2/{}]", build_artifact.steps()).bold(), - "Post processing wasm file".bright_green().bold() - ); - post_process_wasm(&crate_metadata)?; - if !optimize_contract { - return Ok((None, None)); - } - maybe_println!( - verbosity, - " {} {}", - format!("[3/{}]", build_artifact.steps()).bold(), - "Optimizing wasm file".bright_green().bold() - ); - let optimization_result = optimize_wasm(&crate_metadata)?; - Ok(( - Some(crate_metadata.dest_wasm.clone()), - Some(optimization_result), - )) + }) } #[cfg(feature = "test-ci-only")] diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 18135149..1c9dce88 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -18,7 +18,7 @@ use crate::{ crate_metadata::CrateMetadata, maybe_println, util, workspace::{ManifestPath, Workspace}, - BuildArtifacts, BuildResult, OptimizationResult, UnstableFlags, Verbosity, + UnstableFlags, Verbosity, }; use anyhow::Result; @@ -29,223 +29,172 @@ use contract_metadata::{ SourceLanguage, SourceWasm, User, }; use semver::Version; -use std::{fs, path::PathBuf}; +use std::{fs, path::{PathBuf, Path}}; use url::Url; const METADATA_FILE: &str = "metadata.json"; -/// Executes the metadata generation process -struct GenerateMetadataCommand { - crate_metadata: CrateMetadata, - verbosity: Verbosity, - build_artifact: BuildArtifacts, - unstable_options: UnstableFlags, -} - /// Result of generating the extended contract project metadata struct ExtendedMetadataResult { - dest_wasm: Option, source: Source, contract: Contract, user: Option, - optimization_result: Option, } -impl GenerateMetadataCommand { - pub fn exec(&self) -> Result { - util::assert_channel()?; - - let target_directory = self.crate_metadata.target_directory.clone(); - let out_path_metadata = target_directory.join(METADATA_FILE); - - let fname_bundle = format!("{}.contract", self.crate_metadata.package_name); - let out_path_bundle = target_directory.join(fname_bundle); - - // build the extended contract project metadata - let ExtendedMetadataResult { - dest_wasm, - source, - contract, - user, - optimization_result, - } = self.extended_metadata()?; - - let generate_metadata = |manifest_path: &ManifestPath| -> Result<()> { - let mut current_progress = 4; - maybe_println!( - self.verbosity, - " {} {}", - format!("[{}/{}]", current_progress, self.build_artifact.steps()).bold(), - "Generating metadata".bright_green().bold() - ); - let target_dir_arg = format!("--target-dir={}", target_directory.to_string_lossy()); - let stdout = util::invoke_cargo( - "run", - &[ - "--package", - "metadata-gen", - &manifest_path.cargo_arg(), - &target_dir_arg, - "--release", - ], - self.crate_metadata.manifest_path.directory(), - self.verbosity, - )?; - - let ink_meta: serde_json::Map = - serde_json::from_slice(&stdout)?; - let metadata = ContractMetadata::new(source, contract, user, ink_meta); - { - let mut metadata = metadata.clone(); - metadata.remove_source_wasm_attribute(); - let contents = serde_json::to_string_pretty(&metadata)?; - fs::write(&out_path_metadata, contents)?; - current_progress += 1; - } - - if self.build_artifact == BuildArtifacts::All { - maybe_println!( - self.verbosity, - " {} {}", - format!("[{}/{}]", current_progress, self.build_artifact.steps()).bold(), - "Generating bundle".bright_green().bold() - ); - let contents = serde_json::to_string(&metadata)?; - fs::write(&out_path_bundle, contents)?; - } +/// Generates a file with metadata describing the ABI of the smart-contract. +/// +/// It does so by generating and invoking a temporary workspace member. +pub(crate) fn execute( + crate_metadata: &CrateMetadata, + final_contract_wasm: &Path, + verbosity: Verbosity, + unstable_options: &UnstableFlags, +) -> Result<(PathBuf, PathBuf)> { + util::assert_channel()?; + + let target_directory = crate_metadata.target_directory.clone(); + let out_path_metadata = target_directory.join(METADATA_FILE); + + let fname_bundle = format!("{}.contract", crate_metadata.package_name); + let out_path_bundle = target_directory.join(fname_bundle); + + // build the extended contract project metadata + let ExtendedMetadataResult { + source, + contract, + user, + } = extended_metadata(crate_metadata, final_contract_wasm)?; + + let generate_metadata = |manifest_path: &ManifestPath| -> Result<()> { + let mut current_progress = 4; + maybe_println!( + verbosity, + " {} {}", + format!("[{}/{}]", current_progress, 5).bold(), + "Generating metadata".bright_green().bold() + ); + let target_dir_arg = format!("--target-dir={}", target_directory.to_string_lossy()); + let stdout = util::invoke_cargo( + "run", + &[ + "--package", + "metadata-gen", + &manifest_path.cargo_arg(), + &target_dir_arg, + "--release", + ], + crate_metadata.manifest_path.directory(), + verbosity, + )?; - Ok(()) - }; - - if self.unstable_options.original_manifest { - generate_metadata(&self.crate_metadata.manifest_path)?; - } else { - Workspace::new( - &self.crate_metadata.cargo_meta, - &self.crate_metadata.root_package.id, - )? - .with_root_package_manifest(|manifest| { - manifest - .with_added_crate_type("rlib")? - .with_profile_release_lto(false)?; - Ok(()) - })? - .with_metadata_gen_package(self.crate_metadata.manifest_path.absolute_directory()?)? - .using_temp(generate_metadata)?; + let ink_meta: serde_json::Map = + serde_json::from_slice(&stdout)?; + let metadata = ContractMetadata::new(source, contract, user, ink_meta); + { + let mut metadata = metadata.clone(); + metadata.remove_source_wasm_attribute(); + let contents = serde_json::to_string_pretty(&metadata)?; + fs::write(&out_path_metadata, contents)?; + current_progress += 1; } - let dest_bundle = if self.build_artifact == BuildArtifacts::All { - Some(out_path_bundle) - } else { - None - }; - Ok(BuildResult { - dest_metadata: Some(out_path_metadata), - dest_wasm, - dest_bundle, - optimization_result, - target_directory, - build_artifact: self.build_artifact, - verbosity: self.verbosity, - }) - } + maybe_println!( + verbosity, + " {} {}", + format!("[{}/{}]", current_progress, 5).bold(), + "Generating bundle".bright_green().bold() + ); + let contents = serde_json::to_string(&metadata)?; + fs::write(&out_path_bundle, contents)?; - /// Generate the extended contract project metadata - fn extended_metadata(&self) -> Result { - let contract_package = &self.crate_metadata.root_package; - let ink_version = &self.crate_metadata.ink_version; - let rust_version = Version::parse(&rustc_version::version()?.to_string())?; - let contract_name = contract_package.name.clone(); - let contract_version = Version::parse(&contract_package.version.to_string())?; - let contract_authors = contract_package.authors.clone(); - // optional - let description = contract_package.description.clone(); - let documentation = self.crate_metadata.documentation.clone(); - let repository = contract_package - .repository - .as_ref() - .map(|repo| Url::parse(&repo)) - .transpose()?; - let homepage = self.crate_metadata.homepage.clone(); - let license = contract_package.license.clone(); - let (dest_wasm, hash, optimization_result) = self.wasm_hash()?; - let source = { - let lang = SourceLanguage::new(Language::Ink, ink_version.clone()); - let compiler = SourceCompiler::new(Compiler::RustC, rust_version); - let maybe_wasm = if self.build_artifact == BuildArtifacts::All { - let wasm = fs::read(&self.crate_metadata.dest_wasm)?; - // The Wasm which we read must have the same hash as `source.hash` - debug_assert!({ - let expected = blake2_hash(wasm.as_slice()); - expected == hash - }); - Some(SourceWasm::new(wasm)) - } else { - None - }; - Source::new(maybe_wasm, hash, lang, compiler) - }; - - // Required contract fields - let mut builder = Contract::builder(); - builder - .name(contract_name) - .version(contract_version) - .authors(contract_authors); - - if let Some(description) = description { - builder.description(description); - } + Ok(()) + }; - if let Some(documentation) = documentation { - builder.documentation(documentation); - } + if unstable_options.original_manifest { + generate_metadata(&crate_metadata.manifest_path)?; + } else { + Workspace::new( + &crate_metadata.cargo_meta, + &crate_metadata.root_package.id, + )? + .with_root_package_manifest(|manifest| { + manifest + .with_added_crate_type("rlib")? + .with_profile_release_lto(false)?; + Ok(()) + })? + .with_metadata_gen_package(crate_metadata.manifest_path.absolute_directory()?)? + .using_temp(generate_metadata)?; + } - if let Some(repository) = repository { - builder.repository(repository); - } + Ok((out_path_metadata, out_path_bundle)) +} - if let Some(homepage) = homepage { - builder.homepage(homepage); - } +/// Generate the extended contract project metadata +fn extended_metadata(crate_metadata: &CrateMetadata, final_contract_wasm: &Path) -> Result { + let contract_package = &crate_metadata.root_package; + let ink_version = &crate_metadata.ink_version; + let rust_version = Version::parse(&rustc_version::version()?.to_string())?; + let contract_name = contract_package.name.clone(); + let contract_version = Version::parse(&contract_package.version.to_string())?; + let contract_authors = contract_package.authors.clone(); + // optional + let description = contract_package.description.clone(); + let documentation = crate_metadata.documentation.clone(); + let repository = contract_package + .repository + .as_ref() + .map(|repo| Url::parse(&repo)) + .transpose()?; + let homepage = crate_metadata.homepage.clone(); + let license = contract_package.license.clone(); + let source = { + let lang = SourceLanguage::new(Language::Ink, ink_version.clone()); + let compiler = SourceCompiler::new(Compiler::RustC, rust_version); + let wasm = fs::read(final_contract_wasm)?; + let hash = blake2_hash(wasm.as_slice()); + Source::new(Some(SourceWasm::new(wasm)), hash, lang, compiler) + }; - if let Some(license) = license { - builder.license(license); - } + // Required contract fields + let mut builder = Contract::builder(); + builder + .name(contract_name) + .version(contract_version) + .authors(contract_authors); - let contract = builder - .build() - .map_err(|err| anyhow::anyhow!("Invalid contract metadata builder state: {}", err))?; + if let Some(description) = description { + builder.description(description); + } - // user defined metadata - let user = self.crate_metadata.user.clone().map(User::new); + if let Some(documentation) = documentation { + builder.documentation(documentation); + } - Ok(ExtendedMetadataResult { - dest_wasm: Some(dest_wasm), - source, - contract, - user, - optimization_result: Some(optimization_result), - }) + if let Some(repository) = repository { + builder.repository(repository); } - /// Compile the contract and then hash the resulting Wasm. - /// - /// Return a tuple of `(dest_wasm, hash, optimization_result)`. - fn wasm_hash(&self) -> Result<(PathBuf, CodeHash, OptimizationResult)> { - let (maybe_dest_wasm, maybe_optimization_res) = super::build::execute_with_crate_metadata( - &self.crate_metadata, - self.verbosity, - true, // for the hash we always use the optimized version of the contract - self.build_artifact, - self.unstable_options.clone(), - )?; + if let Some(homepage) = homepage { + builder.homepage(homepage); + } - let wasm = fs::read(&self.crate_metadata.dest_wasm)?; - let dest_wasm = maybe_dest_wasm.expect("dest wasm must exist"); - let optimization_res = maybe_optimization_res.expect("optimization result must exist"); - Ok((dest_wasm, blake2_hash(wasm.as_slice()), optimization_res)) + if let Some(license) = license { + builder.license(license); } + + let contract = builder + .build() + .map_err(|err| anyhow::anyhow!("Invalid contract metadata builder state: {}", err))?; + + // user defined metadata + let user = crate_metadata.user.clone().map(User::new); + + Ok(ExtendedMetadataResult { + source, + contract, + user, + }) } /// Returns the blake2 hash of the submitted slice. @@ -257,26 +206,6 @@ fn blake2_hash(code: &[u8]) -> CodeHash { CodeHash(output) } -/// Generates a file with metadata describing the ABI of the smart-contract. -/// -/// It does so by generating and invoking a temporary workspace member. -pub(crate) fn execute( - manifest_path: &ManifestPath, - verbosity: Verbosity, - build_artifact: BuildArtifacts, - unstable_options: UnstableFlags, -) -> Result { - let crate_metadata = CrateMetadata::collect(manifest_path)?; - let res = GenerateMetadataCommand { - crate_metadata, - verbosity, - build_artifact, - unstable_options, - } - .exec()?; - Ok(res) -} - #[cfg(feature = "test-ci-only")] #[cfg(test)] mod tests { @@ -377,10 +306,15 @@ mod tests { test_manifest.write()?; let crate_metadata = CrateMetadata::collect(&test_manifest.manifest_path)?; + + // usually this file will be produced by a previous build step + let final_contract_wasm_path = crate_metadata.dest_wasm; + fs::write(final_contract_wasm_path, "TEST FINAL WASM BLOB"); + let dest_bundle = cmd::metadata::execute( - &test_manifest.manifest_path, + &crate_metadata, + &final_contract_wasm_path, Verbosity::Default, - BuildArtifacts::All, UnstableFlags::default(), )? .dest_bundle diff --git a/src/main.rs b/src/main.rs index 34188abc..2f1a43d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -224,6 +224,8 @@ pub struct BuildResult { /// Result of the optimization process. pub struct OptimizationResult { + /// The path of the optimized wasm file. + pub dest_wasm: PathBuf, /// The original Wasm size. pub original_size: f64, /// The Wasm size after optimizations have been applied. -- GitLab From 518bacacf3e57530d2d8eadc424c36371ec2e728 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 10 Mar 2021 17:39:02 +0000 Subject: [PATCH 2/9] Fmt --- src/cmd/build.rs | 112 ++++++++++++++++++++++++-------------------- src/cmd/metadata.rs | 34 +++++++------- 2 files changed, 78 insertions(+), 68 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 9a0f1b79..8795b60c 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -382,55 +382,25 @@ fn execute( ) -> Result { let crate_metadata = CrateMetadata::collect(manifest_path)?; - let (dest_wasm, opt_result, dest_metadata, dest_bundle) = - match build_artifact { - BuildArtifacts::CodeOnly => { - maybe_println!( - verbosity, - " {} {}", - format!("[1/{}]", build_artifact.steps()).bold(), - "Building cargo project".bright_green().bold() - ); - exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; + let (dest_wasm, opt_result, dest_metadata, dest_bundle) = match build_artifact { + BuildArtifacts::CodeOnly => { + maybe_println!( + verbosity, + " {} {}", + format!("[1/{}]", build_artifact.steps()).bold(), + "Building cargo project".bright_green().bold() + ); + exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; - maybe_println!( - verbosity, - " {} {}", - format!("[2/{}]", build_artifact.steps()).bold(), - "Post processing wasm file".bright_green().bold() - ); - post_process_wasm(&crate_metadata)?; - - let (optimization_result, dest_wasm) = - if optimize_contract { - maybe_println!( - verbosity, - " {} {}", - format!("[3/{}]", build_artifact.steps()).bold(), - "Optimizing wasm file".bright_green().bold() - ); - let optimization_result = optimize_wasm(&crate_metadata)?; - let dest_wasm = optimization_result.dest_wasm.clone(); - (Some(optimization_result), dest_wasm) - } else { - (None, crate_metadata.dest_wasm.clone()) - }; - - (Some(dest_wasm), optimization_result, None, None) - } - BuildArtifacts::CheckOnly => { - exec_cargo_for_wasm_target(&crate_metadata, "check", verbosity, &unstable_flags)?; - (None, None, None, None) - } - BuildArtifacts::All => { - exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; - maybe_println!( - verbosity, - " {} {}", - format!("[2/{}]", build_artifact.steps()).bold(), - "Post processing wasm file".bright_green().bold() - ); - post_process_wasm(&crate_metadata)?; + maybe_println!( + verbosity, + " {} {}", + format!("[2/{}]", build_artifact.steps()).bold(), + "Post processing wasm file".bright_green().bold() + ); + post_process_wasm(&crate_metadata)?; + + let (optimization_result, dest_wasm) = if optimize_contract { maybe_println!( verbosity, " {} {}", @@ -438,10 +408,48 @@ fn execute( "Optimizing wasm file".bright_green().bold() ); let optimization_result = optimize_wasm(&crate_metadata)?; - let (dest_metadata, dest_bundle) = super::metadata::execute(&crate_metadata, optimization_result.dest_wasm.as_path(), verbosity, &unstable_flags)?; - (Some(optimization_result.dest_wasm.clone()), Some(optimization_result), Some(dest_metadata), Some(dest_bundle)) - } - }; + let dest_wasm = optimization_result.dest_wasm.clone(); + (Some(optimization_result), dest_wasm) + } else { + (None, crate_metadata.dest_wasm.clone()) + }; + + (Some(dest_wasm), optimization_result, None, None) + } + BuildArtifacts::CheckOnly => { + exec_cargo_for_wasm_target(&crate_metadata, "check", verbosity, &unstable_flags)?; + (None, None, None, None) + } + BuildArtifacts::All => { + exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; + maybe_println!( + verbosity, + " {} {}", + format!("[2/{}]", build_artifact.steps()).bold(), + "Post processing wasm file".bright_green().bold() + ); + post_process_wasm(&crate_metadata)?; + maybe_println!( + verbosity, + " {} {}", + format!("[3/{}]", build_artifact.steps()).bold(), + "Optimizing wasm file".bright_green().bold() + ); + let optimization_result = optimize_wasm(&crate_metadata)?; + let (dest_metadata, dest_bundle) = super::metadata::execute( + &crate_metadata, + optimization_result.dest_wasm.as_path(), + verbosity, + &unstable_flags, + )?; + ( + Some(optimization_result.dest_wasm.clone()), + Some(optimization_result), + Some(dest_metadata), + Some(dest_bundle), + ) + } + }; Ok(BuildResult { dest_wasm, dest_metadata, diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 1c9dce88..84ed718e 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -29,7 +29,10 @@ use contract_metadata::{ SourceLanguage, SourceWasm, User, }; use semver::Version; -use std::{fs, path::{PathBuf, Path}}; +use std::{ + fs, + path::{Path, PathBuf}, +}; use url::Url; const METADATA_FILE: &str = "metadata.json"; @@ -87,8 +90,7 @@ pub(crate) fn execute( verbosity, )?; - let ink_meta: serde_json::Map = - serde_json::from_slice(&stdout)?; + let ink_meta: serde_json::Map = serde_json::from_slice(&stdout)?; let metadata = ContractMetadata::new(source, contract, user, ink_meta); { let mut metadata = metadata.clone(); @@ -113,25 +115,25 @@ pub(crate) fn execute( if unstable_options.original_manifest { generate_metadata(&crate_metadata.manifest_path)?; } else { - Workspace::new( - &crate_metadata.cargo_meta, - &crate_metadata.root_package.id, - )? - .with_root_package_manifest(|manifest| { - manifest - .with_added_crate_type("rlib")? - .with_profile_release_lto(false)?; - Ok(()) - })? - .with_metadata_gen_package(crate_metadata.manifest_path.absolute_directory()?)? - .using_temp(generate_metadata)?; + Workspace::new(&crate_metadata.cargo_meta, &crate_metadata.root_package.id)? + .with_root_package_manifest(|manifest| { + manifest + .with_added_crate_type("rlib")? + .with_profile_release_lto(false)?; + Ok(()) + })? + .with_metadata_gen_package(crate_metadata.manifest_path.absolute_directory()?)? + .using_temp(generate_metadata)?; } Ok((out_path_metadata, out_path_bundle)) } /// Generate the extended contract project metadata -fn extended_metadata(crate_metadata: &CrateMetadata, final_contract_wasm: &Path) -> Result { +fn extended_metadata( + crate_metadata: &CrateMetadata, + final_contract_wasm: &Path, +) -> Result { let contract_package = &crate_metadata.root_package; let ink_version = &crate_metadata.ink_version; let rust_version = Version::parse(&rustc_version::version()?.to_string())?; -- GitLab From 79ee88958cc0cde091bd2a7e09e46b80a84fd0bc Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 10:34:00 +0000 Subject: [PATCH 3/9] Extract local method for building, always optimize on build --- src/cmd/build.rs | 89 +++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 54 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 8795b60c..8dff9130 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -77,7 +77,6 @@ impl BuildCommand { execute( &manifest_path, verbosity, - true, self.build_artifact, unstable_flags, ) @@ -105,7 +104,6 @@ impl CheckCommand { execute( &manifest_path, verbosity, - false, BuildArtifacts::CheckOnly, unstable_flags, ) @@ -376,66 +374,51 @@ fn do_optimization( fn execute( manifest_path: &ManifestPath, verbosity: Verbosity, - optimize_contract: bool, build_artifact: BuildArtifacts, unstable_flags: UnstableFlags, ) -> Result { let crate_metadata = CrateMetadata::collect(manifest_path)?; - let (dest_wasm, opt_result, dest_metadata, dest_bundle) = match build_artifact { - BuildArtifacts::CodeOnly => { - maybe_println!( - verbosity, - " {} {}", - format!("[1/{}]", build_artifact.steps()).bold(), - "Building cargo project".bright_green().bold() - ); - exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; + let build = || -> Result { + maybe_println!( + verbosity, + " {} {}", + format!("[1/{}]", build_artifact.steps()).bold(), + "Building cargo project".bright_green().bold() + ); + exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; - maybe_println!( - verbosity, - " {} {}", - format!("[2/{}]", build_artifact.steps()).bold(), - "Post processing wasm file".bright_green().bold() - ); - post_process_wasm(&crate_metadata)?; - - let (optimization_result, dest_wasm) = if optimize_contract { - maybe_println!( - verbosity, - " {} {}", - format!("[3/{}]", build_artifact.steps()).bold(), - "Optimizing wasm file".bright_green().bold() - ); - let optimization_result = optimize_wasm(&crate_metadata)?; - let dest_wasm = optimization_result.dest_wasm.clone(); - (Some(optimization_result), dest_wasm) - } else { - (None, crate_metadata.dest_wasm.clone()) - }; - - (Some(dest_wasm), optimization_result, None, None) + maybe_println!( + verbosity, + " {} {}", + format!("[2/{}]", build_artifact.steps()).bold(), + "Post processing wasm file".bright_green().bold() + ); + post_process_wasm(&crate_metadata)?; + + maybe_println!( + verbosity, + " {} {}", + format!("[3/{}]", build_artifact.steps()).bold(), + "Optimizing wasm file".bright_green().bold() + ); + let optimization_result = optimize_wasm(&crate_metadata)?; + + Ok(optimization_result) + }; + + let (opt_result, dest_metadata, dest_bundle) = match build_artifact { + BuildArtifacts::CodeOnly => { + let optimization_result = build()?; + (Some(optimization_result), None, None) } BuildArtifacts::CheckOnly => { exec_cargo_for_wasm_target(&crate_metadata, "check", verbosity, &unstable_flags)?; - (None, None, None, None) + (None, None, None) } BuildArtifacts::All => { - exec_cargo_for_wasm_target(&crate_metadata, "build", verbosity, &unstable_flags)?; - maybe_println!( - verbosity, - " {} {}", - format!("[2/{}]", build_artifact.steps()).bold(), - "Post processing wasm file".bright_green().bold() - ); - post_process_wasm(&crate_metadata)?; - maybe_println!( - verbosity, - " {} {}", - format!("[3/{}]", build_artifact.steps()).bold(), - "Optimizing wasm file".bright_green().bold() - ); - let optimization_result = optimize_wasm(&crate_metadata)?; + let optimization_result = build()?; + let (dest_metadata, dest_bundle) = super::metadata::execute( &crate_metadata, optimization_result.dest_wasm.as_path(), @@ -443,13 +426,13 @@ fn execute( &unstable_flags, )?; ( - Some(optimization_result.dest_wasm.clone()), Some(optimization_result), Some(dest_metadata), Some(dest_bundle), ) } }; + let dest_wasm = opt_result.as_ref().map(|r| r.dest_wasm.clone()); Ok(BuildResult { dest_wasm, dest_metadata, @@ -477,7 +460,6 @@ mod tests_ci_only { let res = super::execute( &manifest_path, Verbosity::Default, - true, BuildArtifacts::All, UnstableFlags::default(), ) @@ -513,7 +495,6 @@ mod tests_ci_only { super::execute( &manifest_path, Verbosity::Default, - true, BuildArtifacts::CheckOnly, UnstableFlags::default(), ) -- GitLab From 723fcd24c73a9bd15b93aba971998f9ffbf7ecb3 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 11:17:16 +0000 Subject: [PATCH 4/9] Add MetadataResult type --- src/cmd/build.rs | 24 ++++++++++-------------- src/cmd/metadata.rs | 30 ++++++++++++++++++++---------- src/main.rs | 19 ++++++++++--------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 8dff9130..9f235239 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -407,36 +407,32 @@ fn execute( Ok(optimization_result) }; - let (opt_result, dest_metadata, dest_bundle) = match build_artifact { - BuildArtifacts::CodeOnly => { - let optimization_result = build()?; - (Some(optimization_result), None, None) - } + let (opt_result, metadata_result) = match build_artifact { BuildArtifacts::CheckOnly => { exec_cargo_for_wasm_target(&crate_metadata, "check", verbosity, &unstable_flags)?; - (None, None, None) + (None, None) + } + BuildArtifacts::CodeOnly => { + let optimization_result = build()?; + (Some(optimization_result), None) } BuildArtifacts::All => { let optimization_result = build()?; - let (dest_metadata, dest_bundle) = super::metadata::execute( + let metadata_result = super::metadata::execute( &crate_metadata, optimization_result.dest_wasm.as_path(), verbosity, + build_artifact.steps(), &unstable_flags, )?; - ( - Some(optimization_result), - Some(dest_metadata), - Some(dest_bundle), - ) + (Some(optimization_result), Some(metadata_result)) } }; let dest_wasm = opt_result.as_ref().map(|r| r.dest_wasm.clone()); Ok(BuildResult { dest_wasm, - dest_metadata, - dest_bundle, + metadata_result, target_directory: crate_metadata.target_directory, optimization_result: opt_result, build_artifact, diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 84ed718e..243e1695 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -37,6 +37,14 @@ use url::Url; const METADATA_FILE: &str = "metadata.json"; +/// Metadata generation result. +pub struct MetadataResult { + /// Path to the resulting metadata file. + pub dest_metadata: PathBuf, + /// Path to the bundled file. + pub dest_bundle: PathBuf, +} + /// Result of generating the extended contract project metadata struct ExtendedMetadataResult { source: Source, @@ -51,8 +59,9 @@ pub(crate) fn execute( crate_metadata: &CrateMetadata, final_contract_wasm: &Path, verbosity: Verbosity, + total_steps: usize, unstable_options: &UnstableFlags, -) -> Result<(PathBuf, PathBuf)> { +) -> Result { util::assert_channel()?; let target_directory = crate_metadata.target_directory.clone(); @@ -73,7 +82,7 @@ pub(crate) fn execute( maybe_println!( verbosity, " {} {}", - format!("[{}/{}]", current_progress, 5).bold(), + format!("[{}/{}]", current_progress, total_steps).bold(), "Generating metadata".bright_green().bold() ); let target_dir_arg = format!("--target-dir={}", target_directory.to_string_lossy()); @@ -103,7 +112,7 @@ pub(crate) fn execute( maybe_println!( verbosity, " {} {}", - format!("[{}/{}]", current_progress, 5).bold(), + format!("[{}/{}]", current_progress, total_steps).bold(), "Generating bundle".bright_green().bold() ); let contents = serde_json::to_string(&metadata)?; @@ -126,7 +135,7 @@ pub(crate) fn execute( .using_temp(generate_metadata)?; } - Ok((out_path_metadata, out_path_bundle)) + Ok(MetadataResult { dest_metadata: out_path_metadata, dest_bundle: out_path_bundle }) } /// Generate the extended contract project metadata @@ -213,7 +222,7 @@ fn blake2_hash(code: &[u8]) -> CodeHash { mod tests { use crate::cmd::metadata::blake2_hash; use crate::{ - cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, BuildArtifacts, + cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, ManifestPath, UnstableFlags, Verbosity, }; use contract_metadata::*; @@ -310,17 +319,18 @@ mod tests { let crate_metadata = CrateMetadata::collect(&test_manifest.manifest_path)?; // usually this file will be produced by a previous build step - let final_contract_wasm_path = crate_metadata.dest_wasm; - fs::write(final_contract_wasm_path, "TEST FINAL WASM BLOB"); + let final_contract_wasm_path = &crate_metadata.dest_wasm; + fs::write(final_contract_wasm_path, "TEST FINAL WASM BLOB").unwrap(); let dest_bundle = cmd::metadata::execute( &crate_metadata, &final_contract_wasm_path, Verbosity::Default, - UnstableFlags::default(), + 5, + &UnstableFlags::default(), )? - .dest_bundle - .expect("bundle file not found"); + .dest_bundle; + let metadata_json: Map = serde_json::from_slice(&fs::read(&dest_bundle)?)?; diff --git a/src/main.rs b/src/main.rs index 2f1a43d7..21d66bda 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,10 @@ mod workspace; use self::workspace::ManifestPath; -use crate::cmd::{BuildCommand, CheckCommand}; +use crate::cmd::{ + BuildCommand, CheckCommand, + metadata::MetadataResult, +}; #[cfg(feature = "extrinsics")] use sp_core::{crypto::Pair, sr25519, H256}; @@ -206,12 +209,10 @@ impl std::str::FromStr for BuildArtifacts { /// Result of the metadata generation process. pub struct BuildResult { - /// Path to the resulting metadata file. - pub dest_metadata: Option, /// Path to the resulting Wasm file. pub dest_wasm: Option, - /// Path to the bundled file. - pub dest_bundle: Option, + /// Result of the metadata generation. + pub metadata_result: Option, /// Path to the directory where output files are written to. pub target_directory: PathBuf, /// If existent the result of the optimization. @@ -264,10 +265,10 @@ impl BuildResult { size_diff, self.target_directory.display().to_string().bold(), ); - if let Some(dest_bundle) = self.dest_bundle.as_ref() { + if let Some(metadata_result) = self.metadata_result.as_ref() { let bundle = format!( " - {} (code + metadata)\n", - util::base_name(&dest_bundle).bold() + util::base_name(&metadata_result.dest_bundle).bold() ); out.push_str(&bundle); } @@ -278,10 +279,10 @@ impl BuildResult { ); out.push_str(&wasm); } - if let Some(dest_metadata) = self.dest_metadata.as_ref() { + if let Some(metadata_result) = self.metadata_result.as_ref() { let metadata = format!( " - {} (the contract's metadata)", - util::base_name(&dest_metadata).bold() + util::base_name(&metadata_result.dest_metadata).bold() ); out.push_str(&metadata); } -- GitLab From fc7d276b4b97e4b8ed6b3630f7a013e85bc953dc Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 11:20:21 +0000 Subject: [PATCH 5/9] Fmt --- src/cmd/metadata.rs | 9 ++++++--- src/main.rs | 5 +---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 243e1695..e16596b7 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -135,7 +135,10 @@ pub(crate) fn execute( .using_temp(generate_metadata)?; } - Ok(MetadataResult { dest_metadata: out_path_metadata, dest_bundle: out_path_bundle }) + Ok(MetadataResult { + dest_metadata: out_path_metadata, + dest_bundle: out_path_bundle, + }) } /// Generate the extended contract project metadata @@ -222,8 +225,8 @@ fn blake2_hash(code: &[u8]) -> CodeHash { mod tests { use crate::cmd::metadata::blake2_hash; use crate::{ - cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, - ManifestPath, UnstableFlags, Verbosity, + cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, ManifestPath, UnstableFlags, + Verbosity, }; use contract_metadata::*; use serde_json::{Map, Value}; diff --git a/src/main.rs b/src/main.rs index 21d66bda..472aee68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,10 +22,7 @@ mod workspace; use self::workspace::ManifestPath; -use crate::cmd::{ - BuildCommand, CheckCommand, - metadata::MetadataResult, -}; +use crate::cmd::{metadata::MetadataResult, BuildCommand, CheckCommand}; #[cfg(feature = "extrinsics")] use sp_core::{crypto::Pair, sr25519, H256}; -- GitLab From 5b0e9951b0fe41c3b0c0ebeaf7a33340b79ad087 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 12:01:24 +0000 Subject: [PATCH 6/9] Create dest wasm dir --- src/cmd/metadata.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index e16596b7..54422033 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -323,6 +323,7 @@ mod tests { // usually this file will be produced by a previous build step let final_contract_wasm_path = &crate_metadata.dest_wasm; + fs::create_dir_all(final_contract_wasm_path.parent().unwrap()).unwrap(); fs::write(final_contract_wasm_path, "TEST FINAL WASM BLOB").unwrap(); let dest_bundle = cmd::metadata::execute( -- GitLab From 1882f7ef1883f89847e472034097b8ae5bca670f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 15:26:57 +0000 Subject: [PATCH 7/9] Execute build directly from metadata tests --- src/cmd/build.rs | 2 +- src/cmd/metadata.rs | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 9f235239..a6cfb62d 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -371,7 +371,7 @@ fn do_optimization( /// Executes build of the smart-contract which produces a wasm binary that is ready for deploying. /// /// It does so by invoking `cargo build` and then post processing the final binary. -fn execute( +pub(crate) fn execute( manifest_path: &ManifestPath, verbosity: Verbosity, build_artifact: BuildArtifacts, diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 54422033..b31365bd 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -224,10 +224,7 @@ fn blake2_hash(code: &[u8]) -> CodeHash { #[cfg(test)] mod tests { use crate::cmd::metadata::blake2_hash; - use crate::{ - cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, ManifestPath, UnstableFlags, - Verbosity, - }; + use crate::{cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, ManifestPath, UnstableFlags, Verbosity, BuildArtifacts}; use contract_metadata::*; use serde_json::{Map, Value}; use std::{fmt::Write, fs}; @@ -326,14 +323,15 @@ mod tests { fs::create_dir_all(final_contract_wasm_path.parent().unwrap()).unwrap(); fs::write(final_contract_wasm_path, "TEST FINAL WASM BLOB").unwrap(); - let dest_bundle = cmd::metadata::execute( - &crate_metadata, - &final_contract_wasm_path, + let build_result = cmd::build::execute( + &test_manifest.manifest_path, Verbosity::Default, - 5, - &UnstableFlags::default(), - )? - .dest_bundle; + BuildArtifacts::All, + UnstableFlags::default(), + )?; + let dest_bundle = build_result.metadata_result + .expect("Metadata should be generated") + .dest_bundle; let metadata_json: Map = serde_json::from_slice(&fs::read(&dest_bundle)?)?; -- GitLab From 40bcd6c56835ff669e574e61bf101ff4568ce136 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 11 Mar 2021 15:28:38 +0000 Subject: [PATCH 8/9] Modify existing build test to code only, since metadata test now builds all --- src/cmd/build.rs | 9 +++++++-- src/cmd/metadata.rs | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index a6cfb62d..5a3ece99 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -448,7 +448,7 @@ mod tests_ci_only { }; #[test] - fn build_template() { + fn build_code_only() { with_tmp_dir(|path| { cmd::new::execute("new_project", Some(path)).expect("new project creation failed"); let manifest_path = @@ -456,7 +456,7 @@ mod tests_ci_only { let res = super::execute( &manifest_path, Verbosity::Default, - BuildArtifacts::All, + BuildArtifacts::CodeOnly, UnstableFlags::default(), ) .expect("build failed"); @@ -469,6 +469,11 @@ mod tests_ci_only { // for `/ink` being the root path. assert!(res.target_directory.ends_with("ink")); + assert!( + res.metadata_result.is_none(), + "CodeOnly should not generate the metadata" + ); + let optimized_size = res.optimization_result.unwrap().optimized_size; assert!(optimized_size > 0.0); diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index b31365bd..1d97541b 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -224,7 +224,10 @@ fn blake2_hash(code: &[u8]) -> CodeHash { #[cfg(test)] mod tests { use crate::cmd::metadata::blake2_hash; - use crate::{cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, ManifestPath, UnstableFlags, Verbosity, BuildArtifacts}; + use crate::{ + cmd, crate_metadata::CrateMetadata, util::tests::with_tmp_dir, BuildArtifacts, + ManifestPath, UnstableFlags, Verbosity, + }; use contract_metadata::*; use serde_json::{Map, Value}; use std::{fmt::Write, fs}; @@ -329,7 +332,8 @@ mod tests { BuildArtifacts::All, UnstableFlags::default(), )?; - let dest_bundle = build_result.metadata_result + let dest_bundle = build_result + .metadata_result .expect("Metadata should be generated") .dest_bundle; -- GitLab From 7dae4f65f6e33a66628f829e309039d09679167d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 Mar 2021 15:05:45 +0000 Subject: [PATCH 9/9] Fix errors after merge --- src/cmd/build.rs | 2 +- src/cmd/metadata.rs | 2 +- src/main.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 45d98b54..60efcd5b 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -412,7 +412,7 @@ pub(crate) fn execute( format!("[3/{}]", build_artifact.steps()).bold(), "Optimizing wasm file".bright_green().bold() ); - let optimization_result = optimize_wasm(&crate_metadata)?; + let optimization_result = optimize_wasm(&crate_metadata, optimization_passes)?; Ok(optimization_result) }; diff --git a/src/cmd/metadata.rs b/src/cmd/metadata.rs index 3d62e3ed..4030e446 100644 --- a/src/cmd/metadata.rs +++ b/src/cmd/metadata.rs @@ -18,7 +18,7 @@ use crate::{ crate_metadata::CrateMetadata, maybe_println, util, workspace::{ManifestPath, Workspace}, - OptimizationPasses, UnstableFlags, Verbosity, + UnstableFlags, Verbosity, }; use anyhow::Result; diff --git a/src/main.rs b/src/main.rs index cbf7d12e..b34c10b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,6 +156,7 @@ impl TryFrom<&OptimizationFlags> for OptimizationPasses { impl OptimizationPasses { /// Returns the string representation of `OptimizationPasses` + #[cfg(not(feature = "binaryen-as-dependency"))] pub(crate) fn to_str(&self) -> &str { match self { OptimizationPasses::Zero => "0", -- GitLab