aboutsummaryrefslogtreecommitdiffstats
path: root/packages/monorepo-scripts/src
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-08-15 05:21:47 +0800
committerFabio Berger <me@fabioberger.com>2018-08-15 05:21:47 +0800
commit2f2582a0da3095d61a99ef09744dc0995677558e (patch)
tree54989565919038c42d495dafb7426d4148605e84 /packages/monorepo-scripts/src
parent8169155a6547fb0283cd0f5362aad3c0b173b00b (diff)
parentfadd292ecf367e42154856509d0ea0c20b23f2f1 (diff)
downloaddexon-0x-contracts-2f2582a0da3095d61a99ef09744dc0995677558e.tar.gz
dexon-0x-contracts-2f2582a0da3095d61a99ef09744dc0995677558e.tar.zst
dexon-0x-contracts-2f2582a0da3095d61a99ef09744dc0995677558e.zip
Merge development
Diffstat (limited to 'packages/monorepo-scripts/src')
-rw-r--r--packages/monorepo-scripts/src/publish.ts22
-rw-r--r--packages/monorepo-scripts/src/test_installation.ts163
-rw-r--r--packages/monorepo-scripts/src/utils/utils.ts2
3 files changed, 132 insertions, 55 deletions
diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts
index 932d912b8..bb2dd60c1 100644
--- a/packages/monorepo-scripts/src/publish.ts
+++ b/packages/monorepo-scripts/src/publish.ts
@@ -21,12 +21,25 @@ const DOC_GEN_COMMAND = 'docs:json';
const NPM_NAMESPACE = '@0xproject/';
const TODAYS_TIMESTAMP = moment().unix();
+async function confirmAsync(message: string): Promise<void> {
+ prompt.start();
+ const result = await promisify(prompt.get)([message]);
+ const didConfirm = result[message] === 'y';
+ if (!didConfirm) {
+ utils.log('Publish process aborted.');
+ process.exit(0);
+ }
+}
+
(async () => {
// Fetch public, updated Lerna packages
const shouldIncludePrivate = true;
const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate);
if (!configs.IS_LOCAL_PUBLISH) {
+ await confirmAsync(
+ 'THIS IS NOT A TEST PUBLISH! You are about to publish one or more packages to npm. Are you sure you want to continue? (y/n)',
+ );
await confirmDocPagesRenderAsync(allUpdatedPackages);
}
@@ -109,14 +122,7 @@ package.ts. Please add an entry for it and try again.`,
opn(link);
});
- prompt.start();
- const message = 'Do all the doc pages render properly? (yn)';
- const result = await promisify(prompt.get)([message]);
- const didConfirm = result[message] === 'y';
- if (!didConfirm) {
- utils.log('Publish process aborted.');
- process.exit(0);
- }
+ await confirmAsync('Do all the doc pages render properly? (y/n)');
}
async function pushChangelogsToGithubAsync(): Promise<void> {
diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts
index a8ddf0c58..87c4ad1d7 100644
--- a/packages/monorepo-scripts/src/test_installation.ts
+++ b/packages/monorepo-scripts/src/test_installation.ts
@@ -2,10 +2,13 @@
import * as fs from 'fs';
import * as _ from 'lodash';
+import * as mkdirp from 'mkdirp';
import * as path from 'path';
import { exec as execAsync } from 'promisify-child-process';
import * as rimraf from 'rimraf';
+import { promisify } from 'util';
+import { Package } from './types';
import { utils } from './utils/utils';
// Packages might not be runnable if they are command-line tools or only run in browsers.
@@ -16,64 +19,132 @@ const UNRUNNABLE_PACKAGES = [
'@0xproject/react-docs',
];
+const mkdirpAsync = promisify(mkdirp);
+const rimrafAsync = promisify(rimraf);
+const writeFileAsync = promisify(fs.writeFile);
+
+interface PackageErr {
+ packageName: string;
+ error: ExecError;
+}
+
+interface ExecError {
+ message: string;
+ stack: string;
+ stderr: string;
+ stdout: string;
+}
+
+// returns the index for the given package name.
+function findPackageIndex(packages: Package[], packageName: string): number {
+ return _.findIndex(packages, pkg => pkg.packageJson.name === packageName);
+}
+
+function logIfDefined(x: any): void {
+ if (!_.isUndefined(x)) {
+ utils.log(x);
+ }
+}
+
(async () => {
const IS_LOCAL_PUBLISH = process.env.IS_LOCAL_PUBLISH === 'true';
const registry = IS_LOCAL_PUBLISH ? 'http://localhost:4873/' : 'https://registry.npmjs.org/';
const monorepoRootPath = path.join(__dirname, '../../..');
- const packages = utils.getTopologicallySortedPackages(monorepoRootPath);
+ const packages = utils.getPackages(monorepoRootPath);
const installablePackages = _.filter(
packages,
pkg => !pkg.packageJson.private && !_.isUndefined(pkg.packageJson.main) && pkg.packageJson.main.endsWith('.js'),
);
utils.log('Testing packages:');
_.map(installablePackages, pkg => utils.log(`* ${pkg.packageJson.name}`));
+ // Run all package tests asynchronously and push promises into an array so
+ // we can wait for all of them to resolve.
+ const promises: Array<Promise<void>> = [];
+ const errors: PackageErr[] = [];
for (const installablePackage of installablePackages) {
- const changelogPath = path.join(installablePackage.location, 'CHANGELOG.json');
- const lastChangelogVersion = JSON.parse(fs.readFileSync(changelogPath).toString())[0].version;
- const packageName = installablePackage.packageJson.name;
- utils.log(`Testing ${packageName}@${lastChangelogVersion}`);
- const testDirectory = path.join(monorepoRootPath, '../test-env');
- rimraf.sync(testDirectory);
- fs.mkdirSync(testDirectory);
- await execAsync('yarn init --yes', { cwd: testDirectory });
- const npmrcFilePath = path.join(testDirectory, '.npmrc');
- fs.writeFileSync(npmrcFilePath, `registry=${registry}`);
- utils.log(`Installing ${packageName}@${lastChangelogVersion}`);
- await execAsync(`npm install --save ${packageName}@${lastChangelogVersion} --registry=${registry}`, {
- cwd: testDirectory,
+ const packagePromise = testInstallPackageAsync(monorepoRootPath, registry, installablePackage).catch(error => {
+ errors.push({ packageName: installablePackage.packageJson.name, error });
});
- const indexFilePath = path.join(testDirectory, 'index.ts');
- fs.writeFileSync(indexFilePath, `import * as Package from '${packageName}';\nconsole.log(Package);\n`);
- const tsConfig = {
- compilerOptions: {
- typeRoots: ['node_modules/@0xproject/typescript-typings/types', 'node_modules/@types'],
- module: 'commonjs',
- target: 'es5',
- lib: ['es2017', 'dom'],
- declaration: true,
- noImplicitReturns: true,
- pretty: true,
- strict: true,
- },
- include: ['index.ts'],
- };
- const tsconfigFilePath = path.join(testDirectory, 'tsconfig.json');
- fs.writeFileSync(tsconfigFilePath, JSON.stringify(tsConfig, null, '\t'));
- utils.log(`Compiling ${packageName}`);
- const tscBinaryPath = path.join(monorepoRootPath, './node_modules/typescript/bin/tsc');
- await execAsync(tscBinaryPath, { cwd: testDirectory });
- utils.log(`Successfully compiled with ${packageName} as a dependency`);
- const isUnrunnablePkg = _.includes(UNRUNNABLE_PACKAGES, packageName);
- if (!isUnrunnablePkg) {
- const transpiledIndexFilePath = path.join(testDirectory, 'index.js');
- utils.log(`Running test script with ${packageName} imported`);
- await execAsync(`node ${transpiledIndexFilePath}`);
- utils.log(`Successfilly ran test script with ${packageName} imported`);
- }
- rimraf.sync(testDirectory);
+ promises.push(packagePromise);
+ }
+ await Promise.all(promises);
+ if (errors.length > 0) {
+ // We sort error messages according to package topology so that we can
+ // them in a more intuitive order. E.g. if package A has an error and
+ // package B imports it, the tests for both package A and package B will
+ // fail. But package B only fails because of an error in package A.
+ // Since the error in package A is the root cause, we log it first.
+ const topologicallySortedPackages = utils.getTopologicallySortedPackages(monorepoRootPath);
+ const topologicallySortedErrors = _.sortBy(errors, packageErr =>
+ findPackageIndex(topologicallySortedPackages, packageErr.packageName),
+ );
+ _.forEach(topologicallySortedErrors, packageError => {
+ utils.log(`ERROR in package ${packageError.packageName}:`);
+ logIfDefined(packageError.error.message);
+ logIfDefined(packageError.error.stderr);
+ logIfDefined(packageError.error.stdout);
+ logIfDefined(packageError.error.stack);
+ });
+ process.exit(0);
}
})().catch(err => {
- utils.log(err.stderr);
- utils.log(err.stdout);
- process.exit(1);
+ utils.log(`Unexpected error: ${err.message}`);
+ process.exit(0);
});
+
+async function testInstallPackageAsync(
+ monorepoRootPath: string,
+ registry: string,
+ installablePackage: Package,
+): Promise<void> {
+ const changelogPath = path.join(installablePackage.location, 'CHANGELOG.json');
+ const lastChangelogVersion = JSON.parse(fs.readFileSync(changelogPath).toString())[0].version;
+ const packageName = installablePackage.packageJson.name;
+ utils.log(`Testing ${packageName}@${lastChangelogVersion}`);
+ const packageDirName = path.join(...(packageName + '-test').split('/'));
+ const testDirectory = path.join(
+ monorepoRootPath,
+ 'packages',
+ 'monorepo-scripts',
+ '.installation-test',
+ packageDirName,
+ );
+ await rimrafAsync(testDirectory);
+ await mkdirpAsync(testDirectory);
+ await execAsync('yarn init --yes', { cwd: testDirectory });
+ const npmrcFilePath = path.join(testDirectory, '.npmrc');
+ await writeFileAsync(npmrcFilePath, `registry=${registry}`);
+ utils.log(`Installing ${packageName}@${lastChangelogVersion}`);
+ await execAsync(`npm install --save ${packageName}@${lastChangelogVersion} --registry=${registry}`, {
+ cwd: testDirectory,
+ });
+ const indexFilePath = path.join(testDirectory, 'index.ts');
+ await writeFileAsync(indexFilePath, `import * as Package from '${packageName}';\nconsole.log(Package);\n`);
+ const tsConfig = {
+ compilerOptions: {
+ typeRoots: ['node_modules/@0xproject/typescript-typings/types', 'node_modules/@types'],
+ module: 'commonjs',
+ target: 'es5',
+ lib: ['es2017', 'dom'],
+ declaration: true,
+ noImplicitReturns: true,
+ pretty: true,
+ strict: true,
+ },
+ include: ['index.ts'],
+ };
+ const tsconfigFilePath = path.join(testDirectory, 'tsconfig.json');
+ await writeFileAsync(tsconfigFilePath, JSON.stringify(tsConfig, null, '\t'));
+ utils.log(`Compiling ${packageName}`);
+ const tscBinaryPath = path.join(monorepoRootPath, './node_modules/typescript/bin/tsc');
+ await execAsync(tscBinaryPath, { cwd: testDirectory });
+ utils.log(`Successfully compiled with ${packageName} as a dependency`);
+ const isUnrunnablePkg = _.includes(UNRUNNABLE_PACKAGES, packageName);
+ if (!isUnrunnablePkg) {
+ const transpiledIndexFilePath = path.join(testDirectory, 'index.js');
+ utils.log(`Running test script with ${packageName} imported`);
+ await execAsync(`node ${transpiledIndexFilePath}`);
+ utils.log(`Successfilly ran test script with ${packageName} imported`);
+ }
+ await rimrafAsync(testDirectory);
+}
diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts
index d9bae3ea9..26ac801bd 100644
--- a/packages/monorepo-scripts/src/utils/utils.ts
+++ b/packages/monorepo-scripts/src/utils/utils.ts
@@ -117,7 +117,7 @@ export const utils = {
return tags;
},
async getLocalGitTagsAsync(): Promise<string[]> {
- const result = await execAsync(`git tags`, {
+ const result = await execAsync(`git tag`, {
cwd: constants.monorepoRootPath,
});
const tagsString = result.stdout;