use std::{path::PathBuf, sync::LazyLock};
use crate::{
common::{self, BASE_64_CT, CL_CONTRACT, CL_TYPES, PATCH_SECTION},
ARGS,
};
const PACKAGE_NAME: &str = "contract";
static CONTRACT_PACKAGE_ROOT: LazyLock<PathBuf> =
LazyLock::new(|| ARGS.root_path().join(PACKAGE_NAME.replace('-', "_")));
static CARGO_TOML: LazyLock<PathBuf> = LazyLock::new(|| CONTRACT_PACKAGE_ROOT.join("Cargo.toml"));
static MAIN_RS: LazyLock<PathBuf> = LazyLock::new(|| CONTRACT_PACKAGE_ROOT.join("src/main.rs"));
static CONFIG_TOML: LazyLock<PathBuf> =
LazyLock::new(|| CONTRACT_PACKAGE_ROOT.join(".cargo/config.toml"));
static RUST_TOOLCHAIN: LazyLock<PathBuf> =
LazyLock::new(|| CONTRACT_PACKAGE_ROOT.join("rust-toolchain"));
static CONTRACT_DEPENDENCIES: LazyLock<String> = LazyLock::new(|| {
format!(
"{}{}{}",
CL_CONTRACT.display_with_features(true, vec![]),
CL_TYPES.display_with_features(true, vec![]),
BASE_64_CT.display_with_features(true, vec![]),
)
});
const CONFIG_TOML_CONTENTS: &str = r#"[build]
target = "wasm32-unknown-unknown"
"#;
static CARGO_TOML_CONTENTS: LazyLock<String> = LazyLock::new(|| {
format!(
r#"[package]
name = "{}"
version = "0.1.0"
edition = "2021"
[dependencies]
{}
[[bin]]
name = "{}"
path = "src/main.rs"
bench = false
doctest = false
test = false
[profile.release]
codegen-units = 1
lto = true
{}"#,
PACKAGE_NAME,
&*CONTRACT_DEPENDENCIES,
PACKAGE_NAME.replace('-', "_"),
&*PATCH_SECTION
)
});
const MAIN_RS_CONTENTS: &str = include_str!("../resources/main.rs.in");
const RUST_TOOLCHAIN_CONTENTS: &str = include_str!("../resources/rust-toolchain.in");
pub fn create() {
let src_folder = MAIN_RS.parent().expect("should have parent");
common::create_dir_all(src_folder);
common::write_file(&*MAIN_RS, MAIN_RS_CONTENTS);
let config_folder = CONFIG_TOML.parent().expect("should have parent");
common::create_dir_all(config_folder);
common::write_file(&*CONFIG_TOML, CONFIG_TOML_CONTENTS);
common::write_file(&*CARGO_TOML, &*CARGO_TOML_CONTENTS);
common::write_file(&*RUST_TOOLCHAIN, RUST_TOOLCHAIN_CONTENTS);
}
#[cfg(test)]
mod tests {
use std::env;
use reqwest::blocking;
use super::RUST_TOOLCHAIN_CONTENTS;
const TEST_BRANCH_NAME: &str = "dev";
const CRON_JOB_BRANCH_NAME_ENV_VAR: &str = "BRANCH_SELECTOR";
const PR_TARGET_BRANCH_NAME_ENV_VAR: &str = "GITHUB_BASE_REF";
const CI_BRANCH_NAME_ENV_VAR: &str = "GITHUB_REF_NAME";
const CASPER_NODE_TOOLCHAIN_URL: &str =
"https://raw.githubusercontent.com/casper-network/casper-node/a7e4ff100549d6b34aa6b800812f29313378663b/smart_contracts/rust-toolchain";
#[test]
fn check_toolchain_version_on_dev() {
if let Ok(true) = env::var(CRON_JOB_BRANCH_NAME_ENV_VAR)
.or_else(|_| env::var(PR_TARGET_BRANCH_NAME_ENV_VAR))
.or_else(|_| env::var(CI_BRANCH_NAME_ENV_VAR))
.map(|env_var| env_var == TEST_BRANCH_NAME)
{
} else {
println!(
"skipping 'check_toolchain_version_on_dev' as none of {}, {} and {} are set to {}",
CRON_JOB_BRANCH_NAME_ENV_VAR,
PR_TARGET_BRANCH_NAME_ENV_VAR,
CI_BRANCH_NAME_ENV_VAR,
TEST_BRANCH_NAME,
);
return;
}
let expected_toolchain_value = blocking::get(CASPER_NODE_TOOLCHAIN_URL)
.expect("should get rust-toolchain from GitHub")
.text()
.expect("should parse rust-toolchain");
assert_eq!(&*expected_toolchain_value, RUST_TOOLCHAIN_CONTENTS);
}
}