Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
digorithm committed Jul 2, 2021
2 parents a8c4268 + 9632501 commit 82b6c98
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 46 deletions.
9 changes: 7 additions & 2 deletions forc/src/cli/commands/deploy.rs
@@ -1,8 +1,13 @@
use structopt::{self, StructOpt};

use crate::ops::forc_deploy;

#[derive(Debug, StructOpt)]
pub(crate) struct Command {}
pub struct Command {}

pub(crate) fn exec(command: Command) -> Result<(), String> {
todo!()
match forc_deploy::deploy(command) {
Err(e) => Err(e.message),
_ => Ok(()),
}
}
2 changes: 1 addition & 1 deletion forc/src/cli/mod.rs
Expand Up @@ -10,7 +10,7 @@ use analysis::Command as AnalysisCommand;
use benchmark::Command as BenchmarkCommand;
pub use build::Command as BuildCommand;
use coverage::Command as CoverageCommand;
use deploy::Command as DeployCommand;
pub use deploy::Command as DeployCommand;
pub use format::Command as FormatCommand;
use init::Command as InitCommand;
use mvprun::Command as MvprunCommand;
Expand Down
49 changes: 6 additions & 43 deletions forc/src/ops/forc_build.rs
@@ -1,4 +1,7 @@
use crate::{cli::BuildCommand, utils::helpers::find_manifest_dir};
use crate::{
cli::BuildCommand,
utils::helpers::{find_manifest_dir, get_main_file, read_manifest},
};
use line_col::LineColLookup;
use source_span::{
fmt::{Color, Formatter, Style},
Expand All @@ -9,13 +12,12 @@ use std::io::{self, Write};
use termcolor::{BufferWriter, Color as TermColor, ColorChoice, ColorSpec, WriteColor};

use crate::utils::constants;
use crate::utils::manifest::{Dependency, DependencyDetails, Manifest};
use crate::utils::manifest::{Dependency, DependencyDetails};
use anyhow::{anyhow, Context, Result};
use core_lang::{
BuildConfig, BytecodeCompilationResult, CompilationResult, FinalizedAsm, LibraryExports,
Namespace,
};

use anyhow::{anyhow, Context, Result};
use curl::easy::Easy;
use dirs::home_dir;
use flate2::read::GzDecoder;
Expand Down Expand Up @@ -357,28 +359,6 @@ fn compile_dependency_lib<'source, 'manifest>(
Ok(())
}

fn read_manifest(manifest_dir: &PathBuf) -> Result<Manifest, String> {
let manifest_path = {
let mut man = manifest_dir.clone();
man.push(crate::utils::constants::MANIFEST_FILE_NAME);
man
};
let manifest_path_str = format!("{:?}", manifest_path);
let manifest = match std::fs::read_to_string(manifest_path) {
Ok(o) => o,
Err(e) => {
return Err(format!(
"failed to read manifest at {:?}: {}",
manifest_path_str, e
))
}
};
match toml::from_str(&manifest) {
Ok(o) => Ok(o),
Err(e) => Err(format!("Error parsing manifest: {}.", e)),
}
}

fn compile_library<'source, 'manifest>(
source: &'source str,
proj_name: &str,
Expand Down Expand Up @@ -597,23 +577,6 @@ fn write_yellow(txt: &str) -> io::Result<()> {
Ok(())
}

fn get_main_file(
manifest_of_dep: &Manifest,
manifest_dir: &PathBuf,
) -> Result<&'static mut String, String> {
let main_path = {
let mut code_dir = manifest_dir.clone();
code_dir.push("src");
code_dir.push(&manifest_of_dep.project.entry);
code_dir
};

// some hackery to get around lifetimes for now, until the AST returns a non-lifetime-bound AST
let main_file = fs::read_to_string(&main_path).map_err(|e| e.to_string())?;
let main_file = Box::new(main_file);
let main_file: &'static mut String = Box::leak(main_file);
return Ok(main_file);
}
fn compile_to_asm<'source, 'manifest>(
source: &'source str,
proj_name: &str,
Expand Down
158 changes: 158 additions & 0 deletions forc/src/ops/forc_deploy.rs
@@ -0,0 +1,158 @@
use core_lang::{parse, CompileError};
use fuel_tx::{crypto::hash, ContractAddress, Output, Salt, Transaction};

use crate::cli::DeployCommand;

use crate::ops::forc_build;
use crate::utils::{constants, helpers};
use constants::{MANIFEST_FILE_NAME, SWAY_LIBRARY, SWAY_PREDICATE, SWAY_SCRIPT};
use helpers::{find_manifest_dir, get_main_file, read_manifest};
use std::{fmt, io, path::PathBuf};

use crate::cli::BuildCommand;

pub fn deploy(_: DeployCommand) -> Result<(), DeployError> {
let curr_dir = std::env::current_dir()?;

match find_manifest_dir(&curr_dir) {
Some(manifest_dir) => {
let manifest = read_manifest(&manifest_dir)?;
let project_name = &manifest.project.name;
let main_file = get_main_file(&manifest, &manifest_dir)?;

// parse the main file and check is it a contract
match parse(main_file) {
core_lang::CompileResult::Ok {
value: parse_tree,
warnings: _,
errors: _,
} => {
if let Some(_) = &parse_tree.contract_ast {
let build_command = BuildCommand {
path: None,
print_asm: false,
binary_outfile: None,
offline_mode: false,
};

let compiled_contract = forc_build::build(build_command)?;
let tx = create_contract_tx(compiled_contract);

// todo: pass the transaction to the running node
println!("{:?}", tx);
Ok(())
} else {
let parse_type = {
if parse_tree.script_ast.is_some() {
SWAY_SCRIPT
} else if parse_tree.predicate_ast.is_some() {
SWAY_PREDICATE
} else {
SWAY_LIBRARY
}
};

Err(DeployError::not_a_contract(project_name, parse_type))
}
}
core_lang::CompileResult::Err {
warnings: _,
errors,
} => Err(DeployError::parsing_failed(project_name, errors)),
}
}
None => Err(DeployError::manifest_file_missing(curr_dir)),
}
}

fn create_contract_tx(compiled_contract: Vec<u8>) -> Transaction {
let gas_price = 0;
let gas_limit = 10000000;
let maturity = 0;
let bytecode_witness_index = 0;
let witnesses = vec![compiled_contract.into()];

let salt = Salt::new([0; 32]);
let static_contracts = vec![];
let inputs = vec![];

let zero_hash = hash("0".as_bytes());

let outputs = vec![Output::ContractCreated {
contract_id: ContractAddress::new(zero_hash.into()),
}];

Transaction::create(
gas_price,
gas_limit,
maturity,
bytecode_witness_index,
salt,
static_contracts,
inputs,
outputs,
witnesses,
)
}

pub struct DeployError {
pub message: String,
}

impl DeployError {
fn manifest_file_missing(curr_dir: PathBuf) -> Self {
let message = format!(
"Manifest file not found at {:?}. Project root should contain '{}'",
curr_dir, MANIFEST_FILE_NAME
);
Self { message }
}

fn parsing_failed(project_name: &str, errors: Vec<CompileError>) -> Self {
let message = errors
.iter()
.map(|e| e.to_friendly_error_string())
.collect::<Vec<String>>()
.join("\n");

Self {
message: format!("Parsing {} failed: \n{}", project_name, message),
}
}

fn not_a_contract(project_name: &str, parse_type: &str) -> Self {
let message = format!(
"{} is not a 'contract' it is a '{}'\nContracts should start with 'contract;'",
project_name, parse_type
);
Self { message }
}
}

impl fmt::Display for DeployError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self)
}
}

impl From<&str> for DeployError {
fn from(s: &str) -> Self {
DeployError {
message: s.to_string(),
}
}
}

impl From<String> for DeployError {
fn from(s: String) -> Self {
DeployError { message: s }
}
}

impl From<io::Error> for DeployError {
fn from(e: io::Error) -> Self {
DeployError {
message: e.to_string(),
}
}
}
1 change: 1 addition & 0 deletions forc/src/ops/mod.rs
@@ -1,3 +1,4 @@
pub mod forc_build;
pub mod forc_deploy;
pub mod forc_fmt;
pub mod forc_init;
4 changes: 4 additions & 0 deletions forc/src/utils/constants.rs
@@ -1,3 +1,7 @@
pub const MANIFEST_FILE_NAME: &'static str = "Forc.toml";
pub const SWAY_EXTENSION: &'static str = "sw";
pub const FORC_DEPENDENCIES_DIRECTORY: &'static str = ".forc";
pub const SRC_DIR: &'static str = "src";
pub const SWAY_PREDICATE: &'static str = "predicate";
pub const SWAY_LIBRARY: &'static str = "library";
pub const SWAY_SCRIPT: &'static str = "script";
42 changes: 42 additions & 0 deletions forc/src/utils/helpers.rs
@@ -1,3 +1,5 @@
use super::constants::SRC_DIR;
use super::manifest::Manifest;
use std::path::PathBuf;

// Continually go up in the file tree until a manifest (Forc.toml) is found.
Expand All @@ -16,3 +18,43 @@ pub fn find_manifest_dir(starter_path: &PathBuf) -> Option<PathBuf> {
}
None
}

pub fn read_manifest(manifest_dir: &PathBuf) -> Result<Manifest, String> {
let manifest_path = {
let mut man = manifest_dir.clone();
man.push(crate::utils::constants::MANIFEST_FILE_NAME);
man
};
let manifest_path_str = format!("{:?}", manifest_path);
let manifest = match std::fs::read_to_string(manifest_path) {
Ok(o) => o,
Err(e) => {
return Err(format!(
"failed to read manifest at {:?}: {}",
manifest_path_str, e
))
}
};
match toml::from_str(&manifest) {
Ok(o) => Ok(o),
Err(e) => Err(format!("Error parsing manifest: {}.", e)),
}
}

pub fn get_main_file(
manifest_of_dep: &Manifest,
manifest_dir: &PathBuf,
) -> Result<&'static mut String, String> {
let main_path = {
let mut code_dir = manifest_dir.clone();
code_dir.push(SRC_DIR);
code_dir.push(&manifest_of_dep.project.entry);
code_dir
};

// some hackery to get around lifetimes for now, until the AST returns a non-lifetime-bound AST
let main_file = std::fs::read_to_string(&main_path).map_err(|e| e.to_string())?;
let main_file = Box::new(main_file);
let main_file: &'static mut String = Box::leak(main_file);
return Ok(main_file);
}

0 comments on commit 82b6c98

Please sign in to comment.