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 7db2eed05..dbca57c3d 100644 Binary files a/packages/core/src/cli/cli.test.ts.snap and b/packages/core/src/cli/cli.test.ts.snap differ 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