Skip to content

Commit

Permalink
Refactor forc_pkg::BuildOptions into its parts (FuelLabs#3166)
Browse files Browse the repository at this point in the history
This is in anticipation of introducing a new `forc-test` library crate
that will contain the logic for building and executing tests. It will
expose a similar `TestOpts` type that shares some of these parts, but
not all.

Also splits up the forc `BuildCommand` for easier sharing between sets
of clap arguments (using the `clap` `flatten` attribute) that require
building a project (e.g. build, test).

Also adds two missing args to the `RunCommand` (`release` and
`build-profile`).

Co-authored-by: Mohammad Fawaz <[email protected]>
  • Loading branch information
mitchmindtree and mohammadfawaz authored Oct 27, 2022
1 parent 4e3e44f commit c0880eb
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 230 deletions.
161 changes: 85 additions & 76 deletions forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,74 @@ pub struct GitSourceIndex {
pub head_with_time: HeadWithTime,
}

#[derive(Default)]
pub struct PkgOpts {
/// Path to the project, if not specified, current working directory will be used.
pub path: Option<String>,
/// Offline mode, prevents Forc from using the network when managing dependencies.
/// Meaning it will only try to use previously downloaded dependencies.
pub offline: bool,
/// Terse mode. Limited warning and error output.
pub terse: bool,
/// Requires that the Forc.lock file is up-to-date. If the lock file is missing, or it
/// needs to be updated, Forc will exit with an error
pub locked: bool,
/// The directory in which the sway compiler output artifacts are placed.
///
/// By default, this is `<project-root>/out`.
pub output_directory: Option<String>,
}

#[derive(Default)]
pub struct PrintOpts {
/// Print the generated Sway AST (Abstract Syntax Tree).
pub ast: bool,
/// Print the finalized ASM.
///
/// This is the state of the ASM with registers allocated and optimisations applied.
pub finalized_asm: bool,
/// Print the generated ASM.
///
/// This is the state of the ASM prior to performing register allocation and other ASM
/// optimisations.
pub intermediate_asm: bool,
/// Print the generated Sway IR (Intermediate Representation).
pub ir: bool,
}

#[derive(Default)]
pub struct MinifyOpts {
/// By default the JSON for ABIs is formatted for human readability. By using this option JSON
/// output will be "minified", i.e. all on one line without whitespace.
pub json_abi: bool,
/// By default the JSON for initial storage slots is formatted for human readability. By using
/// this option JSON output will be "minified", i.e. all on one line without whitespace.
pub json_storage_slots: bool,
}

/// The set of options provided to the `build` functions.
#[derive(Default)]
pub struct BuildOpts {
pub pkg: PkgOpts,
pub print: PrintOpts,
pub minify: MinifyOpts,
/// If set, outputs a binary file representing the script bytes.
pub binary_outfile: Option<String>,
/// If set, outputs source file mapping in JSON format
pub debug_outfile: Option<String>,
/// Name of the build profile to use.
/// If it is not specified, forc will use debug build profile.
pub build_profile: Option<String>,
/// Use release build plan. If a custom release plan is not specified, it is implicitly added to the manifest file.
///
/// If --build-profile is also provided, forc omits this flag and uses provided build-profile.
pub release: bool,
/// Output the time elapsed over each part of the compilation process.
pub time_phases: bool,
/// Include all test functions within the build.
pub tests: bool,
}

impl GitSourceIndex {
pub fn new(time: i64, git_reference: GitReference, commit_hash: String) -> GitSourceIndex {
GitSourceIndex {
Expand Down Expand Up @@ -2038,58 +2106,6 @@ pub fn compile(
}
}

#[derive(Default)]
pub struct BuildOptions {
/// Path to the project, if not specified, current working directory will be used.
pub path: Option<String>,
/// Print the generated Sway AST (Abstract Syntax Tree).
pub print_ast: bool,
/// Print the finalized ASM.
///
/// This is the state of the ASM with registers allocated and optimisations applied.
pub print_finalized_asm: bool,
/// Print the generated ASM.
///
/// This is the state of the ASM prior to performing register allocation and other ASM
/// optimisations.
pub print_intermediate_asm: bool,
/// Print the generated Sway IR (Intermediate Representation).
pub print_ir: bool,
/// If set, outputs a binary file representing the script bytes.
pub binary_outfile: Option<String>,
/// If set, outputs source file mapping in JSON format
pub debug_outfile: Option<String>,
/// Offline mode, prevents Forc from using the network when managing dependencies.
/// Meaning it will only try to use previously downloaded dependencies.
pub offline_mode: bool,
/// Terse mode. Limited warning and error output.
pub terse_mode: bool,
/// The directory in which the sway compiler output artifacts are placed.
///
/// By default, this is `<project-root>/out`.
pub output_directory: Option<String>,
/// By default the JSON for ABIs is formatted for human readability. By using this option JSON
/// output will be "minified", i.e. all on one line without whitespace.
pub minify_json_abi: bool,
/// By default the JSON for initial storage slots is formatted for human readability. By using
/// this option JSON output will be "minified", i.e. all on one line without whitespace.
pub minify_json_storage_slots: bool,
/// Requires that the Forc.lock file is up-to-date. If the lock file is missing, or it
/// needs to be updated, Forc will exit with an error
pub locked: bool,
/// Name of the build profile to use.
/// If it is not specified, forc will use debug build profile.
pub build_profile: Option<String>,
/// Use release build plan. If a custom release plan is not specified, it is implicitly added to the manifest file.
///
/// If --build-profile is also provided, forc omits this flag and uses provided build-profile.
pub release: bool,
/// Output the time elapsed over each part of the compilation process.
pub time_phases: bool,
/// Include all test functions within the build.
pub tests: bool,
}

/// The suffix that helps identify the file which contains the hash of the binary file created when
/// scripts are built_package.
pub const SWAY_BIN_HASH_SUFFIX: &str = "-bin-hash";
Expand All @@ -2100,25 +2116,17 @@ pub const SWAY_BIN_ROOT_SUFFIX: &str = "-bin-root";

pub fn build_package_with_options(
manifest: &PackageManifestFile,
build_options: BuildOptions,
build_options: BuildOpts,
) -> Result<BuiltPackage> {
let key_debug: String = "debug".to_string();
let key_release: String = "release".to_string();

let BuildOptions {
path: _,
let BuildOpts {
pkg,
print,
minify,
binary_outfile,
debug_outfile,
print_ast,
print_finalized_asm,
print_intermediate_asm,
print_ir,
offline_mode,
terse_mode,
output_directory,
minify_json_abi,
minify_json_storage_slots,
locked,
build_profile,
release,
time_phases,
Expand Down Expand Up @@ -2156,15 +2164,15 @@ pub fn build_package_with_options(
);
Default::default()
});
profile.print_ast |= print_ast;
profile.print_ir |= print_ir;
profile.print_finalized_asm |= print_finalized_asm;
profile.print_intermediate_asm |= print_intermediate_asm;
profile.terse |= terse_mode;
profile.print_ast |= print.ast;
profile.print_ir |= print.ir;
profile.print_finalized_asm |= print.finalized_asm;
profile.print_intermediate_asm |= print.intermediate_asm;
profile.terse |= pkg.terse;
profile.time_phases |= time_phases;
profile.include_tests |= tests;

let plan = BuildPlan::from_lock_and_manifest(manifest, locked, offline_mode)?;
let plan = BuildPlan::from_lock_and_manifest(manifest, pkg.locked, pkg.offline)?;

// Build it!
let (built_package, source_map) = build(&plan, &profile)?;
Expand All @@ -2179,7 +2187,8 @@ pub fn build_package_with_options(
}

// Create the output directory for build artifacts.
let output_dir = output_directory
let output_dir = pkg
.output_directory
.map(PathBuf::from)
.unwrap_or_else(|| default_output_directory(manifest.dir()).join(selected_build_profile));
if !output_dir.exists() {
Expand All @@ -2197,7 +2206,7 @@ pub fn build_package_with_options(
.join(&json_abi_program_stem)
.with_extension("json");
let file = File::create(json_abi_program_path)?;
let res = if minify_json_abi {
let res = if minify.json_abi {
serde_json::to_writer(&file, &built_package.json_abi_program)
} else {
serde_json::to_writer_pretty(&file, &built_package.json_abi_program)
Expand All @@ -2216,7 +2225,7 @@ pub fn build_package_with_options(
.join(&json_storage_slots_stem)
.with_extension("json");
let storage_slots_file = File::create(json_storage_slots_path)?;
let res = if minify_json_storage_slots {
let res = if minify.json_storage_slots {
serde_json::to_writer(&storage_slots_file, &built_package.storage_slots)
} else {
serde_json::to_writer_pretty(&storage_slots_file, &built_package.storage_slots)
Expand Down Expand Up @@ -2247,8 +2256,8 @@ pub fn build_package_with_options(
}

/// Builds a project with given BuildOptions
pub fn build_with_options(build_options: BuildOptions) -> Result<Built> {
let path = &build_options.path;
pub fn build_with_options(build_options: BuildOpts) -> Result<Built> {
let path = &build_options.pkg.path;

let this_dir = if let Some(ref path) = path {
PathBuf::from(path)
Expand Down
3 changes: 1 addition & 2 deletions forc-plugins/forc-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fuel-crypto = "0.6"
fuel-gql-client = { version = "0.10", default-features = false }
fuel-tx = { version = "0.18", features = ["builder"] }
fuel-vm = "0.15"
fuels-core = "0.24"
fuels-core = "0.24"
fuels-signers = "0.24"
fuels-types = "0.24"
futures = "0.3"
Expand All @@ -32,7 +32,6 @@ sway-utils = { version = "0.28.1", path = "../../sway-utils" }
tokio = { version = "1.8", features = ["macros", "rt-multi-thread", "process"] }
tracing = "0.1"


[[bin]]
name = "forc-deploy"
path = "src/bin/deploy/main.rs"
Expand Down
54 changes: 32 additions & 22 deletions forc-plugins/forc-client/src/ops/deploy/op.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{bail, Result};
use forc_pkg::{BuildOptions, PackageManifestFile};
use forc_pkg::{self as pkg, PackageManifestFile};
use fuel_gql_client::client::FuelClient;
use fuel_tx::{Output, Salt, TransactionBuilder};
use fuel_vm::prelude::*;
Expand All @@ -25,29 +25,11 @@ pub async fn deploy(command: DeployCommand) -> Result<fuel_tx::ContractId> {
Some(network) => &network.url,
_ => DEFAULT_NODE_URL,
};
let node_url = command.url.unwrap_or_else(|| node_url.to_string());
let node_url = command.url.as_deref().unwrap_or(node_url);
let client = FuelClient::new(node_url)?;

let build_options = BuildOptions {
path: command.path,
print_ast: command.print_ast,
print_finalized_asm: command.print_finalized_asm,
print_intermediate_asm: command.print_intermediate_asm,
print_ir: command.print_ir,
binary_outfile: command.binary_outfile,
offline_mode: command.offline_mode,
debug_outfile: command.debug_outfile,
terse_mode: command.terse_mode,
output_directory: command.output_directory,
minify_json_abi: command.minify_json_abi,
minify_json_storage_slots: command.minify_json_storage_slots,
locked: command.locked,
build_profile: command.build_profile,
release: command.release,
time_phases: command.time_phases,
tests: false,
};
let compiled = forc_pkg::build_package_with_options(&manifest, build_options)?;
let build_opts = build_opts_from_cmd(&command);
let compiled = forc_pkg::build_package_with_options(&manifest, build_opts)?;

let bytecode = compiled.bytecode.clone().into();
let salt = Salt::new([0; 32]);
Expand All @@ -72,3 +54,31 @@ pub async fn deploy(command: DeployCommand) -> Result<fuel_tx::ContractId> {
Err(e) => bail!("{e}"),
}
}

fn build_opts_from_cmd(cmd: &DeployCommand) -> pkg::BuildOpts {
pkg::BuildOpts {
pkg: pkg::PkgOpts {
path: cmd.path.clone(),
offline: cmd.offline_mode,
terse: cmd.terse_mode,
locked: cmd.locked,
output_directory: cmd.output_directory.clone(),
},
print: pkg::PrintOpts {
ast: cmd.print_ast,
finalized_asm: cmd.print_finalized_asm,
intermediate_asm: cmd.print_intermediate_asm,
ir: cmd.print_ir,
},
minify: pkg::MinifyOpts {
json_abi: cmd.minify_json_abi,
json_storage_slots: cmd.minify_json_storage_slots,
},
build_profile: cmd.build_profile.clone(),
release: cmd.release,
time_phases: cmd.time_phases,
binary_outfile: cmd.binary_outfile.clone(),
debug_outfile: cmd.debug_outfile.clone(),
tests: false,
}
}
11 changes: 11 additions & 0 deletions forc-plugins/forc-client/src/ops/run/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ pub struct RunCommand {
#[clap(long)]
pub minify_json_storage_slots: bool,

/// Name of the build profile to use.
/// If it is not specified, forc will use debug build profile.
#[clap(long)]
pub build_profile: Option<String>,

/// Use release build plan. If a custom release plan is not specified, it is implicitly added to the manifest file.
///
/// If --build-profile is also provided, forc omits this flag and uses provided build-profile.
#[clap(long)]
pub release: bool,

/// Set the transaction gas limit. Defaults to the maximum gas limit.
#[clap(long)]
pub gas_limit: Option<u64>,
Expand Down
Loading

0 comments on commit c0880eb

Please sign in to comment.