diff --git a/packages/core/package.json b/packages/core/package.json index 8445c8d0b..284041bba 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -16,6 +16,7 @@ "prepublish": "rimraf artifacts cache dist *.tsbuildinfo", "prepare": "tsc -b && yarn prepare:contracts", "prepare:contracts": "hardhat compile", + "prepublishOnly": "bash scripts/copy-artifacts.sh", "test": "tsc -b && hardhat compile --force && ava", "test:watch": "hardhat compile --force && fgbg 'ava --watch' 'tsc -b --watch'", "version": "node ../../scripts/bump-changelog.js" diff --git a/packages/core/scripts/copy-artifacts.sh b/packages/core/scripts/copy-artifacts.sh new file mode 100644 index 000000000..7007bdff6 --- /dev/null +++ b/packages/core/scripts/copy-artifacts.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# copies proxy artifacts to the location they were until 1.3.0 for backwards compatibility with truffle plugin + +cp artifacts/contracts/proxy/{AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json,ProxyAdmin.sol/ProxyAdmin.json} artifacts diff --git a/packages/core/src/validate.test.ts b/packages/core/src/validate.test.ts index 7df597048..c7a94c5ff 100644 --- a/packages/core/src/validate.test.ts +++ b/packages/core/src/validate.test.ts @@ -8,12 +8,12 @@ import { getContractVersion, assertUpgradeSafe, ValidationOptions, - ValidationLog, + RunValidation, } from './validate'; import { solcInputOutputDecoder } from './src-decoder'; interface Context { - validations: ValidationLog; + validation: RunValidation; } const test = _test as TestInterface; @@ -26,21 +26,21 @@ test.before(async t => { const solcOutput = buildInfo.output; const solcInput = buildInfo.input; const decodeSrc = solcInputOutputDecoder(solcInput, solcOutput); - t.context.validations = [validate(solcOutput, decodeSrc)]; + t.context.validation = validate(solcOutput, decodeSrc); }); function testValid(name: string, valid: boolean) { test(name, t => { - const version = getContractVersion(t.context.validations, name, 0); - t.is(isUpgradeSafe(t.context.validations, version), valid); + const version = getContractVersion(t.context.validation, name); + t.is(isUpgradeSafe([t.context.validation], version), valid); }); } function testOverride(name: string, opts: ValidationOptions, valid: boolean) { const testName = name.concat(valid ? '_Allowed' : '_NotAllowed'); test(testName, t => { - const version = getContractVersion(t.context.validations, name, 0); - const assertUpgSafe = () => assertUpgradeSafe(t.context.validations, version, opts); + const version = getContractVersion(t.context.validation, name); + const assertUpgSafe = () => assertUpgradeSafe([t.context.validation], version, opts); if (valid) { t.notThrows(assertUpgSafe); } else { @@ -83,8 +83,8 @@ testValid('ParentHasEnum', false); testValid('UsesLibraryWithEnum', false); test('inherited storage', t => { - const version = getContractVersion(t.context.validations, 'StorageInheritChild', 0); - const layout = getStorageLayout(t.context.validations, version); + const version = getContractVersion(t.context.validation, 'StorageInheritChild'); + const layout = getStorageLayout([t.context.validation], version); t.is(layout.storage.length, 8); for (let i = 0; i < layout.storage.length; i++) { t.is(layout.storage[i].label, `v${i}`); diff --git a/packages/core/src/validate.ts b/packages/core/src/validate.ts index c599a989c..826a73f37 100644 --- a/packages/core/src/validate.ts +++ b/packages/core/src/validate.ts @@ -13,6 +13,14 @@ import { isNullish } from './utils/is-nullish'; export type ValidationLog = RunValidation[]; export type RunValidation = Record; +// upgrades-core@1.3.0 introduced ValidationLog but for compatibility with ^1.0.0 +// the functions exported by this module also accept a single RunValidation +type Validations = ValidationLog | RunValidation; + +// aliases for backwards compatibility with ^1.0.0 +export type Validation = RunValidation; +export type ValidationResult = ContractValidation; + export interface ContractValidation { version?: Version; inherit: string[]; @@ -121,19 +129,21 @@ export function validate(solcOutput: SolcOutput, decodeSrc: SrcDecoder): RunVali return validation; } -export function getContractVersion(validations: ValidationLog, contractName: string, compilationRun: number): Version { - const { version } = validations[compilationRun][contractName]; +export function getContractVersion(validation: RunValidation, contractName: string): Version { + const { version } = validation[contractName]; if (version === undefined) { throw new Error(`Contract ${contractName} is abstract`); } return version; } -export function getContractNameAndRunValidation(validations: ValidationLog, version: Version): [string, RunValidation] { +export function getContractNameAndRunValidation(validations: Validations, version: Version): [string, RunValidation] { + const validationLog = Array.isArray(validations) ? validations : [validations]; + let runValidation; let contractName; - for (const validation of validations) { + for (const validation of validationLog) { contractName = Object.keys(validation).find( name => validation[name].version?.withMetadata === version.withMetadata, ); @@ -150,7 +160,7 @@ export function getContractNameAndRunValidation(validations: ValidationLog, vers return [contractName, runValidation]; } -export function getStorageLayout(validations: ValidationLog, version: Version): StorageLayout { +export function getStorageLayout(validations: Validations, version: Version): StorageLayout { const [contractName, runValidation] = getContractNameAndRunValidation(validations, version); const c = runValidation[contractName]; const layout: StorageLayout = { storage: [], types: {} }; @@ -161,8 +171,10 @@ export function getStorageLayout(validations: ValidationLog, version: Version): return layout; } -export function getUnlinkedBytecode(validations: ValidationLog, bytecode: string): string { - for (const validation of validations) { +export function getUnlinkedBytecode(validations: Validations, bytecode: string): string { + const validationLog = Array.isArray(validations) ? validations : [validations]; + + for (const validation of validationLog) { const linkableContracts = Object.keys(validation).filter(name => validation[name].linkReferences.length > 0); for (const name of linkableContracts) { @@ -179,7 +191,7 @@ export function getUnlinkedBytecode(validations: ValidationLog, bytecode: string return bytecode; } -export function assertUpgradeSafe(validations: ValidationLog, version: Version, opts: ValidationOptions): void { +export function assertUpgradeSafe(validations: Validations, version: Version, opts: ValidationOptions): void { const [contractName] = getContractNameAndRunValidation(validations, version); let errors = getErrors(validations, version); @@ -314,7 +326,7 @@ function describeError(e: ValidationError): string { return log.join('\n '); } -export function getErrors(validations: ValidationLog, version: Version): ValidationError[] { +export function getErrors(validations: Validations, version: Version): ValidationError[] { const [contractName, runValidation] = getContractNameAndRunValidation(validations, version); const c = runValidation[contractName]; return c.errors @@ -322,7 +334,7 @@ export function getErrors(validations: ValidationLog, version: Version): Validat .concat(...c.libraries.map(name => runValidation[name].errors)); } -export function isUpgradeSafe(validations: ValidationLog, version: Version): boolean { +export function isUpgradeSafe(validations: Validations, version: Version): boolean { return getErrors(validations, version).length == 0; }