diff --git a/packages/compilers/src/lib/common.ts b/packages/compilers/src/lib/common.ts index 94ab331b2..98a1c7354 100644 --- a/packages/compilers/src/lib/common.ts +++ b/packages/compilers/src/lib/common.ts @@ -74,9 +74,15 @@ export function asyncExec( if (error) { reject(error); } else if (stderr) { - reject( - new Error(`Compiler process returned with errors:\n ${stderr}`), - ); + // Vyper compilers <0.4.0 outputs warnings to stderr + // we handle this by checking if the stderr starts with "Warning:" + if (stderr.startsWith('Warning:')) { + resolve(stdout); + } else { + reject( + new Error(`Compiler process returned with errors:\n ${stderr}`), + ); + } } else { resolve(stdout); } diff --git a/packages/compilers/test/vyperCompiler.spec.ts b/packages/compilers/test/vyperCompiler.spec.ts new file mode 100644 index 000000000..0d43fca9d --- /dev/null +++ b/packages/compilers/test/vyperCompiler.spec.ts @@ -0,0 +1,114 @@ +import { expect } from 'chai'; +import { useVyperCompiler } from '../src/lib/vyperCompiler'; +import path from 'path'; + +describe('Verify Vyper Compiler', () => { + const vyperRepoPath = path.join('/tmp', 'vyper-repo'); + + it('Should compile with vyper', async function () { + const compiledJSON = await useVyperCompiler( + vyperRepoPath, + '0.3.7+commit.6020b8bb', + { + language: 'Vyper', + sources: { + 'test.vy': { + content: '@external\ndef test() -> uint256:\n return 42', + }, + }, + settings: { + outputSelection: { + '*': ['*'], + }, + }, + }, + ); + expect(compiledJSON?.contracts?.['test.vy']?.test).to.not.equal(undefined); + }); + + it('Should handle vyper 0.3.10 warnings', async function () { + const compiledJSON = await useVyperCompiler( + vyperRepoPath, + '0.3.10+commit.91361694', + { + language: 'Vyper', + sources: { + 'test.vy': { + content: `@external +@view +def foo(x: uint256, y: int128) -> uint256: + return shift(x, y)`, + }, + }, + settings: { + outputSelection: { + '*': ['*'], + }, + }, + }, + ); + expect(compiledJSON?.contracts?.['test.vy']?.test).to.not.equal(undefined); + // 0.3.10 doesn't include the warnings in the standardJson output + expect(compiledJSON?.errors).to.be.undefined; + }); + + it('Should handle vyper 0.3.10 warnings and errors', async function () { + try { + const compiledJSON = await useVyperCompiler( + vyperRepoPath, + '0.3.10+commit.91361694', + { + language: 'Vyper', + sources: { + 'test.vy': { + content: `@exernal +@view +def foo(x: uint256, y: int128) -> uint256: + return shift(x, y)`, + }, + }, + settings: { + outputSelection: { + '*': ['*'], + }, + }, + }, + ); + expect(compiledJSON?.contracts?.['test.vy']?.test).to.not.equal( + undefined, + ); + } catch (error: any) { + // 0.3.10 doesn't include the warnings in the standardJson output but in the errors + expect(error.errors?.some((e: any) => e.severity === 'warning')).to.be + .false; + expect(error.errors?.some((e: any) => e.severity === 'error')).to.be.true; + } + }); + + it('Should handle vyper 0.4.0 warnings', async function () { + const compiledJSON = await useVyperCompiler( + vyperRepoPath, + '0.4.0+commit.e9db8d9f', + { + language: 'Vyper', + sources: { + 'test.vy': { + content: `@external +@view +def foo(x: uint256, y: int128) -> uint256: + return shift(x, y)`, + }, + }, + settings: { + outputSelection: { + '*': ['*'], + }, + }, + }, + ); + expect(compiledJSON?.contracts?.['test.vy']?.test).to.not.equal(undefined); + // Should still compile successfully despite warnings + expect(compiledJSON?.errors?.some((e) => e.severity === 'warning')).to.be + .true; + }); +});