Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
Rebase master for 2.4.2 (#1115)
Browse files Browse the repository at this point in the history
* Do not fail if contracts folder is missing (#1107)

Fixes #1068

* Handle incorrect keys to loggy (#1112)

* Handle incorrect keys to loggy

When calling Loggy.success with a non-existing key, the reference would not be found, and the call to path.basename in Loggy._log would fail (since its parameter was null). This commit:

- Catches any exceptions in _log, and displays an error (allowing to continue)
- Adds a testing mode to the logger, which is silent but executes logic, and throws an exception upon issues (only to be used in the CLI and lib tests)
- Fixes incorrect or missing keys in calls to the logger

* Remove failing test

* Use require.resolve to lookup contracts in deps (#1110)

* Use chai expect throw syntax in Dependency tests

* Use require.resolve to lookup contracts in deps

Change lookup in both Dependency and Contracts classes. Instead of looking for just node_modules in the current folder, it uses require.resolve (relative to the current workdir) to look for the dependency.

Fixes #1076

* Fix tests

* Add changelogs

* Reset circle cache
  • Loading branch information
spalladino authored and jbcarpanelli committed Jul 18, 2019
1 parent 30edb5e commit 282f449
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 151 deletions.
20 changes: 10 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ defaults: &defaults

aliases:
- restore_cache: &restore-build-cache-lib
keys: ['dependency-cache-v1-build-lib-{{ .Revision }}']
keys: ['dependency-cache-v2-build-lib-{{ .Revision }}']
- restore_cache: &restore-build-cache-cli
keys: ['dependency-cache-v1-build-cli-{{ .Revision }}']
keys: ['dependency-cache-v2-build-cli-{{ .Revision }}']
- restore_cache: &restore-cache-root
keys: ['dependency-cache-v1-root-{{ checksum "package.json" }}', 'dependency-cache-v1-root-']
keys: ['dependency-cache-v2-root-{{ checksum "package.json" }}', 'dependency-cache-v2-root-']
- restore_cache: &restore-cache-lib
keys: ['dependency-cache-v1-lib-{{ checksum "packages/lib/package.json" }}', 'dependency-cache-v1-lib-']
keys: ['dependency-cache-v2-lib-{{ checksum "packages/lib/package.json" }}', 'dependency-cache-v2-lib-']
- restore_cache: &restore-cache-cli
keys: ['dependency-cache-v1-cli-{{ checksum "packages/cli/package.json" }}', 'dependency-cache-v1-cli-']
keys: ['dependency-cache-v2-cli-{{ checksum "packages/cli/package.json" }}', 'dependency-cache-v2-cli-']

commands:

Expand Down Expand Up @@ -106,19 +106,19 @@ jobs:
command: ./node_modules/.bin/lerna bootstrap --loglevel=info --concurrency=4 --scope="zos" --scope="zos-lib"
no_output_timeout: 60m
- save_cache:
key: dependency-cache-v1-root-{{ checksum "package.json" }}
key: dependency-cache-v2-root-{{ checksum "package.json" }}
paths: [node_modules]
- save_cache:
key: dependency-cache-v1-cli-{{ checksum "packages/cli/package.json" }}
key: dependency-cache-v2-cli-{{ checksum "packages/cli/package.json" }}
paths: [packages/cli/node_modules]
- save_cache:
key: dependency-cache-v1-lib-{{ checksum "packages/lib/package.json" }}
key: dependency-cache-v2-lib-{{ checksum "packages/lib/package.json" }}
paths: [packages/lib/node_modules]
- save_cache:
key: dependency-cache-v1-build-cli-{{ .Revision }}
key: dependency-cache-v2-build-cli-{{ .Revision }}
paths: [packages/cli/lib, packages/cli/build]
- save_cache:
key: dependency-cache-v1-build-lib-{{ .Revision }}
key: dependency-cache-v2-build-lib-{{ .Revision }}
paths: [packages/lib/lib, packages/lib/build]

test-lib:
Expand Down
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
},
"devDependencies": {
"lerna": "~3.13.1",
"typescript": "^3.2.2"
"typescript": "^3.2.2",
"mock-stdlib-root": "file:./packages/cli/test/mocks/mock-stdlib"
}
}
7 changes: 7 additions & 0 deletions packages/cli/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## v2.4.2 - 2019-07-18

### Fixed
- Preserve truffle deployment info stored in contract artifacts when compiling. ([#1100](https://github.com/zeppelinos/zos/pull/1100))
- Linked EVM packages lookup works properly when dependencies are hoisted. ([#1110](https://github.com/zeppelinos/zos/pull/1110))
- Do not throw an error if the `contracts` local folder is missing. ([#1107](https://github.com/zeppelinos/zos/pull/1107))

## v2.4.1 - 2019-07-02

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class SolidityProjectCompiler {
}

private _loadSoliditySourcesFromDir(dir = this.inputDir): void {
if (!existsSync(dir) || !lstatSync(dir).isDirectory) return;

// TODO: Replace by a glob expression
readdirSync(dir).forEach(fileName => {
const filePath = path.resolve(dir, fileName);
Expand Down
39 changes: 27 additions & 12 deletions packages/cli/src/models/dependency/Dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,21 @@ export default class Dependency {
}
}

public static hasDependenciesForDeploy(network: string): boolean {
const dependencies = ZosPackageFile.getLinkedDependencies() || [];
public static hasDependenciesForDeploy(
network: string,
packageFilename = 'zos.json',
networkFilename: string = undefined,
): boolean {
const dependencies =
ZosPackageFile.getLinkedDependencies(packageFilename) || [];
const networkDependencies =
ZosNetworkFile.getDependencies(`zos.${network}.json`) || {};
ZosNetworkFile.getDependencies(
networkFilename || `zos.${network}.json`,
) || {};
const hasDependenciesForDeploy = dependencies.find(depNameAndVersion => {
const [name, version] = depNameAndVersion.split('@');
const networkFilePath = `node_modules/${name}/zos.${network}.json`;
const dependency = new Dependency(name);
const networkFilePath = dependency._getNetworkFilePath(network);
const projectDependency = networkDependencies[name];
const satisfiesVersion =
projectDependency &&
Expand Down Expand Up @@ -151,15 +159,16 @@ export default class Dependency {

public getPackageFile(): ZosPackageFile | never {
if (!this._packageFile) {
const filename = `node_modules/${this.name}/zos.json`;
if (!fs.exists(filename)) {
try {
const filename = require.resolve(`${this.name}/zos.json`, {
paths: [process.cwd()],
});
this._packageFile = new ZosPackageFile(filename);
} catch (err) {
throw Error(
`Could not find a zos.json file for '${
this.name
}'. Make sure it is provided by the npm package.`,
`Could not find a zos.json file for '${this.name}'. (${err.message})`,
);
}
this._packageFile = new ZosPackageFile(filename);
}
return this._packageFile;
}
Expand All @@ -171,7 +180,7 @@ export default class Dependency {
throw Error(
`Could not find a zos file for network '${network}' for '${
this.name
}'`,
}'.`,
);
}

Expand All @@ -195,7 +204,13 @@ export default class Dependency {
}

private _getNetworkFilePath(network: string): string {
return `node_modules/${this.name}/zos.${network}.json`;
try {
return require.resolve(`${this.name}/zos.${network}.json`, {
paths: [process.cwd()],
});
} catch (err) {
return null;
}
}

private _validateSatisfiesVersion(
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/models/network/NetworkController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export default class NetworkController {
const libInstance = await this.project.setImplementation(libClass, libName);
this.networkFile.addSolidityLib(libName, libInstance);
Loggy.succeed(
`upload-solidity-lob${libName}`,
`upload-solidity-lib${libName}`,
`${libName} library uploaded`,
);
}
Expand Down
152 changes: 65 additions & 87 deletions packages/cli/test/models/Dependency.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,9 @@ require('../setup');

import sinon from 'sinon';
import npm from 'npm-programmatic';
import { FileSystem as fs } from 'zos-lib';
import Dependency from '../../src/models/dependency/Dependency';

contract('Dependency', function([_, from]) {
const assertErrorMessage = (fn, errorMessage) => {
try {
fn();
} catch (error) {
error.message.should.match(errorMessage);
}
};

describe('static methods', function() {
describe('#satisfiesVersion', function() {
it('verifies if requirement satisfies version', function() {
Expand All @@ -27,10 +18,9 @@ contract('Dependency', function([_, from]) {
describe('#fromNameAndVersion', function() {
describe('with invalid nameAndVersion', function() {
it('throws error', function() {
assertErrorMessage(
() => Dependency.fromNameWithVersion('bildts-kcom'),
/Could not find a zos.json file/,
);
expect(
() => Dependency.fromNameWithVersion('bildts-kcom')
).to.throw(/Cannot find module/);
});
});

Expand Down Expand Up @@ -62,41 +52,21 @@ contract('Dependency', function([_, from]) {

context('when there are dependencies to deploy', function() {
it('returns true', function() {
const projectPackageFile = fs.parseJsonIfExists(
Dependency.hasDependenciesForDeploy(
'test',
'test/mocks/packages/package-with-multiple-stdlibs.zos.json',
);
const projectNetworkFile = fs.parseJsonIfExists(
'test/mocks/networks/network-with-stdlibs.zos.test.json',
);
const stubbedParseJsonIfExists = sinon.stub(fs, 'parseJsonIfExists');
stubbedParseJsonIfExists
.withArgs('zos.json')
.returns(projectPackageFile);
stubbedParseJsonIfExists
.withArgs('zos.test.json')
.returns(projectNetworkFile);

Dependency.hasDependenciesForDeploy('test').should.be.true;
'test/mocks/networks/network-with-stdlibs.zos.test.json'
).should.be.true;
});
});

context('when all dependencies are already deployed', function() {
it('returns false', function() {
const projectPackageFile = fs.parseJsonIfExists(
Dependency.hasDependenciesForDeploy(
'test',
'test/mocks/packages/package-with-stdlib.zos.json',
);
const projectNetworkFile = fs.parseJsonIfExists(
'test/mocks/networks/network-with-stdlibs.zos.test.json',
);
const stubbedParseJsonIfExists = sinon.stub(fs, 'parseJsonIfExists');
stubbedParseJsonIfExists
.withArgs('zos.json')
.returns(projectPackageFile);
stubbedParseJsonIfExists
.withArgs('zos.test.json')
.returns(projectNetworkFile);

Dependency.hasDependenciesForDeploy('test').should.be.false;
'test/mocks/networks/network-with-stdlibs.zos.test.json'
).should.be.false;
});
});
});
Expand All @@ -105,19 +75,25 @@ 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/,
);
expect(
() => new Dependency('mock-stdlib', '1.2.0')
).to.throw(/does not match version/);
});
});

context('with non-existent dependency name', function() {
it('throws an error', function() {
assertErrorMessage(
() => new Dependency('bildts-kcom', '1.1.0'),
/Could not find a zos.json file/,
);
expect(
() => new Dependency('bildts-kcom', '1.1.0')
).to.throw(/Cannot find module/);
});
});

context('with non-ethereum package', function() {
it('throws an error', function() {
expect(
() => new Dependency('chai')
).to.throw(/Cannot find module/);
});
});

Expand All @@ -138,52 +114,54 @@ contract('Dependency', function([_, from]) {
});
});

describe('instance methods', function() {
beforeEach(function() {
this.dependency = new Dependency('mock-stdlib', '1.1.0');
this.txParams = {};
this.addresses = {};
delete this.dependency._packageFile;
});

describe('#deploy', function() {
it('deploys a dependency', async function() {
const project = await this.dependency.deploy({ from });
const address = await project.getImplementation({
contractName: 'Greeter',
function testInstanceMethodsFor(libname) {
describe(`instance methods for ${libname}`, function() {
beforeEach(function() {
this.dependency = new Dependency(libname, '1.1.0');
this.txParams = {};
this.addresses = {};
delete this.dependency._projectFile;
});

describe('#deploy', function() {
it('deploys a dependency', async function() {
const project = await this.dependency.deploy({ from });
const address = await project.getImplementation({
contractName: 'Greeter',
});
address.should.be.nonzeroAddress;
});
address.should.be.nonzeroAddress;
});
});

describe('#getPackageFile', function() {
it('generates a package file', function() {
const packageFile = this.dependency.getPackageFile();
packageFile.should.not.be.null;
packageFile.fileName.should.eq('node_modules/mock-stdlib/zos.json');
packageFile.version.should.eq('1.1.0');
packageFile.contracts.should.include({ Greeter: 'GreeterImpl' });
describe('#projectFile', function() {
it('generates a package file', function() {
const projectFile = this.dependency.getPackageFile();
projectFile.should.not.be.null;
projectFile.fileName.should.match(/mock-stdlib\/zos\.json$/);
projectFile.version.should.eq('1.1.0');
projectFile.contracts.should.include({ Greeter: 'GreeterImpl' });
});
});
});

describe('#getNetworkFile', function() {
context('for a non-existent network', function() {
it('throws an error', function() {
assertErrorMessage(
() => this.dependency.getNetworkFile('bildts-kcom'),
/Could not find a zos file for network/,
);
describe('#getNetworkFile', function() {
context('for a non-existent network', function() {
it('throws an error', function() {
expect(
() => this.dependency.getNetworkFile('bildts-kcom')
).to.throw(/Could not find a zos file/);
});
});
});

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

testInstanceMethodsFor('mock-stdlib');
testInstanceMethodsFor('mock-stdlib-root');
});
Loading

0 comments on commit 282f449

Please sign in to comment.