diff --git a/src/config_manipulate.rs b/src/config_manipulate.rs index 4501fff..425c86e 100644 --- a/src/config_manipulate.rs +++ b/src/config_manipulate.rs @@ -17,3 +17,14 @@ pub fn append_contract( contract["template_type"] = value(toml::to_string(&template_type)?); Ok(()) } + +pub fn append_workspace_member(doc: &mut Document, name: String) -> Result<()> { + let workspace = doc["workspace"] + .as_table_mut() + .ok_or(anyhow!("no 'workspace' section"))?; + let members = workspace["members"] + .as_array_mut() + .ok_or(anyhow!("no 'members' section"))?; + members.push(name); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index c292132..6be2e60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,11 +21,12 @@ use anyhow::{anyhow, Result}; use checker::Checker; use ckb_tool::ckb_types::core::Capacity; use config::TemplateType; -use config_manipulate::{append_contract, Document}; +use config_manipulate::{append_contract, append_workspace_member, Document}; use deployment::manage::{DeployOption, Manage as DeployManage}; use generator::{new_contract, new_project}; use project_context::{ load_project_context, read_config_file, write_config_file, BuildConfig, BuildEnv, DeployEnv, + CARGO_CONFIG_FILE, CONFIG_FILE, CONTRACTS_DIR, }; use recipe::get_recipe; use tester::Tester; @@ -212,11 +213,24 @@ fn run_cli() -> Result<()> { new_contract(name.to_string(), contracts_path, &signal)?; // rewrite config - println!("Rewrite capsule.toml"); - let config_content = read_config_file()?; - let mut doc = config_content.parse::()?; - append_contract(&mut doc, name, TemplateType::Rust)?; - write_config_file(doc.to_string())?; + { + println!("Rewrite Cargo.toml"); + let mut cargo_path = context.project_path.clone(); + cargo_path.push(CARGO_CONFIG_FILE); + let config_content = read_config_file(&cargo_path)?; + let mut doc = config_content.parse::()?; + append_workspace_member(&mut doc, format!("{}/{}", CONTRACTS_DIR, name))?; + write_config_file(&cargo_path, doc.to_string())?; + } + { + println!("Rewrite capsule.toml"); + let mut config_path = context.project_path.clone(); + config_path.push(CONFIG_FILE); + let config_content = read_config_file(&config_path)?; + let mut doc = config_content.parse::()?; + append_contract(&mut doc, name, TemplateType::Rust)?; + write_config_file(&config_path, doc.to_string())?; + } } ("build", Some(args)) => { let context = load_project_context()?; diff --git a/src/project_context.rs b/src/project_context.rs index 8232175..539a669 100644 --- a/src/project_context.rs +++ b/src/project_context.rs @@ -4,14 +4,14 @@ use anyhow::{anyhow, Result}; use log::error; use std::env; use std::fs; -use std::io::ErrorKind as IOErrorKind; use std::path::{Path, PathBuf}; use std::str::FromStr; -const CONTRACTS_DIR: &str = "contracts"; +pub const CONTRACTS_DIR: &str = "contracts"; const CONTRACTS_BUILD_DIR: &str = "build"; const MIGRATIONS_DIR: &str = "migrations"; -const CONFIG_NAME: &str = "capsule.toml"; +pub const CONFIG_FILE: &str = "capsule.toml"; +pub const CARGO_CONFIG_FILE: &str = "Cargo.toml"; #[derive(Debug, Copy, Clone)] pub enum BuildEnv { @@ -115,35 +115,31 @@ impl Context { } } -pub fn read_config_file() -> Result { - let mut project_path = PathBuf::new(); - project_path.push(env::current_dir()?); - let mut path = project_path.clone(); - path.push(CONFIG_NAME); - match fs::read_to_string(path) { +pub fn read_config_file + std::fmt::Debug>(path: P) -> Result { + match fs::read_to_string(&path) { Ok(content) => Ok(content), - Err(err) if err.kind() == IOErrorKind::NotFound => Err(anyhow!( - "Can't found {}, current directory is not a project", - CONFIG_NAME + Err(err) => Err(anyhow!( + "Can't found {:?}, current directory is not a project. error: {:?}", + path, + err )), - Err(err) => Err(err.into()), } } -pub fn write_config_file(content: String) -> Result<()> { - let mut project_path = PathBuf::new(); - project_path.push(env::current_dir()?); - let mut path = project_path.clone(); - path.push(CONFIG_NAME); +pub fn write_config_file>(path: P, content: String) -> Result<()> { fs::write(path, content)?; Ok(()) } pub fn load_project_context() -> Result { - let content = read_config_file()?; - let config: Config = toml::from_slice(content.as_bytes())?; let mut project_path = PathBuf::new(); project_path.push(env::current_dir()?); + let content = { + let mut config_path = project_path.clone(); + config_path.push(CONFIG_FILE); + read_config_file(config_path)? + }; + let config: Config = toml::from_slice(content.as_bytes())?; Ok(Context { config, project_path, diff --git a/src/recipe/rust.rs b/src/recipe/rust.rs index c79d9f1..f320ae9 100644 --- a/src/recipe/rust.rs +++ b/src/recipe/rust.rs @@ -63,26 +63,27 @@ impl<'a> Rust<'a> { "/code/{}", contract_relative_path.to_str().expect("path") )) - .fix_dir_permission("target".to_string()) - .fix_dir_permission("Cargo.lock".to_string()); + .fix_dir_permission("/code/target".to_string()) + .fix_dir_permission("/code/Cargo.lock".to_string()); cmd.run(build_cmd, &signal)?; Ok(()) } /// build contract pub fn run_build(&self, config: BuildConfig, signal: &Signal) -> Result<()> { - let contract_source_path = self.context.contract_path(&self.contract.name); - // docker cargo build - let mut bin_path = PathBuf::new(); + let mut rel_bin_path = PathBuf::new(); let (bin_dir_prefix, build_cmd_opt) = match config.build_env { BuildEnv::Debug => ("debug", ""), BuildEnv::Release => ("release", "--release"), }; - bin_path.push(format!( + rel_bin_path.push(format!( "target/{}/{}/{}", RUST_TARGET, bin_dir_prefix, &self.contract.name )); + let mut container_bin_path = PathBuf::new(); + container_bin_path.push("/code"); + container_bin_path.push(&rel_bin_path); // run build command let build_cmd = format!( @@ -90,21 +91,19 @@ impl<'a> Rust<'a> { ckb-binary-patcher -i {contract_bin} -o {contract_bin}", rustflags = self.injection_rustflags(config), rust_target = RUST_TARGET, - contract_bin = bin_path.to_str().expect("bin"), + contract_bin = container_bin_path.to_str().expect("bin"), build_env = build_cmd_opt ); self.run(build_cmd, signal)?; // copy to build dir - let contract_source_path = contract_source_path.to_str().expect("path"); + let mut project_bin_path = self.context.project_path.clone(); + project_bin_path.push(&rel_bin_path); let mut target_path = self.context.contracts_build_path(config.build_env); // make sure the dir is exist fs::create_dir_all(&target_path)?; target_path.push(&self.contract.name); - let mut contract_bin_path = PathBuf::new(); - contract_bin_path.push(contract_source_path); - contract_bin_path.push(bin_path); - fs::copy(contract_bin_path, target_path)?; + fs::copy(project_bin_path, target_path)?; Ok(()) } diff --git a/src/tester.rs b/src/tester.rs index f55ca3d..93ac180 100644 --- a/src/tester.rs +++ b/src/tester.rs @@ -23,7 +23,10 @@ impl Tester { .fix_dir_permission("target".to_string()) .fix_dir_permission("Cargo.lock".to_string()); cmd.run( - format!("{}={} cargo test -- --nocapture", TEST_ENV_VAR, env_arg), + format!( + "{}={} cargo test -p tests -- --nocapture", + TEST_ENV_VAR, env_arg + ), signal, )?; Ok(()) diff --git a/templates/rust/Cargo.toml b/templates/rust/Cargo.toml index d076790..9998ea6 100644 --- a/templates/rust/Cargo.toml +++ b/templates/rust/Cargo.toml @@ -1,7 +1,9 @@ [workspace] -members = [ - "tests", -] -exclude = [ - "contracts", -] +members = ["tests", "contracts/{{name}}"] + +[profile.release] +overflow-checks = true +opt-level = 's' +lto = true +codegen-units = 1 +panic = 'abort' \ No newline at end of file diff --git a/templates/rust/contract/Cargo.toml b/templates/rust/contract/Cargo.toml index 9334d58..5092685 100644 --- a/templates/rust/contract/Cargo.toml +++ b/templates/rust/contract/Cargo.toml @@ -7,10 +7,3 @@ edition = "2018" [dependencies] ckb-std = "0.6.3" - -[profile.release] -overflow-checks = true -opt-level = 's' -lto = true -codegen-units = 1 -panic = 'abort'