123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- import { ethers } from "ethers"
- import * as fs from "fs"
- import * as path from "path"
- import { config } from "dotenv"
- // 环境配置接口
- interface EnvConfig {
- name: string
- rpcUrl: string
- chainId: number
- envFile: string
- outputDir: string
- description: string
- }
- // 预定义的环境配置
- const ENVIRONMENTS: { [key: string]: EnvConfig } = {
- hardhat: {
- name: "hardhat",
- rpcUrl: "http://127.0.0.1:8545",
- chainId: 31337,
- envFile: ".env.hardhat",
- outputDir: "./output/hardhat",
- description: "Hardhat本地环境"
- },
- bsctest: {
- name: "bsctest",
- rpcUrl: "https://data-seed-prebsc-1-s1.binance.org:8545/",
- chainId: 97,
- envFile: ".env.bsctest",
- outputDir: "./output/bsctest",
- description: "BSC测试网环境"
- },
- bscmainnet: {
- name: "bscmainnet",
- rpcUrl: "https://bsc-dataseed1.binance.org/",
- chainId: 56,
- envFile: ".env.bscmainnet",
- outputDir: "./output/bscmainnet",
- description: "BNB主网环境"
- }
- }
- // 脚本配置接口
- interface ScriptConfig {
- name: string
- script: string
- description: string
- }
- // 可用的脚本列表
- const AVAILABLE_SCRIPTS: ScriptConfig[] = [
- { name: "01:deploy", script: "01-deploy-contracts.ts", description: "部署合约" },
- { name: "02:distribute", script: "02-distribute-tokens.ts", description: "分发代币" },
- { name: "03:init", script: "03-init-sale.ts", description: "初始化销售" },
- { name: "04:contribute", script: "04-test-contributions.ts", description: "测试贡献" },
- { name: "05:claim", script: "05-test-claiming.ts", description: "测试领取" },
- { name: "test", script: "test-env.ts", description: "测试环境配置" }
- ]
- function printUsage() {
- console.log("🚀 多环境脚本执行器")
- console.log("\n📋 使用方法:")
- console.log(" npm run env <environment> <script>")
- console.log(" npm run env <environment> <script> [options]")
-
- console.log("\n🌍 可用环境:")
- Object.entries(ENVIRONMENTS).forEach(([key, env]) => {
- console.log(` ${key.padEnd(10)} - ${env.description}`)
- })
-
- console.log("\n📜 可用脚本:")
- AVAILABLE_SCRIPTS.forEach(script => {
- console.log(` ${script.name.padEnd(12)} - ${script.description}`)
- })
-
- console.log("\n💡 示例:")
- console.log(" npm run env hardhat 01:deploy")
- console.log(" npm run env bsctest 03:init")
- console.log(" npm run env bscmainnet 01:deploy")
- console.log(" npm run env hardhat 04:contribute SCENARIO=1")
-
- console.log("\n📁 输出目录:")
- Object.entries(ENVIRONMENTS).forEach(([key, env]) => {
- console.log(` ${key.padEnd(10)} - ${env.outputDir}`)
- })
- }
- function validateEnvironment(envName: string): EnvConfig {
- const env = ENVIRONMENTS[envName]
- if (!env) {
- console.error(`❌ 错误:未知环境 '${envName}'`)
- console.log("\n可用环境:")
- Object.keys(ENVIRONMENTS).forEach(key => console.log(` - ${key}`))
- process.exit(1)
- }
- return env
- }
- function validateScript(scriptName: string): ScriptConfig {
- const script = AVAILABLE_SCRIPTS.find(s => s.name === scriptName)
- if (!script) {
- console.error(`❌ 错误:未知脚本 '${scriptName}'`)
- console.log("\n可用脚本:")
- AVAILABLE_SCRIPTS.forEach(s => console.log(` - ${s.name}`))
- process.exit(1)
- }
- return script
- }
- function setupEnvironment(env: EnvConfig) {
- console.log(`\n🌍 切换到环境: ${env.description}`)
- console.log(`📁 输出目录: ${env.outputDir}`)
- console.log(`🔗 RPC地址: ${env.rpcUrl}`)
-
- // 创建输出目录
- if (!fs.existsSync(env.outputDir)) {
- fs.mkdirSync(env.outputDir, { recursive: true })
- console.log(`✅ 创建输出目录: ${env.outputDir}`)
- }
-
- // 加载环境变量
- const envPath = path.resolve(env.envFile)
- if (fs.existsSync(envPath)) {
- // 清除之前的环境变量,然后加载指定的环境文件
- Object.keys(process.env).forEach(key => {
- if (key.startsWith('PRIVATE_KEY') || key.startsWith('RPC_URL') || key.startsWith('CHAIN_ID')) {
- delete process.env[key]
- }
- })
- config({ path: envPath, override: true })
- console.log(`✅ 加载环境文件: ${env.envFile}`)
- } else {
- console.warn(`⚠️ 环境文件不存在: ${env.envFile}`)
- console.log("💡 请创建环境文件或使用默认.env文件")
- }
-
- // 设置环境变量
- process.env.ENVIRONMENT = env.name
- process.env.OUTPUT_DIR = env.outputDir
- process.env.RPC_URL = env.rpcUrl
- process.env.CHAIN_ID = env.chainId.toString()
-
- console.log(`✅ 环境设置完成`)
- }
- async function runScript(script: ScriptConfig, args: string[]) {
- console.log(`\n📜 执行脚本: ${script.description}`)
- console.log(`📄 脚本文件: ${script.script}`)
-
- // 构建脚本路径
- const scriptPath = path.resolve(`./scripts/${script.script}`)
-
- if (!fs.existsSync(scriptPath)) {
- console.error(`❌ 脚本文件不存在: ${scriptPath}`)
- process.exit(1)
- }
-
- // 设置脚本参数
- process.argv = [process.argv[0], process.argv[1], ...args]
-
- try {
- // 动态导入并执行脚本
- const scriptModule = await import(scriptPath)
- if (scriptModule.main) {
- await scriptModule.main()
- } else {
- console.error(`❌ 脚本 ${script.script} 没有导出 main 函数`)
- process.exit(1)
- }
- } catch (error) {
- console.error(`❌ 执行脚本失败:`, error)
- process.exit(1)
- }
- }
- async function main() {
- const args = process.argv.slice(2)
-
- // 显示帮助信息
- if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
- printUsage()
- return
- }
-
- // 解析参数
- const envName = args[0]
- const scriptName = args[1]
- const scriptArgs = args.slice(2)
-
- if (!envName || !scriptName) {
- console.error("❌ 错误:缺少环境或脚本参数")
- printUsage()
- process.exit(1)
- }
-
- // 验证环境
- const env = validateEnvironment(envName)
-
- // 验证脚本
- const script = validateScript(scriptName)
-
- // 设置环境
- setupEnvironment(env)
-
- // 执行脚本
- await runScript(script, scriptArgs)
-
- console.log("\n🎉 脚本执行完成!")
- }
- // 如果直接运行此脚本
- if (require.main === module) {
- main().catch(error => {
- console.error("❌ 执行失败:", error)
- process.exit(1)
- })
- }
- export { main, ENVIRONMENTS, AVAILABLE_SCRIPTS }
|