secret-polar-reworks
Version:
Polar is a development environment to compile, deploy, test, run scrt contracts on different networks.
156 lines (135 loc) • 4.91 kB
text/typescript
import chalk from "chalk";
import { execSync } from "child_process";
import { readdirSync } from "fs";
import fs from "fs-extra";
import path from "path";
import { PolarError } from "../../internal/core/errors";
import { ERRORS } from "../../internal/core/errors-list";
import {
ARTIFACTS_DIR,
assertDir,
CACHE_DIR,
CONTRACTS_DIR,
SCHEMA_DIR,
TARGET_DIR
} from "../../internal/core/project-structure";
import { replaceAll } from "../../internal/util/strings";
export async function compile (
docker: boolean,
sourceDir: string[],
force: boolean,
skipSchema: boolean
): Promise<void> {
await assertDir(CACHE_DIR);
let contractDirs: string[] = [];
const toml = "Cargo.toml";
// Contract(s) path given
if (sourceDir.length > 0) {
contractDirs = sourceDir;
} else {
const paths = readdirSync(CONTRACTS_DIR);
// Only one contract in the contracts dir and compile in contracts dir only
if (paths.includes(toml)) {
contractDirs.push(CONTRACTS_DIR);
} else {
// Multiple contracts and each should be compiled by going inside each of them
const contractNames = new Set();
for (const p of paths) {
const contractPath = path.join(CONTRACTS_DIR, path.basename(p));
const val = readContractName(path.join(contractPath, toml));
// Check for similar contract names before compiling contracts.
// For contract with same names raise an error.
if (contractNames.has(val)) {
throw new PolarError(ERRORS.GENERAL.SAME_CONTRACT_NAMES, {
val
});
} else {
contractNames.add(readContractName(path.join(contractPath, toml)));
contractDirs.push(contractPath);
}
}
}
}
for (const dir of contractDirs) {
compileContract(dir, docker);
if (!skipSchema) { // only generate schema if this flag is not passed
generateSchema(dir, docker);
}
const contractName = readContractName(path.join(dir, toml));
createArtifacts(
TARGET_DIR, path.join(SCHEMA_DIR, contractName), path.join(ARTIFACTS_DIR, CONTRACTS_DIR), path.join(dir, "schema"), docker, skipSchema
);
}
}
export function readContractName (tomlFilePath: string): string {
const tomlFileContent: string = fs.readFileSync(tomlFilePath, 'utf-8');
return replaceAll(tomlFileContent.split('\n')[1].split("\"")[1], '-', '_');
}
export function compileContract (contractDir: string, docker: boolean): void {
const currDir = process.cwd();
process.chdir(contractDir);
console.log(`🛠 Compiling your contract in directory: ${chalk.gray(contractDir)}`);
console.log("===========================================");
// Compiles the contract and creates .wasm file alongside others
try {
execSync(`RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown`, { stdio: 'inherit' });
} catch (error) {
if (error instanceof Error) {
throw new PolarError(ERRORS.GENERAL.RUST_COMPILE_ERROR);
} else {
throw error;
}
}
process.chdir(currDir);
}
export function generateSchema (contractDir: string, docker: boolean): void {
const currDir = process.cwd();
process.chdir(contractDir);
console.log(`Creating schema for contract in directory: ${chalk.gray(contractDir)}`);
// Creates schema .json files
execSync(`cargo run --example schema`, { stdio: 'inherit' });
process.chdir(currDir);
}
export function createArtifacts (
targetDir: string,
schemaDir: string,
artifactsDir: string,
sourceSchemaDir: string,
docker: boolean,
skipSchema: boolean
): void {
const paths = fs.readdirSync(targetDir);
// create nested dirs if not present
if (!fs.existsSync(artifactsDir)) {
fs.mkdirSync(artifactsDir, { recursive: true });
}
if (!fs.existsSync(schemaDir)) {
fs.mkdirSync(schemaDir, { recursive: true });
}
for (const p of paths) {
const filename = path.basename(p);
if (filename.split('.')[filename.split('.').length - 1] !== "wasm") {
continue;
}
console.log(`Copying file ${filename} from ${chalk.gray(targetDir)} to ${chalk.gray(artifactsDir)}`);
const sourcePath = path.resolve(targetDir, filename);
const destPath = path.resolve(artifactsDir, filename);
fs.copyFileSync(sourcePath, destPath);
}
if (skipSchema) { // do not copy schema to artifacts as there is none
return;
}
const schemaPaths = fs.readdirSync(sourceSchemaDir);
for (const p of schemaPaths) {
const filename = path.basename(p);
if (filename.split('.')[filename.split('.').length - 1] !== "json") {
continue;
}
console.log(
`Copying file ${filename} from ${chalk.gray(sourceSchemaDir)} to ${chalk.gray(schemaDir)}`
);
const sourcePath = path.resolve(sourceSchemaDir, filename);
const destPath = path.resolve(schemaDir, filename);
fs.copyFileSync(sourcePath, destPath);
}
}