From 1777feec91962d19247fcb73befd4d7f7d7909d8 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Fri, 16 Aug 2024 16:56:06 -0400 Subject: [PATCH] Check for build info in contract name --- packages/core/src/cli/cli.test.ts | 25 ++++++++++++++++-- packages/core/src/cli/cli.test.ts.md | 23 ---------------- packages/core/src/cli/cli.test.ts.snap | Bin 2914 -> 2598 bytes .../core/src/cli/validate/find-contract.ts | 16 ++++++++++- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/packages/core/src/cli/cli.test.ts b/packages/core/src/cli/cli.test.ts index d53988289..305a1ab24 100644 --- a/packages/core/src/cli/cli.test.ts +++ b/packages/core/src/cli/cli.test.ts @@ -422,6 +422,27 @@ test('validate - contract must not have build info dir name', async t => { `${CLI} validate ${updatedDir} --referenceBuildInfoDirs ${referenceDir} --contract build-info:MyContract --reference build-info-v1:MyContract`, ), ); - const expectation: string[] = [`Stdout: ${(error as any).stdout}`, `Stderr: ${(error as any).stderr}`]; - t.snapshot(expectation.join('\n')); + t.true(error?.message.includes('Contract build-info:MyContract must be specified without a build info directory name'), error?.message); }); + +test('validate - contract must not have build info dir name - fully qualified', async t => { + const temp = await getTempDir(t); + const referenceDir = path.join(temp, 'build-info-v1'); + await fs.mkdir(referenceDir); + + const referenceBuildInfo = await artifacts.getBuildInfo(`contracts/test/cli/ValidateBuildInfoV1.sol:MyContract`); + await fs.writeFile(path.join(referenceDir, 'validate.json'), JSON.stringify(referenceBuildInfo)); + + const updatedDir = path.join(temp, 'build-info'); + await fs.mkdir(updatedDir); + + const updatedBuildInfo = await artifacts.getBuildInfo(`contracts/test/cli/ValidateBuildInfoV2_Ok.sol:MyContract`); + await fs.writeFile(path.join(updatedDir, 'validate.json'), JSON.stringify(updatedBuildInfo)); + + const error = await t.throwsAsync( + execAsync( + `${CLI} validate ${updatedDir} --referenceBuildInfoDirs ${referenceDir} --contract build-info:contracts/test/cli/ValidateBuildInfoV2_Ok.sol:MyContract --reference build-info-v1:MyContract`, + ), + ); + t.true(error?.message.includes('Contract build-info:contracts/test/cli/ValidateBuildInfoV2_Ok.sol:MyContract must be specified without a build info directory name'), error?.message); +}); \ No newline at end of file diff --git a/packages/core/src/cli/cli.test.ts.md b/packages/core/src/cli/cli.test.ts.md index 6e5874123..4576c0dd7 100644 --- a/packages/core/src/cli/cli.test.ts.md +++ b/packages/core/src/cli/cli.test.ts.md @@ -380,26 +380,3 @@ Generated by [AVA](https://avajs.dev). FAILED␊ ␊ Stderr: ` - -## validate - contract must not have build info dir name - -> Snapshot 1 - - `Stdout: ␊ - Stderr: /Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/validate/find-contract.js:39␊ - throw new ReferenceContractNotFound(contractName, origin?.fullyQualifiedName, Object.keys(buildInfoDictionary));␊ - ^␊ - ␊ - ReferenceContractNotFound [Error]: Could not find contract build-info:MyContract.␊ - at findContract (/Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/validate/find-contract.js:39:15)␊ - at findSpecifiedContracts (/Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/validate/validate-upgrade-safety.js:53:56)␊ - at validateUpgradeSafety (/Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/validate/validate-upgrade-safety.js:46:32)␊ - at async main (/Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/validate.js:34:24)␊ - at async run (/Users/eric/git/openzeppelin-upgrades/packages/core/dist/cli/cli.js:6:5) {␊ - reference: 'build-info:MyContract',␊ - origin: undefined,␊ - buildInfoDirs: [ '', 'build-info', 'build-info-v1' ]␊ - }␊ - ␊ - Node.js v18.18.2␊ - ` diff --git a/packages/core/src/cli/cli.test.ts.snap b/packages/core/src/cli/cli.test.ts.snap index 7db2eed05ea0b878e584c8a4ab2c3a6c2c9d08f6..dbca57c3dcf0c0ed48081998c40847990f3c19af 100644 GIT binary patch literal 2598 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 MUofl)^lv`^0AW3pNB{r; diff --git a/packages/core/src/cli/validate/find-contract.ts b/packages/core/src/cli/validate/find-contract.ts index 74c962275..af36f6732 100644 --- a/packages/core/src/cli/validate/find-contract.ts +++ b/packages/core/src/cli/validate/find-contract.ts @@ -39,7 +39,12 @@ export function findContract( ) { const foundContracts: SourceContract[] = []; if (onlyMainBuildInfoDir) { - // TODO give error if specified contract has a build info dir name + if (hasBuildInfoDirWithContractName(contractName) || hasBuildInfoDirWithFullyQualifiedName(contractName)) { + throw new ValidateCommandError( + `Contract ${contractName} must be specified without a build info directory name`, + () => `Build info directory names can only be specified for reference contracts.`, + ); + } foundContracts.push(...buildInfoDictionary[''].filter(c => isMatchFound(contractName, c, ''))); } else { for (const [dir, contracts] of Object.entries(buildInfoDictionary)) { @@ -74,3 +79,12 @@ function isMatchFound(contractName: string, foundContract: SourceContract, build `${prefix}${foundContract.fullyQualifiedName}` === contractName || `${prefix}${foundContract.name}` === contractName ); } + +function hasBuildInfoDirWithContractName(contractName: string): boolean { + return contractName.split(':').length === 2 && !contractName.includes('.sol:'); +} + +function hasBuildInfoDirWithFullyQualifiedName(contractName: string): boolean { + const tokens = contractName.split(':'); + return tokens.length === 3 && tokens[1].endsWith('.sol'); +} \ No newline at end of file