Skip to content
This repository was archived by the owner on Jan 24, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions packages/cli/src/models/dependency/Dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export default class Dependency {
}

static satisfiesVersion(version, requirement) {
return !requirement || version === requirement || semver.satisfies(version, requirement);
return !requirement
|| version === requirement
|| semver.satisfies(version, requirement);
}

static async install(nameAndVersion) {
Expand All @@ -28,11 +30,17 @@ export default class Dependency {
this.name = name
this._networkFiles = {}

const packageVersion = this.getPackageFile().version
this._validateSatisfiesVersion(packageVersion, requirement)
this.version = packageVersion
this.nameAndVersion = `${name}@${packageVersion}`
this.requirement = requirement || tryWithCaret(packageVersion)
const zosVersion = this.getPackageFile().version
const npmVersion = this.getNpmFile().version
this._validateSatisfiesNpmVersion(npmVersion, requirement)

this.version = npmVersion
this.npmRequirement = requirement || tryWithCaret(npmVersion)
this.zosRequirement = tryWithCaret(zosVersion)
}

get requirement() {
return this.npmRequirement
}

async deploy(txParams) {
Expand Down Expand Up @@ -64,6 +72,17 @@ export default class Dependency {
return project
}

getNpmFile() {
if (!this._npmFile) {
const filename = `node_modules/${this.name}/package.json`
if (!fs.exists(filename)) {
throw Error(`Could not find a package.json file for '${this.name}'.`)
}
this._npmFile = fs.parseJson(filename);
}
return this._npmFile
}

getPackageFile() {
if (!this._packageFile) {
const filename = `node_modules/${this.name}/zos.json`
Expand All @@ -83,7 +102,7 @@ export default class Dependency {
}

this._networkFiles[network] = new ZosNetworkFile(this.getPackageFile(), network, filename)
this._validateSatisfiesVersion(this._networkFiles[network].version, this.requirement)
this._validateSatisfiesNetworkVersion(this._networkFiles[network].version, this.zosRequirement, network)
}
return this._networkFiles[network]
}
Expand All @@ -98,9 +117,15 @@ export default class Dependency {
return `node_modules/${this.name}/zos.${network}.json`
}

_validateSatisfiesVersion(version, requirement) {
_validateSatisfiesNpmVersion(version, requirement) {
if (!Dependency.satisfiesVersion(version, requirement)) {
throw Error(`Dependency ${this.name} requires package version ${requirement}, but ${version} was found. Please update ${this.name} package to the required version.`);
}
}

_validateSatisfiesNetworkVersion(version, requirement, network) {
if (!Dependency.satisfiesVersion(version, requirement)) {
throw Error(`Required dependency version ${requirement} does not match version ${version}`);
throw Error(`Dependency ${this.name} defines version ${semver.coerce(requirement)}, but ${version} was found for network ${network}.`);
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions packages/cli/test/mocks/mock-stdlib/zos.invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": "1.0.0",
"zosversion": "2",
"provider": {
"address": "0x0000000000000000000000000000000000000010"
},
"package": {
"address": "0x0000000000000000000000000000000000000080"
},
"contracts": {
"Greeter": {
"address": "0x1020",
"bytecodeHash": "0x0001"
}
}
}
10 changes: 8 additions & 2 deletions packages/cli/test/models/Dependency.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract('Dependency', function([_, from]) {
describe('#constructor', function() {
context('with invalid version', function() {
it('throws an error',function() {
assertErrorMessage(() => new Dependency('mock-stdlib', '1.2.0'), /does not match version/)
assertErrorMessage(() => new Dependency('mock-stdlib', '1.2.0'), /requires package version 1\.2\.0/)
})
})

Expand Down Expand Up @@ -115,11 +115,17 @@ contract('Dependency', function([_, from]) {
})

context('for an existent network', function() {
it ('generates network file', function() {
it ('returns network file', function() {
const networkFile = this.dependency.getNetworkFile('test')
networkFile.fileName.should.eq('node_modules/mock-stdlib/zos.test.json')
})
})

context('on a mismatching version', function() {
it('throws an error', function() {
assertErrorMessage(() => this.dependency.getNetworkFile('invalid'), /defines version 1\.1\.0/)
})
})
})
})

Expand Down
9 changes: 5 additions & 4 deletions packages/cli/test/scripts/link.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ contract('link script', function() {
.should.be.rejectedWith('Package projects cannot use other packages.');
});

it('should raise an error if requested version of dependency does not match its package version', async function () {
await linkLibs({ libs: ['mock-stdlib-invalid@1.0.0'], packageFile: this.packageFile })
.should.be.rejectedWith('Required dependency version 1.0.0 does not match version 2.0.0')
it('should allow mismatching npm and zos versions', async function () {
// mock-stdlib-invalid has npm version 1.1.0 but zos version 2.0.0
await linkLibs({ libs: ['mock-stdlib-invalid@1.1.0'], packageFile: this.packageFile });
this.shouldHaveDependency('mock-stdlib', '1.1.0');
});

it('should install the dependency if a valid version range is requested', async function () {
Expand All @@ -73,7 +74,7 @@ contract('link script', function() {

it('should raise an error if requested version range does not match its package version', async function () {
await linkLibs({ libs: ['mock-stdlib@~1.0.0'], packageFile: this.packageFile })
.should.be.rejectedWith('Required dependency version ~1.0.0 does not match version 1.1.0')
.should.be.rejectedWith('mock-stdlib requires package version ~1.0.0, but 1.1.0 was found.')
});

it('should raise an error if requested version of dependency lacks zosversion identifier', async function () {
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/test/scripts/push.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ contract('push script', function([_, owner]) {
const mockStdlibPackage = new ZosPackageFile('test/mocks/mock-stdlib/zos.json');
mockStdlibPackage.version = newVersion;
sinon.stub(Dependency.prototype, 'getPackageFile').callsFake(() => mockStdlibPackage);
sinon.stub(Dependency.prototype, 'getNpmFile').callsFake(() => ({ version: '1.2.0' }));

await this.dependencyPackage.newVersion(newVersion)
this.dependencyGetNetworkFileStub.callsFake(() => ({ packageAddress: this.dependencyPackage.address, version: newVersion }));
Expand Down Expand Up @@ -436,7 +437,7 @@ contract('push script', function([_, owner]) {

it('should fail to push', async function () {
await push({ network, txParams, networkFile: this.networkFile })
.should.be.rejectedWith(/Required dependency version 1.0.0 does not match version 2.0.0/)
.should.be.rejectedWith(/requires package version 1.0.0, but 1.1.0 was found/)
});
})

Expand Down