diff --git a/script/action/allowlists.ts b/script/action/allowlists.ts index cb4bc1453..4b5cd5202 100644 --- a/script/action/allowlists.ts +++ b/script/action/allowlists.ts @@ -16,9 +16,9 @@ import { formatSortJson } from "../common/json"; import * as bluebird from "bluebird"; import { copyFile } from "fs"; -async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string, string]> { - let errorMsg = ""; - let warningMsg = ""; +async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string[], string[]]> { + let errorMsgs: string[] = []; + let warningMsgs: string[] = []; const assets = getChainAssetsList(chain); const allowlistPath = getChainAllowlistPath(chain); @@ -31,12 +31,12 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro const commonElementsOrDuplicates = findCommonElementsOrDuplicates(currentAllowlist, currentDenylist); if (commonElementsOrDuplicates && commonElementsOrDuplicates.length > 0) { - errorMsg += `Denylist and allowlist for chain ${chain} should have no common elements or duplicates, found ${commonElementsOrDuplicates.length} ${commonElementsOrDuplicates[0]}\n`; + errorMsgs.push(`Denylist and allowlist for chain ${chain} should have no common elements or duplicates, found ${commonElementsOrDuplicates.length} ${commonElementsOrDuplicates[0]}`); } const allowlistOrphan = arrayDiff(currentAllowlist, assets); if (allowlistOrphan && allowlistOrphan.length > 0) { // warning only - warningMsg += `Allowlist for chain ${chain} contains non-exitent assets, found ${allowlistOrphan.length}, ${allowlistOrphan[0]}\n`; + warningMsgs.push(`Allowlist for chain ${chain} contains non-exitent assets, found ${allowlistOrphan.length}, ${allowlistOrphan[0]}`); } const newDeny = makeUnique(currentDenylist.concat(allowlistOrphan)); @@ -47,34 +47,34 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro const wDiff1 = arrayDiffNocase(newAllow, currentAllowlist); if (wDiff1.length > 0) { // warning only - warningMsg += `Some elements are missing from allowlist for chain ${chain}: ${wDiff1.length} ${wDiff1[0]}\n`; + warningMsgs.push(`Some elements are missing from allowlist for chain ${chain}: ${wDiff1.length} ${wDiff1[0]}`); } const wDiff2 = arrayDiffNocase(currentAllowlist, newAllow); if (wDiff2.length > 0) { // warning only - warningMsg += `Some elements should be removed from allowlist for chain ${chain}: ${wDiff2.length} ${wDiff2[0]}\n`; + warningMsgs.push(`Some elements should be removed from allowlist for chain ${chain}: ${wDiff2.length} ${wDiff2[0]}`); } const bDiff1 = arrayDiffNocase(newDeny, currentDenylist); if (bDiff1.length > 0) { - warningMsg += `Some elements are missing from denylist for chain ${chain}: ${bDiff1.length} ${bDiff1[0]}\n`; + warningMsgs.push(`Some elements are missing from denylist for chain ${chain}: ${bDiff1.length} ${bDiff1[0]}`); } const bDiff2 = arrayDiffNocase(currentDenylist, newDeny); if (bDiff2.length > 0) { - warningMsg += `Some elements should be removed from denylist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}\n`; + warningMsgs.push(`Some elements should be removed from denylist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}`); } // additionally check for nice formatting, sorting: const newAllowText = formatSortJson(newAllow); const newDenyText = formatSortJson(newDeny); if (newAllowText !== currentAllowlistText) { - warningMsg += `Allowlist for chain ${chain}: not formatted nicely \n`; + warningMsgs.push(`Allowlist for chain ${chain}: not formatted nicely `); } if (newDenyText !== currentDenylistText) { - warningMsg += `Denylist for chain ${chain}: not formatted nicely \n`; + warningMsgs.push(`Denylist for chain ${chain}: not formatted nicely `); } - if (errorMsg.length > 0 || warningMsg.length > 0) { + if (errorMsgs.length > 0 || warningMsgs.length > 0) { // sg wrong, may need to fix if (!checkOnly) { // update @@ -83,7 +83,7 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro console.log(`Updated allow and denylists for chain ${chain}`); } } - return [(errorMsg.length == 0 && warningMsg.length == 0), errorMsg, warningMsg]; + return [(errorMsgs.length == 0 && warningMsgs.length == 0), errorMsgs, warningMsgs]; } export class Allowlist implements ActionInterface { @@ -98,11 +98,11 @@ export class Allowlist implements ActionInterface { { getName: () => { return `Allowlist and denylist for ${chain} should be consistent with assets`}, check: async () => { - const [isOK, errorMsg, warningMsg] = await checkUpdateAllowDenyList(chain, true); + const [isOK, errorMsgs, warningMsgs] = await checkUpdateAllowDenyList(chain, true); if (!isOK) { - return [errorMsg, warningMsg]; + return [errorMsgs, warningMsgs]; } - return ["", ""]; + return [[], []]; } } ); diff --git a/script/action/binance.ts b/script/action/binance.ts index 0e808c492..6f5fd44eb 100644 --- a/script/action/binance.ts +++ b/script/action/binance.ts @@ -106,16 +106,16 @@ export class BinanceAction implements ActionInterface { { getName: () => { return "Binance chain; assets must exist on chain"}, check: async () => { - var error: string = ""; + var errors = []; const tokenSymbols = await retrieveAssetSymbols(); const assets = readDirSync(getChainAssetsPath(Binance)); assets.forEach(asset => { if (!(tokenSymbols.indexOf(asset) >= 0)) { - error += `Asset ${asset} missing on chain\n`; + errors.push(`Asset ${asset} missing on chain`); } }); console.log(` ${assets.length} assets checked.`); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/cosmos.ts b/script/action/cosmos.ts index f1205e163..9ba7bec88 100644 --- a/script/action/cosmos.ts +++ b/script/action/cosmos.ts @@ -11,22 +11,22 @@ export class CosmosAction implements ActionInterface { { getName: () => { return "Cosmos validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Cosmos); const prefix = "cosmosvaloper1"; const expLength = 52; assets.forEach(addr => { if (!(addr.startsWith(prefix))) { - error += `Address ${addr} should start with '${prefix}'\n`; + errors.push(`Address ${addr} should start with '${prefix}'`); } if (addr.length != expLength) { - error += `Address ${addr} should have length ${expLength}\n`; + errors.push(`Address ${addr} should have length ${expLength}`); } if (!isLowerCase(addr)) { - error += `Address ${addr} should be in lowercase\n`; + errors.push(`Address ${addr} should be in lowercase`); } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/eth-forks.ts b/script/action/eth-forks.ts index 9b3dad785..236fc68b0 100644 --- a/script/action/eth-forks.ts +++ b/script/action/eth-forks.ts @@ -75,29 +75,29 @@ export class EthForks implements ActionInterface { { getName: () => { return `Folder structure for chain ${chain} (ethereum fork)`;}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assetsFolder = getChainAssetsPath(chain); const assetsList = getChainAssetsList(chain); console.log(` Found ${assetsList.length} assets for chain ${chain}`); await bluebird.each(assetsList, async (address) => { const assetPath = `${assetsFolder}/${address}`; if (!isPathExistsSync(assetPath)) { - error += `Expect directory at path: ${assetPath}\n`; + errors.push(`Expect directory at path: ${assetPath}`); } const inChecksum = toChecksum(address, chain); if (address !== inChecksum) { - error += `Expect asset at path ${assetPath} in checksum: '${inChecksum}'\n`; + errors.push(`Expect asset at path ${assetPath} in checksum: '${inChecksum}'`); } const assetLogoPath = getChainAssetLogoPath(chain, address); if (!isPathExistsSync(assetLogoPath)) { - error += `Missing file at path '${assetLogoPath}'\n`; + errors.push(`Missing file at path '${assetLogoPath}'`); } const [isInfoOK, infoMsg] = isAssetInfoOK(chain, address); if (!isInfoOK) { - error += infoMsg + "\n"; + errors.push(infoMsg); } }); - return [error, ""]; + return [errors, []]; } } ); diff --git a/script/action/folders-and-files.ts b/script/action/folders-and-files.ts index 39755eef8..9f89da42d 100644 --- a/script/action/folders-and-files.ts +++ b/script/action/folders-and-files.ts @@ -27,54 +27,54 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Repository root dir"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const dirActualFiles = readDirSync("."); dirActualFiles.forEach(file => { if (!(rootDirAllowedFiles.indexOf(file) >= 0)) { - error += `File "${file}" should not be in root or added to predifined list\n`; + errors.push(`File "${file}" should not be in root or added to predifined list`); } }); - return [error, ""]; + return [errors, []]; } }, { getName: () => { return "Chain folders are lowercase, contain only predefined list of files"}, check: async () => { - var error: string = ""; + var errors: string[] = []; foundChains.forEach(chain => { if (!isLowerCase(chain)) { - error += `Chain folder must be in lowercase "${chain}"\n`; + errors.push(`Chain folder must be in lowercase "${chain}"`); } getChainFolderFilesList(chain).forEach(file => { if (!(chainFolderAllowedFiles.indexOf(file) >= 0)) { - error += `File '${file}' not allowed in chain folder: ${chain}\n`; + errors.push(`File '${file}' not allowed in chain folder: ${chain}`); } }); }); - return [error, ""]; + return [errors, []]; } }, { getName: () => { return "Chain folders have logo, and correct size"}, check: async () => { - var error: string = ""; + var errors: string[] = []; await bluebird.each(foundChains, async (chain) => { const chainLogoPath = getChainLogoPath(chain); if (!isPathExistsSync(chainLogoPath)) { - error += `File missing at path "${chainLogoPath}"\n`; + errors.push(`File missing at path "${chainLogoPath}"`); } const [isOk, error1] = await isLogoOK(chainLogoPath); if (!isOk) { - error += error1 + "\n"; + errors.push(error1); } }); - return [error, ""]; + return [errors, []]; } }, { getName: () => { return "Asset folders contain only predefined set of files"}, check: async () => { - var error: string = ""; + var errors: string[] = []; foundChains.forEach(chain => { const assetsPath = getChainAssetsPath(chain); if (isPathExistsSync(assetsPath)) { @@ -82,13 +82,13 @@ export class FoldersFiles implements ActionInterface { const assetFiles = getChainAssetPath(chain, address) readDirSync(assetFiles).forEach(assetFolderFile => { if (!(assetFolderAllowedFiles.indexOf(assetFolderFile) >= 0)) { - error += `File '${assetFolderFile}' not allowed at this path: ${assetsPath}\n`; + errors.push(`File '${assetFolderFile}' not allowed at this path: ${assetsPath}`); } }); }) ; } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/interface.ts b/script/action/interface.ts index d8e1aec32..e88e313f6 100644 --- a/script/action/interface.ts +++ b/script/action/interface.ts @@ -1,8 +1,8 @@ // A single check step export interface CheckStepInterface { getName(): string; - // return [error, warning], null/"" on success - check(): Promise<[string, string]>; + // return [errors, warnings] + check(): Promise<[string[], string[]]>; } // An action for a check, fix, or update, or a combination. diff --git a/script/action/json.ts b/script/action/json.ts index 318857b1b..eef56b3bf 100644 --- a/script/action/json.ts +++ b/script/action/json.ts @@ -12,17 +12,17 @@ export class JsonAction implements ActionInterface { { getName: () => { return "Check all JSON files to have valid content"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const files = [ ...findFiles(chainsPath, 'json'), ]; await bluebird.each(files, async file => { if (!isValidJSON(file)) { - error += `${file} path contains invalid JSON\n`; + errors.push(`${file} path contains invalid JSON`); } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/kava.ts b/script/action/kava.ts index 868f8c122..1d9fbdf38 100644 --- a/script/action/kava.ts +++ b/script/action/kava.ts @@ -11,22 +11,22 @@ export class KavaAction implements ActionInterface { { getName: () => { return "Kava validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Kava); const prefix = "kavavaloper1"; const expLength = 50; assets.forEach(addr => { if (!(addr.startsWith(prefix))) { - error += `Address ${addr} should start with '${prefix}'\n`; + errors.push(`Address ${addr} should start with '${prefix}'`); } if (addr.length != expLength) { - error += `Address ${addr} should have length ${expLength}\n`; + errors.push(`Address ${addr} should have length ${expLength}`); } if (!isLowerCase(addr)) { - error += `Address ${addr} should be in lowercase\n`; + errors.push(`Address ${addr} should be in lowercase`); } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/logo-size.ts b/script/action/logo-size.ts index 0717275e5..8f022313e 100644 --- a/script/action/logo-size.ts +++ b/script/action/logo-size.ts @@ -16,12 +16,12 @@ import { checkResizeIfTooLarge } from "../common/image"; import { ActionInterface, CheckStepInterface } from "./interface"; // return name of large logo, or empty -async function checkDownsize(chains, checkOnly: boolean): Promise { +async function checkDownsize(chains, checkOnly: boolean): Promise { console.log(`Checking all logos for size ...`); let totalCountChecked: number = 0; let totalCountTooLarge: number = 0; let totalCountUpdated: number = 0; - let largePath = ""; + let largePaths: string[] = []; await bluebird.map(chains, async chain => { let countChecked: number = 0; let countTooLarge: number = 0; @@ -30,7 +30,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise { const path = getChainLogoPath(chain); countChecked++; const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly); - if (tooLarge) { largePath = path; } + if (tooLarge) { largePaths.push(path); } countTooLarge += tooLarge ? 1 : 0; countUpdated += updated ? 1 : 0; @@ -41,7 +41,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise { const path = getChainAssetLogoPath(chain, asset); countChecked++; const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly); - if (tooLarge) { largePath = path; } + if (tooLarge) { largePaths.push(path); } countTooLarge += tooLarge ? 1 : 0; countUpdated += updated ? 1 : 0; }) @@ -55,7 +55,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise { const path = getChainValidatorAssetLogoPath(chain, id); countChecked++; const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly); - if (tooLarge) { largePath = path; } + if (tooLarge) { largePaths.push(path); } countTooLarge += tooLarge ? 1 : 0; countUpdated += updated ? 1 : 0; }) @@ -65,11 +65,11 @@ async function checkDownsize(chains, checkOnly: boolean): Promise { totalCountTooLarge += countTooLarge; totalCountUpdated += countUpdated; if (countTooLarge > 0 || countUpdated > 0) { - console.log(`Checking logos on chain ${chain} completed, ${countChecked} checked, ${countTooLarge} too large, ${largePath}, ${countUpdated} logos updated`); + console.log(`Checking logos on chain ${chain} completed, ${countChecked} checked, ${countTooLarge} too large, ${largePaths}, ${countUpdated} logos updated`); } }); console.log(`Checking logos completed, ${totalCountChecked} logos checked, ${totalCountTooLarge} too large, ${totalCountUpdated} logos updated`); - return largePath; + return largePaths; } export class LogoSize implements ActionInterface { @@ -81,11 +81,9 @@ export class LogoSize implements ActionInterface { getName: () => { return "Check that logos are not too large"}, check: async () => { const foundChains = readDirSync(chainsPath); - var largePath = await checkDownsize(foundChains, true); - if (largePath.length > 0) { - return [`Found at least one logo that is too large: ${largePath}`, ""]; - } - return ["", ""]; + const largePaths = await checkDownsize(foundChains, true); + const errors: string[] = largePaths.map(p => `Logo too large: ${p}`); + return [errors, []]; } }, ]; diff --git a/script/action/terra.ts b/script/action/terra.ts index 651d72be2..c2312a0bb 100644 --- a/script/action/terra.ts +++ b/script/action/terra.ts @@ -11,22 +11,22 @@ export class TerraAction implements ActionInterface { { getName: () => { return "Terra validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Terra); const prefix = "terravaloper1"; const expLength = 51; assets.forEach(addr => { if (!(addr.startsWith(prefix))) { - error += `Address ${addr} should start with '${prefix}'\n`; + errors.push(`Address ${addr} should start with '${prefix}'`); } if (addr.length != expLength) { - error += `Address ${addr} should have length ${expLength}\n`; + errors.push(`Address ${addr} should have length ${expLength}`); } if (!isLowerCase(addr)) { - error += `Address ${addr} should be in lowercase\n`; + errors.push(`Address ${addr} should be in lowercase`); } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/tezos.ts b/script/action/tezos.ts index eed13eacf..b753e8f83 100644 --- a/script/action/tezos.ts +++ b/script/action/tezos.ts @@ -83,14 +83,14 @@ export class TezosAction implements ActionInterface { { getName: () => { return "Tezos validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Tezos); assets.forEach(addr => { if (!(eztz.crypto.checkAddress(addr))) { - error += `Address ${addr} must be valid Tezos address'\n`; + errors.push(`Address ${addr} must be valid Tezos address'`); } }); - return [error, ""]; + return [errors, []]; } }, ]; diff --git a/script/action/tron.ts b/script/action/tron.ts index 257be34bc..58b2f92f8 100644 --- a/script/action/tron.ts +++ b/script/action/tron.ts @@ -25,32 +25,32 @@ export class TronAction implements ActionInterface { { getName: () => { return "Tron assets should be TRC10 or TRC20, logo of correct size"; }, check: async () => { - var error: string = ""; + var errors: string[] = []; const path = getChainAssetsPath(Tron); const assets = readDirSync(path); await bluebird.each(assets, async (asset) => { if (!isTRC10(asset) && !isTRC20(asset)) { - error += `Asset ${asset} at path '${path}' is not TRC10 nor TRC20\n`; + errors.push(`Asset ${asset} at path '${path}' is not TRC10 nor TRC20`); } const assetsLogoPath = getChainAssetLogoPath(Tron, asset); if (!isPathExistsSync(assetsLogoPath)) { - error += `Missing file at path '${assetsLogoPath}'\n`; + errors.push(`Missing file at path '${assetsLogoPath}'`); } }); - return [error, ""]; + return [errors, []]; } }, { getName: () => { return "Tron validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Tron); assets.forEach(addr => { if (!(isTRC20(addr))) { - error += `Address ${addr} should be TRC20 address'\n`; + errors.push(`Address ${addr} should be TRC20 address'`); } }); - return [error, ""]; + return [errors, []]; } } ]; diff --git a/script/action/update-all.ts b/script/action/update-all.ts index 27b0da3c1..af337d80c 100644 --- a/script/action/update-all.ts +++ b/script/action/update-all.ts @@ -32,30 +32,50 @@ const actionList: ActionInterface[] = [ new WavesAction() ]; +const maxErrosFromOneCheck = 5; + async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], string[]]> { - var errors: string[] = []; - var warnings: string[] = []; + var errorsAll: string[] = []; + var warningsAll: string[] = []; await bluebird.each(steps, async (step) => { try { //console.log(` Running check step '${step.getName()}'...`); - const [error, warning] = await step.check(); - if (error && error.length > 0) { - console.log(`- ${chalk.red('X')} '${step.getName()}': '${error}'`); - errors.push(`${step.getName()}: ${error}`); + const [errors, warnings] = await step.check(); + if (errors && errors.length > 0) { + console.log(`- ${chalk.red('X')} '${step.getName()}': ${errors.length} errors`); + var cnt = 0; + errors.forEach(err => { + if (cnt < maxErrosFromOneCheck) { + console.log(` ${chalk.red('X')} '${err}'`); + errorsAll.push(err); + } else if (cnt == maxErrosFromOneCheck) { + console.log(` ${chalk.red('X')} ${errors.length} errors in total, omitting rest ...`); + } + cnt++; + }); } - if (warning && warning.length > 0) { - console.log(`- ${chalk.yellow('!')} '${step.getName()}': '${warning}'`); - warnings.push(`${step.getName()}: ${warning}`); + if (warnings && warnings.length > 0) { + console.log(`- ${chalk.yellow('!')} '${step.getName()}': ${warnings.length} warnings`); + var cnt = 0; + warnings.forEach(warn => { + if (cnt < maxErrosFromOneCheck) { + console.log(` ${chalk.yellow('!')} '${warn}'`); + warningsAll.push(warn); + } else if (cnt == maxErrosFromOneCheck) { + console.log(` ${chalk.red('X')} ${warnings.length} warnings in total, omitting rest ...`); + } + cnt++; + }); } - if (error.length == 0 && warning.length == 0) { + if (errors.length == 0 && warnings.length == 0) { console.log(`- ${chalk.green('✓')} '${step.getName()}' OK`); } } catch (error) { console.log(`- ${chalk.red('X')} '${step.getName()}': Caught error: ${error.message}`); - errors.push(`${step.getName()}: Exception: ${error.message}`); + errorsAll.push(`${step.getName()}: Exception: ${error.message}`); } }); - return [errors, warnings]; + return [errorsAll, warningsAll]; } async function sanityCheckByActionList(actions: ActionInterface[]): Promise<[string[], string[]]> { diff --git a/script/action/validators.ts b/script/action/validators.ts index aca3f26a4..014576842 100644 --- a/script/action/validators.ts +++ b/script/action/validators.ts @@ -37,11 +37,11 @@ export class Validators implements ActionInterface { var steps: CheckStepInterface[] = [ { getName: () => { return "Make sure tests added for new staking chain"}, - check: async (): Promise<[string, string]> => { + check: async (): Promise<[string[], string[]]> => { if (stakingChains.length != 8) { - return [`Wrong number of staking chains ${stakingChains.length}`, ""]; + return [[`Wrong number of staking chains ${stakingChains.length}`], []]; } - return ["", ""]; + return [[], []]; } }, ]; @@ -49,44 +49,44 @@ export class Validators implements ActionInterface { steps.push( { getName: () => { return `Make sure chain ${chain} has valid list file, has logo`}, - check: async () => { + check: async (): Promise<[string[], string[]]> => { const validatorsListPath = getChainValidatorsListPath(chain); if (!isValidJSON(validatorsListPath)) { - return [`Not valid Json file at path ${validatorsListPath}`, ""]; + return [[`Not valid Json file at path ${validatorsListPath}`], []]; } - var error: string = ""; + var errors: string[] = []; const validatorsList = getChainValidatorsList(chain); const chainValidatorsAssetsList = getChainValidatorsAssets(chain); await bluebird.each(validatorsList, async (val: ValidatorModel) => { if (!isValidatorHasAllKeys(val)) { - error += `Some key and/or type missing for validator ${JSON.stringify(val)}\n`; + errors.push(`Some key and/or type missing for validator ${JSON.stringify(val)}`); } const id = val.id; const path = getChainValidatorAssetLogoPath(chain, id); if (!isPathExistsSync(path)) { - error += `Chain ${chain} asset ${id} logo must be present at path ${path}\n`; + errors.push(`Chain ${chain} asset ${id} logo must be present at path ${path}`); } const [isOk, logoMsg] = await isLogoOK(path); if (!isOk) { - error += logoMsg + "\n"; + errors.push(logoMsg); } // Make sure validator has corresponding logo if (!(chainValidatorsAssetsList.indexOf(id) >= 0)) { - error += `Expecting image asset for validator ${id} on chain ${chain}\n`; + errors.push(`Expecting image asset for validator ${id} on chain ${chain}`); } }); // Make sure validator asset logo has corresponding info chainValidatorsAssetsList.forEach(valAssetLogoID => { if (validatorsList.filter(v => v.id === valAssetLogoID).length != 1) { - error += `Expect validator logo ${valAssetLogoID} to have info\n`; + errors.push(`Expect validator logo ${valAssetLogoID} to have info`); } }); - return [error, ""]; + return [errors, []]; } } ); diff --git a/script/action/waves.ts b/script/action/waves.ts index 76a1e96bb..50cd16406 100644 --- a/script/action/waves.ts +++ b/script/action/waves.ts @@ -18,14 +18,14 @@ export class WavesAction implements ActionInterface { { getName: () => { return "Waves validator assets must have correct format"}, check: async () => { - var error: string = ""; + var errors: string[] = []; const assets = getChainValidatorsAssets(Waves); assets.forEach(addr => { if (!(isWavesAddress(addr))) { - error += `Address ${addr} should be a Waves address'\n`; + errors.push(`Address ${addr} should be a Waves address'`); } }); - return [error, ""]; + return [errors, []]; } }, ];